Developer World Spresense
English 日本語
目录

1. 示例

Spresense SDK 使用NuttX的NSH shell功能以 Built-in 命令的形式实现和提供每个示例。

示例名 说明

accel

加速度传感器的样本

adc

A/D 转换器示例

alarm

这是一个报警示例

asmp

ASMP 示例

audio_player

音频播放器的示例

audio_recorder

这是录音机的示例

audio_through

音频路径

camera

相机示例

colorsensor

颜色传感器示例

geofence

Geofence样本

gnss

GPS 示例

gyro

这是陀螺仪传感器的样本

hello

基于C的helloworld示例

helloxx

C++ 的helloworld示例

light

这是照度传感器的样本

mag

这是地磁传感器的样本

press

这是气压传感器的样本

proximity

接近传感器的样本

tilt

倾斜传感器示例

watchdog

看门狗计时器的示例

2. GPS(GNSS)示例应用程序

本章介绍了GPS(GNSS)示例应用程序的操作过程。

2.1. 编译和加载过程

导航到下载的 Spresense SDK 文件夹,并使用以下步骤进行编译:

  1. 进入目录 sdk

    cd spresense/sdk
    
  2. 配置SDK。
    现在,我们将编译一个名为 gnss 的Example应用程序,并指定 examples/gnss

    tools/config.py examples/gnss
    
  3. 编译。

    make
    

如果一切顺利,将在 sdk 文件夹中创建一个名为 nuttx.spk 的二进制映像。

  1. 与Hello示例一样,使用 tools/flash.sh 将编译的映像 nuttx.spk 加载到 Spresense 中。

    tools/flash.sh -c /dev/ttyUSB0 nuttx.spk
    
  2. 加载完成并自动重新启动。

2.2. GPS 操作检查

将此 nuttx.spk 加载到 Spresense 中以运行GPS程序。

与Hello示例一样,打开串行终端。

minicom -D /dev/ttyUSB0 -b 115200 -s

builtin,当运行名为 gnss 的应用时,

tutorial gnss log1
图表 1. GPS 启动日志

将显示日志。

当定位不出来时

No Positioning Data

显示启动时为0的时间。 如果位置很好,大约一分钟,显示格林威治标准时间。 大约三分钟后,定位应该能够工作。

如果定位正常

Hour:9, minute:13, sec:20, usec:559
LAT 35.25.6303
LNG 139.22.1986

可以执行此操作,并获取纬度和经度。

3. Audio Player 示例应用程序

本章介绍了Audio Player示例应用程序的操作过程。

3.1. 编译烧入过程

这里显示了使用命令行的构建过程。

  1. 进入 sdk 目录。

    加载build-env.sh脚本会启用config.py工具的Tab关键字补全功能。

    cd spresense/sdk
    source tools/build-env.sh
    
  2. 配置并且编译SDK。

    config.py 的参数设置为 examples/audio_player 并执行配置。 编译成功后,将在 sdk 目录下生成 nuttx.spk 二进制文件。

    tools/config.py examples/audio_player
    make
    
  3. nuttx.spk 加载到Spresense基板上。

    在这种情况下,串行端口设置为 /dev/ttyUSB0 ,波特率设置为 500000 bps。该参数应设置为适合您的环境。

    tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
    
  4. 对于Audio Player,需要加载DSP二进制文件才能执行解码操作。 DSP二进制文件的位置可以是SD卡或SPI-Flash, 但是这里我们将从SD卡加载。

    在应用程序代码( audio_player_main.cxx )中指定DSP二进制路径。 在 audio_player_main.cxx 中,它由 DSPBIN_FILE_PATH 指定。

    #define DSPBIN_FILE_PATH "/mnt/sd0/BIN"

    上面代码表示选择SD卡。

    如果要用SPI-flash,请指定 /mnt/spif/BIN

    当在PC上读取SD卡时,此 /mnt/sd0/BIN 目录就是SDK卡根目录下的 BIN/
    创建此目录,然后在此处放置所需编解码器的DSP。

    使用MP3解码文件
    spresense/sdk/modules/audio/dsp/ 下选择 MP3DEC

  5. 将你想要播放的音乐文件拷贝到SD卡。 在`audio_player_main.cxx` 文件的 PLAYBACK_FILE_PATH 中指定。

    #define PLAYBACK_FILE_PATH "/mnt/sd0/AUDIO"

    因此,请将SD卡插入PC并在SD卡根目录下创建 AUDIO 目录。 接下来,将音频文件放在 AUDIO 目录中,也可以将其放置在子目录中。

  6. 当前的音频播放器示例正在播放一个简单的播放列表。 因此,指定播放列表文件的位置和文件名并播放音乐文件。 在 audio_player_main.cxx 中,通过 PLAYLIST_FILE_PATH 指定播放列表路径, 以及通过 PLAYLIST_FILE_NAME 指定播放列表名字。

    #define PLAYLIST_FILE_PATH "/mnt/sd0/PLAYLIST"
    #define PLAYLIST_FILE_NAME "TRACK_DB.CSV"

    请在SD卡的根目录下创建 PLAYLIST/ , 然后将 TRACK_DB.CSV 放入其中。

    有关 TRACK_DB.CSV 的内容,请参考 spresense/sdk/modules/audio/playlist/ 下的 README.txt

然后,您可以播放播放列表。

3.2. Audio Player 操作确认

当将 nuttx.spk 加载到Spresense板上时,可以执行音频播放器程序。

与 Hello 示例一样,打开串行终端。

minicom -D /dev/ttyUSB0 -b 115200 -s

builtin 名为 audio_player 的应用运行时,

tutorial player log
图表 2. 音乐播放日志

显示日志并播放音频。

如果出现错误,请参考 关于音频子系统错误

3.3. 附录:自定义音频信号处理

到目前为止,您可以在本教程中运行audio_player应用程序。
从这里开始,它说明了有关添加自定义信号处理的可选功能。

在AudioPlayer示例中,您可以对播放的音频执行自己的信号处理。
如果您想这样做,则需要在配置菜单中启用 [Use postprocess]

  1. 启用 Postprocess.

    tools/cofig.py -m
    

    检查 [Use Postprocess]

    [Examples]
      [Audio player example]
        [Use Postprocess]        <= Y
    有关 Postprocess 的更多信息,请参阅SDK开发人员指南Set preprocess
  2. 开始编译

    make
    

    构建成功完成后,将在 spresense/examples/audio_player/worker/ 下生成 POSTPROC 二进制文件。
    请将此文件放在 /mnt/sd0/BIN 上(如果您在PC上读取SD卡,则为 BIN/ )。

    在此示例应用程序中,默认情况下,POSTPROC 包含一个简单的RCfilter。
    如果要自定义自己的信号处理等,请参考 在这里

    尝试在启用或禁用`[Use Postprocess]` 的情况下播放音频文件,以查看区别。 请参阅 如何播放

    == 关于自定义DSP二进制文件(POSTPROC)

本章介绍如何自定义DSP二进制文件(POSTPROC)。

3.3.1. 步骤1.编辑POSTPROC的代码

POSTPROC的代码结构和编辑位置的说明。
该代码分为两部分: 编辑用户的部分 以及作为框架提供的部分。

3.3.1.1. 用户编辑的代码

这是用户应主要编辑的代码。
通过编辑这些代码,可以进行独特的信号处理。

DSP代码位于 worker 目录中,该目录下有 userproc 目录。
用户仅需要在 userproc 目录中写入信号处理即可,基本上不需要更改其他内容。

由于 main.cpp 提供了与主CPU的启动处理和数据通信控制,因此请勿对其进行更改。

Diagram
图表 3. 源代码的结构
main.cpp

编写了启动处理和DSP通信处理,无需编辑。

userproc_command.h

它是一个头文件,用于定义与DSP的通信命令。
在此文件中描述您的必要参数。

userproc.h

用户代码的头文件。

userproc.cpp

用户代码的源文件。
在此文件中写入或调用信号处理等。

3.3.1.2. 为用户代码提供API

userproc.cppInit , Exec , Flush , Set 命令提供了框架。
用户代码可以通过编写唯一内容来支持DSP中的处理。

描述用户应该编写的过程。
(* 默认情况下,包含一个RC滤波器作为示例。)

下图所示,通过命令在DSP内部执行状态转换。

Diagram
图表 4. DSP的状态转换

使用各个命令来按以下流程进行处理。

  1. 当调用AUDCMD_INIT_OUTPUTMIXER时,DSP启动。

  2. Init 命令设置必要的参数(通道数,位长等)

  3. 播放开始时,捕获的音频数据会通过 Exec 命令定期发送到DSP,请进行所希望的过滤处理。

  4. 如果您想随时更改DSP内部的参数,可以通过发送 Set 命令来实现。 该命令的执行时机是包括 Exec 在内的接收顺序。

  5. 当播放停止时,在 Exec 上的最后一个音频数据之后发送 Flush 命令,因此如果需要终止处理,则在此处执行处理。

命令定义

每个函数使用的数据类型在 userproc_command.h 中描述,其内容可以自由编写。

每个命令的格式如下所示。
最低要求的参数位于顶部白色区域。 请不要更改这些。
下图的 userproc_command.h 中的 User param 部分(粉色部分),您可以定义参数。

Diagram
图表 5. 命令格式

每个命令的说明如下。

struct InitParam : public CustomprocCommand::CmdBase
  • Init处理参数。
    所有参数都由 reserve 定义,因此您将把它们更改为需要的参数,例如通道数和位长。

struct ExecParam : public CustomprocCommand::CmdBase
  • Exec处理参数。
    音频数据的地址和大小在 CustomprocCommand::ExecParamBase 中定义,如上图的 ExecParam 所示。
    有关详细信息,请参见 /sdk/modules/include/audio/dsp_framework/customproc_command_base.h

struct FlushParam : public CustomprocCommand::CmdBase
  • Flush处理参数。
    音频数据的地址和大小在 CustomprocCommand::ExecParamBase 中定义,如上图的 ExecParam 所示。
    有关详细信息,请参见 sdk/modules/include/audio/dsp_framework/customproc_command_base.h

struct SetParam : public CustomprocCommand::CmdBase
  • Set处理参数。
    定义多种可动态更改的参数。 默认情况下,RC滤波器的On/Off和系数作为样本被定义。

各个功能对应的函数

以下功能写在 userproc.cpp 中。 内容可以自由编写。
根据每个命令定义执行处理。

void UserProc::init(InitParam *)
  • 根据InitParam编写初始化处理。
    它由应用程序代码中的 AUDCMD_INITMPP 命令执行。
    (默认情况下不执行任何操作)

void UserProc::exec(ExecParam *)
  • 根据ExecParam编写信号处理。 当您开始播放时,它将定期从SDK中调用。
    LPCM时,一帧为640个样本,MP3为1152(但在16 kHz时为1728)个样本。
    从输入数据地址获取数据,进行信号处理,然后写入输出数据地址。 (默认情况下写入RC过滤)

void UserProc::flush(FlushParam *)
  • 根据FlushParam 编写和载入(终端)处理。
    当播放停止时,只能从SDK调用一次。
    IIR和FIR滤波器发生延迟时,将在最后一帧之后执行 flush 并输出延迟部分。
    如果有数据要输出,则将其写入输出数据地址。
    (默认情况下不执行任何操作)

void UserProc::set(SetParam *)
  • 根据SetParam编写设置处理过程。
    它由应用程序代码中的 AUDCMD_SETMPPPARAM 命令执行。
    (RC滤波器系数默认设置。)

3.3.2. Step2. 构建`POSTPROC`二进制文件

如果在 Configuration 中启用了 User Postprocess ,则在构建此应用程序时将自动创建 POSTPROC 二进制文件。
spresense/examples/audio_player/worker/ 路径下创建 POSTPROC
将其放入SD卡上的 /mnt/sd0/BIN (从PC查看的话是 \BIN )文件夹中。

4. Audio Recorder 示例应用程序

本章提供Audio Recorder示例应用程序的操作说明。

代码结构、数据流、API 引用等,请参考 Audio Recorder Functions

4.1. 生成和加载过程

导航到下载的 Spresense SDK 文件夹,然后按照以下步骤生成它:

  1. 进入 sdk

    cd spresense/sdk
    
  2. 配置 SDK。

    1. 现在,将生成名为 audio_recorder 的Example应用程序,并指定 examples/audio_recorder

      tools/config.py examples/audio_recorder
      

      这个配置为audio_recorder设置。
      如果必要,可以更改以下项目。请不要更改任何其它。

      [SDK audio]                    <= Y
        [Audio Recorder]             <= Y
          [DSP imange mount path]    <= /mnt/sd0/BIN  (1)
      1 将DSP二进制文件的默认位置设置为SD卡。SPI-flash路径为 /mnt/spif/BIN
      了解有关配置功能本身的详细信息,请参考 配置
    2. 如果要对要录制的音频执行自己的信号处理,请设置Preprocess。

      AudioRecorder 允许用户对录制的音频执行自己的信号处理。
      如果要执行此操作,则必须在配置菜单中启用 [Use preprocess]

      打开配置菜单。

      tools/cofig.py -m
      

      检查 [Use preprocess]

      [Examples]
        [Audio recorder example]
          [Use preprocess]        <= Y  (1)
      1 Preprocess处理
      有关Preprocess的详细信息,请参阅SDK开发人员指南 Set preprocess
  3. 编译。

    make
    
    了解有关编译的详细信息,请参考 编译

    如果所有步骤都成功,将在 sdk 文件夹中创建名为 nuttx.spk 的二进制映像。

  4. 与Hello示例一样,使用 tools/flash.sh 将生成的映像 nuttx.spk 加载到 Spresense 中。

    tools/flash.sh -c /dev/ttyUSB0 nuttx.spk
    
  5. 加载完成并自动重新启动。

  6. 对于Audio Recorder,需要加载DSP二进制文件才能进行编码。 可以在SD卡或SPI-Flash之间选择DSP二进制文件的位置,但在这里,将了解如何从SD卡加载它。

    DSP二进制路径规范由应用程序代码(audio_recorder_main.cxx)中的宏值设置。
    在audio_recorder_main.cxx中,使用 DSPBIN_PATH 设置,并根据需要更改应用程序代码。

    #define DSPBIN_PATH "/mnt/sd0/BIN"

    在SD卡上的 BIN 目录中。

    当PC读取时,此 /mnt/sd0/BIN 将成为根目录下的 BIN/
    创建此目录,并将 DSP 放在所需的编解码器上。

    如果要SPI-flash,请指定 /mnt/spif/BIN 。 此外,如果指定null,则路径将在Config中设置。

    使用MP3进行编码
    spresense/sdk/modules/audio/dsp/ 下,选择 MP3ENC
    其他编码的Codec类型和DSP二进制的组合如下表所示。

    Codec DSP二进制

    MP3

    MP3ENC

    LPCM

    SRC

    此外,如果设置了 Preprocess 处理,则以下Preprocess二进制文件也放在SD卡上。
    二进制是 PREPROC ,存于spresense/examples/audio_recorder/worker/src。

    在此示例应用程序中, PREPROC 默认包含一个简单的 RCfilter。
    如果要自定义,如自己的信号处理,请参考 此处
  7. 录制的声音将记录在SD卡上。 录制路径也由应用程序代码(audio_recorder_main.cxx)中的宏值设置。 在audio_recorder_main.cxx中,使用 RECFILE_ROOTPATH 设置它,因此根据需要更改应用程序代码。 示例一样,打开串行终端。

    #define RECFILE_ROOTPATH "/mnt/sd0/REC"

    记录在SD卡上。

4.2. Audio Recorder 检查操作

nuttx.spk 加载到实际设备中时,将运行音频记录程序。

与 Hello示例一样,打开串行终端。

minicom -D /dev/ttyUSB0 -b 115200 -s

builtin,当运行名为 recorder 的应用时,

tutorial recorder log
图表 6. 语音录制日志

将显示声音。

录制的音频可以在PC上播放。在这种情况下,音频文件位于SD卡根目录下的 REC/

如果出现错误,请参考 关于音频子系统错误

4.3. 关于DSP二进制(PREPROC)自定义

描述如何自定义DSP二进制文件(PREPROC)。

4.3.1. Step1. PREPROC 代码编辑

了解 PREPROC 的代码配置和编辑位置。
代码分为两部分:开发者编译指引 以及作为框架提供的部分。

4.3.1.1. 用户编辑的代码

开发者应主要编辑的代码。
可以编辑这些代码以在 DSP 中编写信号处理。

DSP代码位于 woker 目录中,其中有一个 userproc 目录。
如果仅在 userproc 目录中写入信号处理等,而不需要更改任何其他信息。

main.cpp 包含与启动过程~MainCPU 的数据通信控制,因此不要更改它。

Diagram
图表 7. 代码结构
main.cpp

包括启动和DSP通信处理。无需编辑。

userproc_command.h

定义与DSP通信命令的标头文件。
此文件包含所需的参数。

userproc.h

用户代码的标头文件。

userproc.cpp

用户代码正文。
写入或调用此文件,如信号处理。

4.3.1.2. 用户代码提供的接口

userproc.cpp 提供 InitExecFlushSet 命令框架。 用户代码可以通过编写相应的内容来实现DSP中的处理。

描述用户应执行的操作。
(默认情况下,RC 筛选器作为示例内置。)

通过命令在DSP内部进行状态转换,如下图所示。

Diagram
图表 8. DSP状态转换

使用每个命令按以下方式处理。

  1. 当调用 AUDCMD_INIT_MICFRONTEND 时,DSP将启动。

  2. 设置 Init 命令所需的参数,如ch数和位长度。

  3. 开始录制时,捕获的语音数据会定期发送到DSP与 Exec 命令,因此请执行所需的筛选。

  4. 如果要随时更改DSP中的参数等,则希望通过发送 Set 命令来实现它。 此命令的执行时间按接收顺序显示,包括 Exec

  5. 如果停止录制,则最后一个语音数据 Exec 后跟 Flush 命令,因此,如果需要终止,请在此处执行此操作。

定义命令

每个功能使用的数据类型都写入 userproc_command.h ,可以自由重写其内容。

每个命令的格式如下图所示。
顶部白色部分具有固定所需的最小参数。请不要更改。
开发者在 userproc_command.h 中定义的参数是下图中的 User param (粉红色部分)。

Diagram
图表 9. 命令格式

描述每个命令。

struct InitParam : public CustomprocCommand::CmdBase
  • 用于Init处理的参数。
    默认情况下,所有内容都保留,但应更改为所需的参数,如ch数和位长度。

struct ExecParam : public CustomprocCommand::CmdBase
  • Exec处理的参数。
    语音数据的地址大小在继承的 CustomprocCommand::ExecParamBase 中定义,如上图中的 ExecParam 中那样。
    详细信息,请参考 /sdk/modules/include/audio/dsp_framework/customproc_command_base.h

struct FlushParam : public CustomprocCommand::CmdBase
  • 这是Flush处理的参数。
    语音数据的地址大小定义为继承自有的 CustomprocCommand::FlushParamBase ,如上图中的 ExecParam 中那样。
    详细信息,请参考 /sdk/modules/include/audio/dsp_framework/customproc_command_base.h

struct SetParam : public CustomprocCommand::CmdBase
  • 用于Set处理的参数。
    定义要动态更改的各种参数。定义默认RC滤波器的On/Off和系数。

功能函数

以下函数组在 userproc.cpp 中编写。 内容可以自由重写。
根据每个操作 命令定义

void UserProc::init(InitParam *)
void UserProc::exec(ExecParam *)
  • 然后按照 ExecParam,处理信号。
    开始录制时定期从SDK内部调用。
    1帧是768个样本,用于LPCM的录制设置,1152(但在16kHz时为1728),用于MP3。
    (默认情况下,写入了 RC 筛选。)

void UserProc::flush(FlushParam *)
  • 按照 FlushParam ,编写Flush(终止)功能。
    停止录制时仅从SDK内部调用一次。
    如果延迟(如IIR或FIR滤波器)发生,请在最终帧后执行 flush 以输出延迟。
    如果要输出任何数据,请写入输出数据地址。
    (默认情况下,不工作。)

void UserProc::set(SetParam *)

4.3.2. Step2. PREPROC 生成二进制文件

如果在Configuration启用 Preprocess ,则生成应用程序时将自动创建 PREPROC 二进制文件。
创建的路径是 PREPROC ,在 spresense/examples/audio_recorder/worker/ 下。
将此放在SD卡的 /mnt/sd0/BIN (从PC上查看时为 \BIN )文件夹。

5. Audio Recognizer 示例应用程序

本章提供Audio Recognizer示例应用程序的操作说明。

5.1. 生成和加载过程

导航到下载的 Spresense SDK 文件夹,然后按照以下步骤生成它:

  1. 进入 sdk

    cd spresense/sdk
    
  2. 配置 SDK。

    1. 现在,我们将构建一个 Example 应用程序,称为"audio_recognizer",因此我们将指定"examples/audio_recognizer。

      tools/config.py examples/audio_recognizer
      

      此配置为audio_recognizer设置。

    2. 如果要根据识别库的格式处理语音数据,请设置Preprocess 。

      捕获的音频采样频率为48kHz或192kHz,位长度为16位或32位。
      Audio Recognizer允许根据识别库的输入格式进行预处理。
      如果要执行此操作,则必须在配置菜单中启用 [Use preprocess]
      如果捕获的音频按原样输入到识别库中,则可以禁用它。

      打开配置菜单。

      tools/cofig.py -m
      

      选中 [Use preprocess]

      [Examples]
        [Audio recognizer example]
          [Use preprocess]        <= Y  (1)
      1 启用前处理
      有关Preprocess的详细信息,请参阅SDK开发人员指南中的 set preprocess
  3. 编译。

    make
    
    详细信息,请参考 编译

    如果所有步骤都成功,将在 sdk 文件夹中创建名为 nuttx.spk 的二进制映像。

  4. 与Hello示例一样,使用 tools/flash.sh 将生成的映像 nuttx.spk 加载到 Spresense 中。

    tools/flash.sh -c /dev/ttyUSB0 nuttx.spk
    
  5. 加载完成并自动重新启动。

  6. 对于音频Recognizer,需要加载DSP二进制文件才能执行语音识别。 DSP二进制文件的放置位置可以在SD卡或SPI-Flash之间进行选择。 在这里,我们将了解如何从SD卡加载它,因此我们将它放在 "/mnt/sd0/BIN" 中。

    当PC读取时,此"/mnt/sd0/BIN"将成为根目录下的 BIN/
    创建此目录,并将语音识别所需的DSP放在此处。

    在此示例应用程序中,语音识别的DSP二进制文件设置为使用用户自定义的二进制文件,二进制文件是 spresense/examples/audio_recognizer/worker_recognizer/ 下生成为 RCGPROC 。如果要执行识别处理,请参考 关于 RecognizerPROC 的自定义

    此外,如果设置了 Preprocess处理 ,应将以下前置二进制文件放在 SD 卡上。
    二进制文件 PREPROCspresense/examples/audio_recognizer/worker_preprocess/ 下。

    在此示例应用程序中, PREPROC 默认包含一个简单的RCfilter。
    如果要自定义信号处理等,请参阅 此处

5.2. 检查Audio Recognizer工作原理

将生成的 nuttx.spk 加载到实际设备中时,将运行Audio Recognizer程序。

与Hello示例一样,打开串行终端。

minicom -D /dev/ttyUSB0 -b 115200 -s

builtin,运行名为 recognizer 的应用时,

tutorial recognizer log
图表 10. 语音识别操作日志

开始语音识别。

识别结果由应用程序代码中的回调函数接收。
接收的参数由用于语音识别的 DSP 决定。 请参考 RecognizerProc
由于数据由MemoryHandle接收,因此可以通过引用地址来检索数据,如下所示。

static void recognizer_find_callback(AsRecognitionInfo info)
{
  /* Get Recognition result */

  MyRecognizerResultFormat *result =
    static_cast<MyRecognizerResultFormat *>(info.getVa())

  /* Print result */
  ...
  printf("Data size %d byte\n", info.size);
  printf("Data1 : %x, Data2 : %x\n", result->data1, result->data2);
  ...
}

如果出现错误,请参阅 关于音频子系统错误 中的错误。

5.3. 关于 DSP 二进制自定义

audio_recognizer示例使用两个DSP 二进制文件:用于预处理( PREPROC )和识别处理( RCGPROC )。
了解如何自定义它们。

5.3.1. Step1. PREPROC,RCGPROC 代码编辑

了解PREPROC和RCGPROC的代码配置和编辑位置。
代码分为两部分:用户编辑部分 和框架提供的部分。

5.3.1.1. 用户编辑代码

用户应主要编辑的代码。
可以编辑这些代码,以便 DSP 可以编写信号和识别处理。

 +
`PREPROC` 位于 `woker_preprocess` 目录中,`RCGPROC` 包含 `worker_recognizer` 中的DSP代码,每个代码都包含 `userproc` 。 +
用户仅在 `userproc` 目录中写入信号、识别等,而不需要更改任何其他信息。 +

main.cpp 包含与启动过程~MainCPU(Supervisor)的数据通信控制,因此不要更改它。

Diagram
图表 11. PREPROC,RCGPROC代码配置
main.cpp

包括启动和DSP通信处理。无需编辑。

userproc_command.h

定义与预处理DSP通信命令的标头文件。
此文件包含所需的参数。

userproc.h

用于预处理的DSP用户代码的标头文件。

userproc.cpp

用于预处理的DSP的用户代码正文。
写入或调用此文件,如信号处理。

rcgproc_command.h

定义与识别DSP通信命令的标头文件。
此文件包含所需的参数。

rcgproc.h

用于识别DSP的用户代码头文件。

rcgproc.cpp

用于识别DSP的用户代码正文。
在此文件中编写或调用识别过程。

5.3.1.2. 用户代码提供的接口

提供 InitExecFlushSet 命令框架
用户代码可以通过编写相应的内容来实现DSP中的处理。

描述用户应执行的操作。
(※ 默认情况下, PREPROC 作为示例包含 RC 筛选器。)

命令的DSP内部状态转换如下图所示。

Diagram
图表 12. DSP状态转换

使用每个命令按以下方式处理。

  1. 当调用 AUDCMD_INIT_RECOGNIZER 时,将启动识别DSP。

  2. 设置 Init 命令所需的参数,如ch数和位长度。

  3. 启动识别过程时,捕获的语音数据将定期发送到DSP的 Exec 命令,因此请执行所需的识别过程。

  4. 如果要随时更改DSP中的参数等,则希望通过发送 Set 命令来实现它。 此命令的执行时间按接收顺序显示,包括 Exec

  5. 如果停止识别处理,则在最后一个语音数据 Exec 之后发送 Flush 命令,因此,如果需要终止处理,请在此处执行此操作。

定义命令

每个功能使用的数据类型在 PREPROC 中写入 userproc_command.h ,在 RCGPROC 中写入 rcgproc_command.h ,内容可以自由重写。

每个命令的格式如下图所示,在 PREPROCRCGPROC 中是相同的。
顶部白色部分具有固定所需的最小参数。请不要更改它们。
用户在 userproc_command.h 中定义的参数是下图中的 User param (粉红色部分)。

notificationExec 命令的响应(识别结果)标志,它使用非零规范将响应返回到应用程序。
例如,它通常用于仅在识别结果更改点(无识别→点)时响应,而不返回响应。

Diagram
图表 13. 命令格式

描述每个命令。

struct InitRcgParam : public CustomprocCommand::CmdBase
  • 用于Init处理的参数。
    默认情况下,设置ch数和位宽度。 将其更改为所需的参数。

struct ExecRcgParam : public CustomprocCommand::CmdBase
  • Exec 处理的参数。
    语音数据的地址大小在继承的 CustomprocCommand::ExecParamBase 中定义,如上图中的 ExecParam 中那样。
    有关详细信息,请参考 /sdk/modules/include/audio/dsp_framework/customproc_command_base.h

struct FlushRcgParam : public CustomprocCommand::CmdBase
  • 这是 Flush 处理的参数。
    语音数据的地址大小在继承的 CustomprocCommand::FlushParamBase 中定义,如上图中的 ExecParam 中那样。
    有关详细信息,请参考 /sdk/modules/include/audio/dsp_framework/customproc_command_base.h

struct SetRcgParam : public CustomprocCommand::CmdBase
  • 用于Set处理的参数。
    定义要动态更改的各种参数。默认情况下,它定义识别过程的开/关。

对应于每个功能的函数

以下函数组在 rcgproc.cpp 中编写。内容可以自由重写。
每个 命令定义 执行操作。

void RcgProc::init(InitRcgParam *)
void RcgProc::exec(ExecRcgParam *)
  • ExecRcgParam 编写信号处理。
    开始录制时定期从SDK内部调用。
    在此示例应用程序中,一帧是320个样本(可以在应用程序中自由更改它)。
    从输入数据地址获取数据,执行识别过程,并将结果写入输出数据地址。
    (默认情况下,输出输入帧中样本值的最大、最小和平均值。)

void RcgProc::flush(FlushRcgParam *)
  • 按照 FlushRcgParam 编写Flush(终止)处理。
    停止录制时,仅在SDK内部调用一次。
    如果识别过程出现帧延迟,请在最终帧后执行 flush 以输出延迟。
    如果要输出任何数据,请写入输出数据地址。
    (默认情况下,无操作。)

void RcgProc::set(SetRcgParam *)

5.3.2. Step2. PREPROCRCGPROC 二进制文件的生成

生成此应用程序时,将自动创建 RCGPROC 二进制文件。
此外,如果在 Configuration 中启用了 Preprocess ,则还会创建 PREPROC 二进制文件。
创建的路径是 RCGPROC 下的 worker_recognizer/ ,在 worker_preprocess/ 下为 PREPROC
将此放在SD卡的 /mnt/sd0/BIN (从 PC 上查看时为 \BIN )文件夹。

6. Zmodem 传输文件

本章演示如何使用Zmodem传输在主机PC和Spresense板之间发送和接收文件。

6.1. 编译和加载过程

进入 Spresense SDK 文件夹,然后按照以下步骤编译:

  1. 进入 sdk 目录。

    cd spresense/sdk
    
  2. 配置SDK。
    现在,将构建名为 zmodem 的系统工具,并指定 feature/zmodem

    tools/config.py feature/zmodem
    
    有关配置的详细信息,请参阅 配置
  3. 编译。

    make
    
    详细信息,请参考 编译

    如果所有步骤都成功,将在 sdk 文件夹中创建名为 nuttx.spk 的二进制映像。

  4. 使用 tools/flash.sh 将生成的映像 nuttx.spk 加载到 Spresense 板上。

    tools/flash.sh -c /dev/ttyUSB0 nuttx.spk
    
  5. 加载完成并自动重新启动。

6.2. 操作说明

使用支持Zmodem传输功能的串行终端。

下面是一个示例minicom。
如果未安装minicom或lrzzz,请预安装它。

sudo apt install minicom lrzsz

启动 minicom。

minicom -D /dev/ttyUSB0 -b 115200

可以使用来自NuttShell中Zmodem的rz(接收)和sz(发送)命令。

使用rz命令
tutorial zmodem1 rz
使用sz命令
tutorial zmodem1 sz

6.2.1. 从主机PC传输文件到Spresense板

以下是将文件从主机PC传输到Spresense板的步骤:

  1. 在minicom上按 CTRL-a ,然后按 z 打开菜单。(此快捷键的分配由用户更改。有关详细信息,请参阅minicom文档。)
    继续按 s 键选择Send files发送文件。

    tutorial zmodem2 menu
  2. 使用光标键选择 zmodem 并使用 Enter 键运行。

    tutorial zmodem2 upload
  3. 使用光标键和空格键移动文件夹,然后选择要传输的文件。
    使用光标键选择文件夹,然后按空格键两次以导航到文件夹。
    使用光标键选择文件,使用空格键选择文件,然后按 Enter 开始传输。

    tutorial zmodem2 dir

    或者,可以按 Enter 输入文件名以执行传输。

    tutorial zmodem2 file
  4. 如果文件传输开始,并且显示为Transfer complete,则传输已完成。

    tutorial zmodem2 complete
  5. 可以在CONFIG_SYSTEM_ZMODEM_MOUNTPOINT中更改Spresense板上的文件目标。
    默认配置将文件传输到Flash上的 /mnt/spif 以下。

使用TeraTerm时,可以从菜单中发送 Files → Transfer → ZMODEM → Send 中选择的文件。

6.2.2. 从Spresense板传输文件到主机PC

以下是将文件从Spresense板传输到主机PC的步骤。

  1. 在NuttShell上,指定要传输到 sz 命令参数的文件。
    文件名为 / 输入以完整路径名称开头的文件名。
    下面的示例具有 -x 1 二进制传输选项。

    nsh> sz -x 1 /mnt/spif/test00.dat
  2. 如果文件传输开始,并且显示为Transfer complete,则传输已完成。

    tutorial zmodem3 complete
  3. 将文件传输到在HostPC上运行minicom的文件夹。

如果使用TeraTerm,则可以在从NuttShell中输入 sz 命令后,通过 Files → Transfer → ZMODEM → Receive 接收文件。 HostPC 端的文件接收目录位于 Files → Change Directory

7. 自动启动应用程序方法

本章介绍如何在启动时自动启动用户应用程序,而不是NuttShell提示。

7.1. 启动脚本

通过准备启动脚本,系统启动时,它将按照该脚本运行。 使用此功能,打开电源后可以自动执行任何用户应用程序。 启动脚本可以包括NuttShell命令,包括用户应用程序和简单的控制语法,例如if和while。
详细信息,请参考 NuttShell 文件

7.1.1. 使用脚本

在这里,作为示例,尝试将examples/hello应用程序设置为自动启动。
(省略了有关NuttX内核的配置和构建的说明。)

  1. 启用hello应用程序并打开menuconfig配置菜单。

    ./tools/config.py -m examples/hello
    
  2. 启用 Support ROMFS start-up script

    System tools --> NSH Library ---> Scripting Support
    tutorial autostart menuconfig1
  3. 选择 ROMFS header location 作为 Custom ROMFS header path 。 在 Custom ROMFS header file path 中,输入 ../../nsh_romfsimg.h 并保存配置。

    指定 nsh_romfsimg.h 相对于sdk/system/nshlib目录的位置。
    tutorial autostart menuconfig2
  4. 接下来,直接在sdk目录下创建一个名为 rcS.template 的启动脚本。
    在此,作为示例,如下描述 echo 命令和 hello 命令。

    cat spresense/sdk/rcS.template
    echo Start-up hello application
    hello
    
  5. 使用 mkromfsimg.sh 工具从 rcS.template 生成 nsh_romfsimg.h

    cd spresense/sdk
    ./tools/mkromfsimg.sh .
    ls nsh_romfsimg.h
    nsh_romfsimg.h
    
  6. 将以通常方式编译的二进制文件烧入Spresense板。

    make
    tools/flash.sh -c /dev/ttyUSB0 nuttx.spk
    
  7. 打开电源时,可以在显示NuttShell之前确认脚本中编写的hello应用程序正在运行。

    tutorial autostart log

7.1.2. 更改脚本位置

如果要更改 rcS.template 的位置,请参考以下内容。

  1. 例如,将 rcS.template 放在spresense/examples/hello下。

    cat spresense/examples/hello/rcS.template
    echo Start-up hello application
    hello
    
  2. 使用 rcS.template 所在目录中的 mkromfsimg.sh 工具生成 nsh_romfsimg.h

    cd spresense/examples/hello
    ../../sdk/tools/mkromfsimg.sh ../../sdk
    ls nsh_romfsimg.h
    nsh_romfsimg.h
    
  3. 打开配置菜单
    Cutom ROMFS header file path 中,输入 ../../../examples/hello/nsh_romfsimg.h

    指定 nsh_romfsimg.h 相对于sdk/system/nshlib目录的位置。
  4. 其余的编译过程与之前相同。

7.2. SDK 入口点

您也可以与启动脚本分开更改CONFIG_INIT_ENTRYPOINT。

在默认配置中,CONFIG_INIT_ENTRYPOINT = nsh_main。

如果将其更改为例如hello_main,则可以更改为在启动时启动hello应用程序。

tutorial autostart entrypoint
启动时需要应用程序初始化。引用以下内容添加#include <sys/boardctl.h>,然后从用户入口点函数调用boardctl(BOARDIOC_INIT,0)。
#include <sys/boardctl.h>

#ifdef CONFIG_BUILD_KERNEL
int main(int argc, FAR char *argv[])
#else
int hello_main(int argc, char *argv[])
#endif
{
  /* Initialize apllication */
  boardctl(BOARDIOC_INIT, 0);

  printf("Hello, World!!\n");
  return 0;
}

8. 可加载的ELF教程

可加载的ELF是一个功能,它允许操作系统和应用程序在单独的二进制文件中创建,并在应用程序运行时动态加载和运行。

当应用程序被创建为可加载的ELF时,可以根据需要将其加载到内存中,从而减少运行时的内存总量或允许应用程序独立更新。 但是,需要注意的是,由于反复加载/卸载,可能会延长应用程序的启动时间,并可能出现内存碎片。

可加载式ELF与ASMP ELF不同。要启动的应用程序只在主核心上运行。

在本教程中,我们将使用SD卡作为我们应用程序中ELF文件的存储位置。

8.1. 编译程序

本节展示的是命令行建立过程。 使用IDE编译时,应使用以下配置信息作为参考。

  1. 导航到 sdk 目录。

    装入 build-env.sh 脚本,启用 config.py 工具的Tab完成功能。

    cd spresense/sdk
    source tools/build-env.sh
    
  2. 配置和编译SDK。

    feature/loadable device/sdcard 作为参数运行配置。

    tools/config.py feature/loadable device/sdcard
    tools/config.py -m
    

    打开菜单配置并激活 Hello, World! example。 这时,如果将 Hello, World! example 设置为 M,应用程序将作为一个可加载的ELF建立。

    [Application Configuration]
      [Examples]
        ["Hello, World!" example] => M

    配置完成后,编译。

    make
    

    如果编译成功,在 sdk 文件夹下会创建一个 nuttx.spk 文件,在 sdk/apps/bin 下会创建一个ELF文件 hello 。 你应该把 hello 单独复制到SD卡中。

  3. nuttx.spk 写到Spresense板上。

    在这个例子中,串口被设置为 /dev/ttyUSB0 ,写入速度的波特率被设置为 500000 bps。 请根据您所使用的环境进行修改。

    tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
    

8.2. 操作检查

打开串行终端,运行 hello 应用程序。

  1. 启动串行终端。

    串行端口为 /dev/ttyUSB0 ,波特率为 115200 bps,则下面是一个使用minicom终端的例子。

    minicom -D /dev/ttyUSB0 -b 115200
    
  2. 从NuttShell中运行一个 hello 应用程序。

    指定SD卡上 hello ELF文件的完整路径。

    nsh> /mnt/sd0/hello
    Hello, World!!

8.3. 使用PATH环境变量

NuttShell可以使用 PATH 环境变量以及bash的环境变量来设置ELF文件的路径。 feature/loadable 包含了使用它的设置,但实际使用路径必须由用户自己设置。 打开菜单配置,将 PATH 环境变量设置为SD卡的路径。 在此设置下,位于SD卡正下方的应用程序将能够运行,无需指定完整路径。

[Binary Loader]
  [Initial PATH Value] => "/mnt/sd0"

编译它并写上 nuttx.spk 。 你可以在SD卡上输入 hello ,在NuttShell中输入 hello 就可以启动 hello 应用程序。

nsh> hello
Hello, World!!