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 文件夹,并使用以下步骤进行编译:
-
进入目录
sdk
。cd spresense/sdk
-
配置SDK。
现在,我们将编译一个名为gnss
的Example应用程序,并指定examples/gnss
。tools/config.py examples/gnss
-
编译。
make
如果一切顺利,将在 sdk
文件夹中创建一个名为 nuttx.spk
的二进制映像。
-
与Hello示例一样,使用
tools/flash.sh
将编译的映像nuttx.spk
加载到 Spresense 中。tools/flash.sh -c /dev/ttyUSB0 nuttx.spk
-
加载完成并自动重新启动。
2.2. GPS 操作检查
将此 nuttx.spk
加载到 Spresense 中以运行GPS程序。
与Hello示例一样,打开串行终端。
minicom -D /dev/ttyUSB0 -b 115200 -s
builtin,当运行名为 gnss
的应用时,
将显示日志。
当定位不出来时
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. 编译烧入过程
这里显示了使用命令行的构建过程。
-
进入
sdk
目录。加载build-env.sh脚本会启用config.py工具的Tab关键字补全功能。
cd spresense/sdk source tools/build-env.sh
-
配置并且编译SDK。
将
config.py
的参数设置为examples/audio_player
并执行配置。 编译成功后,将在sdk
目录下生成nuttx.spk
二进制文件。tools/config.py examples/audio_player make
-
将
nuttx.spk
加载到Spresense基板上。在这种情况下,串行端口设置为
/dev/ttyUSB0
,波特率设置为500000
bps。该参数应设置为适合您的环境。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
-
对于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
-
将你想要播放的音乐文件拷贝到SD卡。 在`audio_player_main.cxx` 文件的
PLAYBACK_FILE_PATH
中指定。#define PLAYBACK_FILE_PATH "/mnt/sd0/AUDIO"
因此,请将SD卡插入PC并在SD卡根目录下创建
AUDIO
目录。 接下来,将音频文件放在AUDIO
目录中,也可以将其放置在子目录中。 -
当前的音频播放器示例正在播放一个简单的播放列表。 因此,指定播放列表文件的位置和文件名并播放音乐文件。 在
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
的应用运行时,
显示日志并播放音频。
如果出现错误,请参考 关于音频子系统错误 。
3.3. 附录:自定义音频信号处理
到目前为止,您可以在本教程中运行audio_player应用程序。 从这里开始,它说明了有关添加自定义信号处理的可选功能。 |
在AudioPlayer示例中,您可以对播放的音频执行自己的信号处理。
如果您想这样做,则需要在配置菜单中启用 [Use postprocess]
。
-
启用 Postprocess.
tools/cofig.py -m
检查
[Use Postprocess]
。[Examples] [Audio player example] [Use Postprocess] <= Y
有关 Postprocess
的更多信息,请参阅SDK开发人员指南Set preprocess。 -
开始编译
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的启动处理和数据通信控制,因此请勿对其进行更改。
编写了启动处理和DSP通信处理,无需编辑。
它是一个头文件,用于定义与DSP的通信命令。
在此文件中描述您的必要参数。
用户代码的头文件。
用户代码的源文件。
在此文件中写入或调用信号处理等。
3.3.1.2. 为用户代码提供API
userproc.cpp
为 Init
, Exec
, Flush
, Set
命令提供了框架。
用户代码可以通过编写唯一内容来支持DSP中的处理。
描述用户应该编写的过程。
(* 默认情况下,包含一个RC滤波器作为示例。)
下图所示,通过命令在DSP内部执行状态转换。
使用各个命令来按以下流程进行处理。
-
当调用AUDCMD_INIT_OUTPUTMIXER时,DSP启动。
-
为
Init
命令设置必要的参数(通道数,位长等) -
播放开始时,捕获的音频数据会通过
Exec
命令定期发送到DSP,请进行所希望的过滤处理。 -
如果您想随时更改DSP内部的参数,可以通过发送
Set
命令来实现。 该命令的执行时机是包括Exec
在内的接收顺序。 -
当播放停止时,在
Exec
上的最后一个音频数据之后发送Flush
命令,因此如果需要终止处理,则在此处执行处理。
命令定义
每个函数使用的数据类型在 userproc_command.h
中描述,其内容可以自由编写。
每个命令的格式如下所示。
最低要求的参数位于顶部白色区域。 请不要更改这些。
下图的 userproc_command.h
中的 User param
部分(粉色部分),您可以定义参数。
每个命令的说明如下。
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 文件夹,然后按照以下步骤生成它:
-
进入
sdk
。cd spresense/sdk
-
配置 SDK。
-
现在,将生成名为
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
。了解有关配置功能本身的详细信息,请参考 配置 。 -
如果要对要录制的音频执行自己的信号处理,请设置Preprocess。
AudioRecorder 允许用户对录制的音频执行自己的信号处理。
如果要执行此操作,则必须在配置菜单中启用[Use preprocess]
。打开配置菜单。
tools/cofig.py -m
检查
[Use preprocess]
。[Examples] [Audio recorder example] [Use preprocess] <= Y (1)
1 Preprocess处理 有关Preprocess的详细信息,请参阅SDK开发人员指南 Set preprocess 。
-
-
编译。
make
了解有关编译的详细信息,请参考 编译 。 如果所有步骤都成功,将在
sdk
文件夹中创建名为nuttx.spk
的二进制映像。 -
与Hello示例一样,使用
tools/flash.sh
将生成的映像nuttx.spk
加载到 Spresense 中。tools/flash.sh -c /dev/ttyUSB0 nuttx.spk
-
加载完成并自动重新启动。
-
对于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。
如果要自定义,如自己的信号处理,请参考 此处 。 -
录制的声音将记录在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
的应用时,
将显示声音。
录制的音频可以在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 的数据通信控制,因此不要更改它。
包括启动和DSP通信处理。无需编辑。
定义与DSP通信命令的标头文件。
此文件包含所需的参数。
用户代码的标头文件。
用户代码正文。
写入或调用此文件,如信号处理。
4.3.1.2. 用户代码提供的接口
userproc.cpp 提供 Init
、 Exec
、 Flush
和 Set
命令框架。
用户代码可以通过编写相应的内容来实现DSP中的处理。
描述用户应执行的操作。
(默认情况下,RC 筛选器作为示例内置。)
通过命令在DSP内部进行状态转换,如下图所示。
使用每个命令按以下方式处理。
-
当调用 AUDCMD_INIT_MICFRONTEND 时,DSP将启动。
-
设置
Init
命令所需的参数,如ch数和位长度。 -
开始录制时,捕获的语音数据会定期发送到DSP与
Exec
命令,因此请执行所需的筛选。 -
如果要随时更改DSP中的参数等,则希望通过发送
Set
命令来实现它。 此命令的执行时间按接收顺序显示,包括Exec
。 -
如果停止录制,则最后一个语音数据
Exec
后跟Flush
命令,因此,如果需要终止,请在此处执行此操作。
定义命令
每个功能使用的数据类型都写入 userproc_command.h
,可以自由重写其内容。
每个命令的格式如下图所示。
顶部白色部分具有固定所需的最小参数。请不要更改。
开发者在 userproc_command.h
中定义的参数是下图中的 User param
(粉红色部分)。
描述每个命令。
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 *)
-
按照 InitParam ,编写初始化过程。
使用应用程序代码中的 AUDCMD_INIT_PREPROCESS_DSP 命令运行。
(默认情况下,不工作。)
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 *)
-
按照 SetParam 编写设置功能。
使用应用程序代码中的 AUDCMD_SET_PREPROCESS_DSP 命令运行。
(默认情况下,设置RC滤波器的系数)
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 文件夹,然后按照以下步骤生成它:
-
进入
sdk
。cd spresense/sdk
-
配置 SDK。
-
现在,我们将构建一个 Example 应用程序,称为"audio_recognizer",因此我们将指定"examples/audio_recognizer。
tools/config.py examples/audio_recognizer
此配置为audio_recognizer设置。
-
如果要根据识别库的格式处理语音数据,请设置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 。
-
-
编译。
make
详细信息,请参考 编译 。 如果所有步骤都成功,将在
sdk
文件夹中创建名为nuttx.spk
的二进制映像。 -
与Hello示例一样,使用
tools/flash.sh
将生成的映像nuttx.spk
加载到 Spresense 中。tools/flash.sh -c /dev/ttyUSB0 nuttx.spk
-
加载完成并自动重新启动。
-
对于音频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 卡上。
二进制文件PREPROC
在spresense/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
的应用时,
开始语音识别。
识别结果由应用程序代码中的回调函数接收。
接收的参数由用于语音识别的 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)的数据通信控制,因此不要更改它。
包括启动和DSP通信处理。无需编辑。
定义与预处理DSP通信命令的标头文件。
此文件包含所需的参数。
用于预处理的DSP用户代码的标头文件。
用于预处理的DSP的用户代码正文。
写入或调用此文件,如信号处理。
定义与识别DSP通信命令的标头文件。
此文件包含所需的参数。
用于识别DSP的用户代码头文件。
用于识别DSP的用户代码正文。
在此文件中编写或调用识别过程。
5.3.1.2. 用户代码提供的接口
提供 Init
、 Exec
、 Flush
和 Set
命令框架
用户代码可以通过编写相应的内容来实现DSP中的处理。
描述用户应执行的操作。
(※ 默认情况下, PREPROC
作为示例包含 RC 筛选器。)
命令的DSP内部状态转换如下图所示。
使用每个命令按以下方式处理。
-
当调用 AUDCMD_INIT_RECOGNIZER 时,将启动识别DSP。
-
设置
Init
命令所需的参数,如ch数和位长度。 -
启动识别过程时,捕获的语音数据将定期发送到DSP的
Exec
命令,因此请执行所需的识别过程。 -
如果要随时更改DSP中的参数等,则希望通过发送
Set
命令来实现它。 此命令的执行时间按接收顺序显示,包括Exec
。 -
如果停止识别处理,则在最后一个语音数据
Exec
之后发送Flush
命令,因此,如果需要终止处理,请在此处执行此操作。
定义命令
每个功能使用的数据类型在 PREPROC
中写入 userproc_command.h
,在 RCGPROC
中写入 rcgproc_command.h
,内容可以自由重写。
每个命令的格式如下图所示,在 PREPROC
和 RCGPROC
中是相同的。
顶部白色部分具有固定所需的最小参数。请不要更改它们。
用户在 userproc_command.h
中定义的参数是下图中的 User param
(粉红色部分)。
notification
是 Exec
命令的响应(识别结果)标志,它使用非零规范将响应返回到应用程序。
例如,它通常用于仅在识别结果更改点(无识别→点)时响应,而不返回响应。
描述每个命令。
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 *)
-
InitRcgParam 编写初始化过程。
从应用程序代码的 AUDCMD_INIT_RECOGNIZER_DSP 命令运行。
(默认情况下,Ch数和位宽度设置。)
void RcgProc::exec(ExecRcgParam *)
-
ExecRcgParam 编写信号处理。
开始录制时定期从SDK内部调用。
在此示例应用程序中,一帧是320个样本(可以在应用程序中自由更改它)。
从输入数据地址获取数据,执行识别过程,并将结果写入输出数据地址。
(默认情况下,输出输入帧中样本值的最大、最小和平均值。)
void RcgProc::flush(FlushRcgParam *)
-
按照 FlushRcgParam 编写Flush(终止)处理。
停止录制时,仅在SDK内部调用一次。
如果识别过程出现帧延迟,请在最终帧后执行flush
以输出延迟。
如果要输出任何数据,请写入输出数据地址。
(默认情况下,无操作。)
void RcgProc::set(SetRcgParam *)
-
请根据 SetRcgParam ,编写设置过程。
使用应用程序代码中的 AUDCMD_SET_RECOGNIZER_DSP 命令运行。
(默认情况下,设置识别过程的On/Off。)
5.3.2. Step2. PREPROC
、 RCGPROC
二进制文件的生成
生成此应用程序时,将自动创建 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 文件夹,然后按照以下步骤编译:
-
进入
sdk
目录。cd spresense/sdk
-
配置SDK。
现在,将构建名为zmodem
的系统工具,并指定feature/zmodem
。tools/config.py feature/zmodem
有关配置的详细信息,请参阅 配置 。 -
编译。
make
详细信息,请参考 编译 。 如果所有步骤都成功,将在
sdk
文件夹中创建名为nuttx.spk
的二进制映像。 -
使用
tools/flash.sh
将生成的映像nuttx.spk
加载到 Spresense 板上。tools/flash.sh -c /dev/ttyUSB0 nuttx.spk
-
加载完成并自动重新启动。
6.2. 操作说明
使用支持Zmodem传输功能的串行终端。
下面是一个示例minicom。
如果未安装minicom或lrzzz,请预安装它。
sudo apt install minicom lrzsz
启动 minicom。
minicom -D /dev/ttyUSB0 -b 115200
可以使用来自NuttShell中Zmodem的rz(接收)和sz(发送)命令。
- 使用rz命令
-
- 使用sz命令
-
6.2.1. 从主机PC传输文件到Spresense板
以下是将文件从主机PC传输到Spresense板的步骤:
-
在minicom上按
CTRL-a
,然后按z
打开菜单。(此快捷键的分配由用户更改。有关详细信息,请参阅minicom文档。)
继续按s
键选择Send files发送文件。 -
使用光标键选择 zmodem 并使用
Enter
键运行。 -
使用光标键和空格键移动文件夹,然后选择要传输的文件。
使用光标键选择文件夹,然后按空格键两次以导航到文件夹。
使用光标键选择文件,使用空格键选择文件,然后按Enter
开始传输。或者,可以按
Enter
输入文件名以执行传输。 -
如果文件传输开始,并且显示为Transfer complete,则传输已完成。
-
可以在CONFIG_SYSTEM_ZMODEM_MOUNTPOINT中更改Spresense板上的文件目标。
默认配置将文件传输到Flash上的/mnt/spif
以下。
使用TeraTerm时,可以从菜单中发送 Files → Transfer → ZMODEM → Send 中选择的文件。
|
6.2.2. 从Spresense板传输文件到主机PC
以下是将文件从Spresense板传输到主机PC的步骤。
-
在NuttShell上,指定要传输到
sz
命令参数的文件。
文件名为 / 输入以完整路径名称开头的文件名。
下面的示例具有-x 1
二进制传输选项。nsh> sz -x 1 /mnt/spif/test00.dat
-
如果文件传输开始,并且显示为Transfer complete,则传输已完成。
-
将文件传输到在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内核的配置和构建的说明。)
-
启用hello应用程序并打开menuconfig配置菜单。
./tools/config.py -m examples/hello
-
启用
Support ROMFS start-up script
。System tools --> NSH Library ---> Scripting Support
-
选择
ROMFS header location
作为Custom ROMFS header path
。 在Custom ROMFS header file path
中,输入../../nsh_romfsimg.h
并保存配置。指定 nsh_romfsimg.h
相对于sdk/system/nshlib目录的位置。 -
接下来,直接在sdk目录下创建一个名为
rcS.template
的启动脚本。
在此,作为示例,如下描述echo
命令和hello
命令。cat spresense/sdk/rcS.template echo Start-up hello application hello
-
使用
mkromfsimg.sh
工具从rcS.template
生成nsh_romfsimg.h
。cd spresense/sdk ./tools/mkromfsimg.sh . ls nsh_romfsimg.h nsh_romfsimg.h
-
将以通常方式编译的二进制文件烧入Spresense板。
make tools/flash.sh -c /dev/ttyUSB0 nuttx.spk
-
打开电源时,可以在显示NuttShell之前确认脚本中编写的hello应用程序正在运行。
7.1.2. 更改脚本位置
如果要更改 rcS.template
的位置,请参考以下内容。
-
例如,将
rcS.template
放在spresense/examples/hello下。cat spresense/examples/hello/rcS.template echo Start-up hello application hello
-
使用
rcS.template
所在目录中的mkromfsimg.sh
工具生成nsh_romfsimg.h
。cd spresense/examples/hello ../../sdk/tools/mkromfsimg.sh ../../sdk ls nsh_romfsimg.h nsh_romfsimg.h
-
打开配置菜单
在Cutom ROMFS header file path
中,输入../../../examples/hello/nsh_romfsimg.h
。指定 nsh_romfsimg.h
相对于sdk/system/nshlib目录的位置。 -
其余的编译过程与之前相同。
7.2. SDK 入口点
您也可以与启动脚本分开更改CONFIG_INIT_ENTRYPOINT。
在默认配置中,CONFIG_INIT_ENTRYPOINT = nsh_main。
如果将其更改为例如hello_main,则可以更改为在启动时启动hello应用程序。
启动时需要应用程序初始化。引用以下内容添加#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编译时,应使用以下配置信息作为参考。
-
导航到
sdk
目录。装入
build-env.sh
脚本,启用config.py
工具的Tab完成功能。cd spresense/sdk source tools/build-env.sh
-
配置和编译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卡中。 -
将
nuttx.spk
写到Spresense板上。在这个例子中,串口被设置为
/dev/ttyUSB0
,写入速度的波特率被设置为500000
bps。 请根据您所使用的环境进行修改。tools/flash.sh -c /dev/ttyUSB0 -b 500000 nuttx.spk
8.2. 操作检查
打开串行终端,运行 hello
应用程序。
-
启动串行终端。
串行端口为
/dev/ttyUSB0
,波特率为115200
bps,则下面是一个使用minicom终端的例子。minicom -D /dev/ttyUSB0 -b 115200
-
从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!!