13 KiB
开发指南
本文档旨在对用户从设置开发环境到应用开发提供帮助,以便使用基于 Espressif 的 ESP32-S3 芯片进行 AIoT 应用开发。
准备
-
开发环境的安装
按照 ESP-IDF 编程指南的指引完成 esp-idf 开发环境的安装,尽管有图形化的IDE和插件,但是我们推荐您手动安装并使用命令提示行进行编译。
按照以上指引完成的安装很可能并不是编译 esp-box 依赖的 esp-idf 版本,此时需要根据版本说明来切换 esp-idf 到指定的版本。以 commit id 为 2bdea81b2a 为例子,下面的命令将完成切换
cd esp-idf git fetch git checkout 2bdea81b2a git submodule update --init --recursive ./install.sh -
获取 esp-box
在命令提示行中进入到自己工作的目录后运行如下命令克隆仓库
git clone --recursive https://github.com/espressif/esp-box.git
编译并运行第一个应用
在成功完成准备工作后就可以开始编译第一个应用了,你可以从 examples/factory_demo 工程开始。
设置 esp-idf 环境变量
每打开一个新的命令提示行进行编译都需要这一步
cd esp-idf
. ./export.sh
进行编译
进入到工程目录下后编译
cd esp-box/examples/factory_demo
idf.py build
您将看到如下的 log 输出:
Executing action: all (aliases: build)
Running cmake in directory /home/user/esp-box/examples/factory_demo/build
Executing "cmake -G Ninja -DPYTHON_DEPS_CHECKED=1 -DESP_PLATFORM=1 -DIDF_TARGET=esp32s3 -DCCACHE_ENABLE=0 /home/user/work/esp-box/examples/factory_demo"...
-- Found Git: /usr/bin/git (found version "2.36.0")
-- Not find RMAKER_PATH, default is /home/user/work/esp-box/examples/factory_demo/../../components/esp-rainmaker
-- Component directory /home/user/work/esp-box/components/esp-rainmaker does not contain a CMakeLists.txt file. No component will be added
-- Component directory /home/user/work/esp-box/components/esp-rainmaker/components/esp-insights does not contain a CMakeLists.txt file. No component will be added
-- The C compiler identification is GNU 8.4.0
-- The CXX compiler identification is GNU 8.4.0
-- The ASM compiler identification is GNU
-- Found assembler: /home/user/esp/.espressif/tools/xtensa-esp32s3-elf/esp-2021r2-8.4.0/xtensa-esp32s3-elf/bin/xtensa-esp32s3-elf-gcc
......
Project build complete. To flash, run this command:
/home/user/esp/.espressif/python_env/idf4.4_py3.8_env/bin/python ../../../../esp/esp-idf/components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32s3 --no-stub write_flash --flash_mode dio --flash_size 16MB --flash_freq 80m 0x0 build/bootloader/bootloader.bin 0x8000 build/partition_table/partition-table.bin 0x16000 build/ota_data_initial.bin 0x20000 build/factory_demo.bin 0x3bd000 build/storage.bin 0x647000 build/model.bin
烧录固件并运行
BOX 开发板均可通过 USB 接口直接下载固件。在下载之前需要确保电脑正确识别了设备
- Linux 和 MacOS 通常无需安装驱动即可识别。
- 对于 Windos 系统的电脑,我们推荐使用
Windows 10及以上版本,在该系统下USB-Serial-Jtag的驱动将联网自动下载。如果使用Windows 7系统,请手动下载 USB-Serial-JTAG 驱动 并安装。
通过以下命令下载固件并打开监视器:
idf.py -p PORT flash monitor
请替换 PORT 为电脑识别到的端口名称,Linux 系统下通常为 /dev/ttyACM0
下载固件完成将会自动开始运行
调试应用程序
- JTAG 调试 参见:https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s3/api-guides/jtag-debugging/index.html
- 应用层跟踪 参见:https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s3/api-guides/app_trace.html
组件
包含以下组件:
| 组件 | 说明 |
|---|---|
| bsp | 包含已支持开发板信息以及板载外设的驱动 |
| esp-rainmaker | 与 Rainmaker 云连接 |
| esp-sr | 乐鑫语音识别库 |
| i2c_bus | I2C 驱动 |
| i2c_devices | 一些常用 I2C 设备驱动 |
| iot_button | 按键驱动 |
| lvgl | LVGL 图形库 |
| audio | 播放/文件管理/解码库 |
bsp 组件
-
boards
bsp_board.c 是系统调用文件,用以兼容不同硬件平台,目前 box 工程支持 BOARD_S3_BOX 和 BOARD_S3_BOX_LITE 两个硬件平台。系统初始化后,根据 iic detect 到的不同器件地址判断当前运行在哪个硬件平台,以分别调用不同的硬件初始化接口。
esp32_s3_box.c 和 esp32_s3_box_lite.c 分别是
BOARD_S3_BOX和BOARD_S3_BOX_LITE的具体硬件管脚配置和初始化实现。 -
codec
codec 目录下为硬件所需要用到的 Micphoone 和 Speaker 驱动接口
BOARD_S3_BOX_LITEADC Module ES7243 Codec Module ES8153 BOARD_S3_BOXADC Module ES7210 Codec Module ES8311 -
peripherals
bsp_btn.c 是 box 的按键处理接口,该接口和 iot button 组件协同工作。iot button 维护 button 事件注册链表,并建立 1ms 按键查询机制
button_create_com。 定时器会依次轮询bsp_btn_register_callback注册的按键事件,并根据按键的事件匹配触发应用层注册的回调函数CALL_EVENT_CB(ev)。-
BOARD_S3_BOX有boot1 个物理按键, 中间红色小圆点为TP虚拟按键。 boot 处理 wifi 的恢复出厂和中英文语言切换的触发功能。 -
BOARD_S3_BOX_LITE有boot1 个物理按键,preventernext3 个 ADC 按键。 boot 功能同上,3 个 ADC 按键作为功能切换的导航键。 ADC 按键设计使用一路 ADC,分别接上不同电阻,用 ADC 值来区分哪一路按键被按下,这种方式节省了 IO 口资源。
bsp_codec.c 提供了上述 codec 的接口中间件,这里实现了对不同 codec 和 ADC 芯片的统一调用。
bsp_i2c.c 提供了 i2c_bus 接口中间件。
bsp_i2s.c 提供了 i2s 接口中间件。
bsp_lcd.c 提供了显示与硬件接口的中间件。
-
bsp_spi_lcd_init根据 board 定义的管脚初始化 LCD 的 SPI 接口。 -
lcd_trans_done_cb是 SPI 数据发送完成的回调函数,让 LVGL 的刷图逻辑保持同步。p_on_trans_done_cb(p_user_data)->lv_port_flush_ready通知显示清除flushing标志位。 -
bsp_lcd_flush为 LVGL 通知驱动准备刷新接口,如果接口已经完成上一帧数据发送,接口会在此处调用esp_lcd_panel_ops.c/esp_lcd_panel_draw_bitmap将显示数据送至 SPI 接口。
-
esp-sr 组件
这里主要针对 SR 的一些应用接口展开介绍。
- 配置文件介绍
#define AFE_CONFIG_DEFAULT() { \ .aec_init = true, \ //AEC 算法是否使能 .se_init = true, \ //BSS/NS 算法是否使能 .vad_init = true, \ //VAD 是否使能 ( 仅可在语音识别场景中使用 ) .wakenet_init = true, \ //唤醒是否使能. .voice_communication_init = false, \ //语音通话是否使能。与wakenet_init 不能同时使能. .voice_communication_agc_init = false, \ //语音通话中AGC是否使能 .voice_communication_agc_gain = 15, \ //AGC的增益值,单位为dB .vad_mode = VAD_MODE_3, \ //VAD 检测的操作模式,越大越激进 .wakenet_model_name = NULL, \ //选择唤醒词模型 .wakenet_mode = DET_MODE_2CH_90, \ //唤醒的模式。对应为多少通道的唤醒,根据mic通道的数量选择 .afe_mode = SR_MODE_LOW_COST, \ //SR_MODE_LOW_COST: 量化版本,占用资源较少。 //SR_MODE_HIGH_PERF: 非量化版本,占用资源较多。 .afe_perferred_core = 0, \ //AFE 内部 BSS/NS/MISO 算法,运行在哪个 CPU 核 .afe_perferred_priority = 5, \ //AFE 内部 BSS/NS/MISO 算法,运行的task优先级。 .afe_ringbuf_size = 50, \ //内部 ringbuf 大小的配置 .memory_alloc_mode = \ AFE_MEMORY_ALLOC_MORE_PSRAM, \ //绝大部分从外部psram分配 .agc_mode = AFE_MN_PEAK_AGC_MODE_2, \ //线性放大喂给后续multinet的音频,峰值处为 -4dB。 .pcm_config.total_ch_num = 3, \ //total_ch_num = mic_num + ref_num .pcm_config.mic_num = 2, \ //音频的麦克风通道数。目前仅支持配置为 1 或 2。 .pcm_config.ref_num = 1, \ //音频的参考回路通道数,目前仅支持配置为 0 或 1。 } - 模型初始化以及设置介绍
/* ESP_AFE_SR_HANDLE:语音识别模型 * ESP_AFE_VC_HANDLE:语音通话模型 */ afe_handle = &ESP_AFE_SR_HANDLE; afe_config_t afe_config = AFE_CONFIG_DEFAULT(); /* 唤醒词模型命名方式为 wm*,命令词模型命名方式为mn* * esp_srmodel_filter 是一个封装了 model 分区搜寻模型的接口 */ afe_config.wakenet_model_name = esp_srmodel_filter(models, ESP_WN_PREFIX, NULL); afe_config.aec_init = false; //aec不使能 esp_afe_sr_data_t *afe_data = afe_handle->create_from_config(&afe_config); - 切换唤醒词和命令词模型
/* 唤醒词模型切换 */ wn_name = esp_srmodel_filter(models, ESP_WN_PREFIX, (SR_LANG_EN == g_sr_data->lang ? "hiesp" : "hilexin")); g_sr_data->afe_handle->set_wakenet(g_sr_data->afe_data, wn_name); //设置唤醒词模型 /* 命令词模型切换 */ mn_name = esp_srmodel_filter(models, ESP_MN_PREFIX, ((SR_LANG_EN == g_sr_data->lang) ? ESP_MN_ENGLISH : ESP_MN_CHINESE)); esp_mn_iface_t *multinet = esp_mn_handle_from_name(mn_name); model_iface_data_t *model_data = multinet->create(mn_name, 5760); //设置命令词模型 - 命令词设置接口
/* 加载模型自带命令词模型 * 命令词模型可从 menuconfig 如下路径进行修改: TOP -> ESP_SPEECH_RECOGNITION -> commands */ esp_mn_commands_update_from_sdkconfig(*multinet, *model_data); /* 代码手动操作命令词 * 用户可调用如下 API 进行命令词的操作 */ esp_err_t esp_mn_commands_add(command_id, *phoneme_string); esp_err_t esp_mn_commands_remove(*phoneme_string); esp_err_t esp_mn_commands_modify(*old_phoneme_string, *new_phoneme_string); esp_mn_error_t *esp_mn_commands_update(*multinet, *model_data); - rainmaker 与 sr 的接口
cmd_write_to_sr(&cmd)是 rainmaker 下发至 BOX 的语音指令修改接口。
SR 控制命令按照如下规则:
-
同一个控制命令最多对应
8条命令词,如果超过 8 条,新增命令词将替换表中最后 1 条。 -
相同语音命令词不允许重复添加。
-
lvgl 组件
这里主要介绍一下 LVGL 在 BOX_S3 上的移植接口。
-
输入设备
-
输入设备硬件初始化,
indev_init_default()根据输入设备的类型,分别作不同初始化。如上方
bsp_btn介绍,BOARD_S3_BOX_LITE采用 3 个导航键按键,BOARD_S3_BOX采用 TP 加 1 个 TP 的虚拟按键。TP:目前工程移植了两款触摸芯片,
tt21100和ft5x06。上电后通过tp_prob函数 detect 不同 IIC 地址来识别具体芯片,进行不同的初始化的初始化动作indev_tp_init。按键:在
bsp_btn按键初始化时候初始化。 -
注册输入设备
lv_port_indev_init()->lv_indev_drv_register()注册设备需要
type和read_cb两个参数。注册同时,内部会创建一个周期为LV_INDEV_DEF_READ_PERIOD的定时器,轮训外部输入事件。
-
-
文件系统
-
重定向文件操作 API
主要是根据平台重定向 fopen,fclose,fwrite 等接口。LVGL 封装了 lv_fs_fatfs , lv_fs_posix , lv_fs_sdio , lv_fs_win32 可供参考和配置,用户可在 menuconfig 进行配置,也可以自己实现。
-
文件盘符配置
Espressif 的文件系统盘符为
'S'。用户需要注意,lv_fs在进行所有文件操作时,都会先判断操作盘符是否匹配。不匹配的盘符会收到LV_FS_RES_NOT_EX的返回值,影响对文件的正常操作。
-
-
显示接口
显示初始化主要分为两个部分:硬件接口初始化,注册显示设备。下图简单介绍了 BOX 用到的初始化模块和相关联系。
