380|1

1333

帖子

1

资源

五彩晶圆(初级)

【ESP32-Korvo测评】(3)ESP-Skainet工程的编译 [复制链接]

  既然 ESP-Korvo 具有语音处理的硬件,自然少不了官方的软件支持了。这次评测的重点是乐鑫提供的 ESP-Skainet 这个开放软件包,它提供了若干音频和语音识别的API支持,也包含了这个开发板的硬件驱动库。
  我是从 github 上把 esp-skainet 克隆到本地电脑上的。(也许还有其它更便捷的下载方式)因为 ESP-Skainet 自带了某一个版本的 ESP-IDF, 所以就不用单独下载 IDF 了。什么是 ESP-IDF? 这是 ESP32 的软件开发框架,包括了很多部件,并不是一个单纯的硬件支持库。比如说,IDF 提供了 bootloader, 做了比 STM32 MCU 启动代码多很多的工作;比如说,IDF 底层有 FreeRTOS, 编写一个应用的入口函数是 app_main() 而不是 main(). IDF给我的感觉是更接近操作系统的一个东西,把ESP32启动过程隐藏了,能想得到的BLE、网络支持、文件系统支持它都有。如果不用 IDF 的话对 ESP32 开发就很难下手(乐鑫说:我们把框架都给你搭好了,你就用吧……)
  有了 ESP-IDF 就可以开发 ESP32 了,那么用什么编译呢?自然需要 Xtensa 处理器的 gcc 编译工具,可以从乐鑫的网站上下载到。想折腾,自己用 GCC 的源代码编译也是可以的。但只有编译器还不够,因为 IDF 每个工程也需要配置,就绕不开使用使用乐鑫的 Python 脚本和辅助程序。这跟开发 STM32/LPC/ATSAM...都很不一样是不是?也难怪,因为 IDF 实在复杂太多了。如果是 Linux 系统,软件工具的问题就看系统上装的够不够使,如果是 Windows 系统呢?需要一个类似 Linux 下的操作环境,比如 cygwin, msys 然后使用经过移植的软件。乐鑫又给了金点子:不好装吗?我给你准备了一套,下载去就能用咯!
  我这次使用的是直接下过来的 esp32_win32_msys2_environment_and_esp2020r2_toolchain-20200601.zip 这个压缩包,里面有 msys2 环境下的软件,和 Xtensa 编译工具。直接解压缩就可以使用了,缺点嘛,就是对 windows xp 不友好,这是 msys2 版本的问题。

  启动 msys2 终端程序(mingw32.exe),试着编译一下 esp-skainet 里面 examples/get_started 这个工程。因为已存在 Makefile, 就直接 make 好啦。

#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#

PROJECT_NAME := get_started
EXTRA_COMPONENT_DIRS += ../../components/

include $(IDF_PATH)/make/project.mk

  这个 Makefile 包含了 IDF 里面实际用的编译指令,所以要设置一下 IDF 的路径:
        export IDF_PATH=../../esp-idf
  然后再 make 就一路编译下去了……居然编译了很久,可不像一个MCU的工程。结束后在生成的 build 目录下可以发现有超过百兆字节的文件。我还没有配置 IDF 组件, 用的 esp-skainet 原先默认的了。如果想配置,那么执行 make menuconfig, 出现跟配置 linux 内核相仿的字符界面:
config.png

  在编译完成后有如下的提示,说明怎么下载到板子:
To flash all build output, run 'make flash' or:
python /d/esp-skainet/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect 0x1000 /d/esp-skainet/examples/get_started/build/bootloader/bootloader.bin 0x10000 /d/esp-skainet/examples/get_started/build/get_started.bin 0x8000 /d/esp-skainet/examples/get_started/build/partitions.bin

  要烧写的文件有三个:bootloader.bin, get_started.bin, partitions.bin
  我使用连着板子的另一台机器来进行下载:
download.PNG

  复位之后运行正常,串口打印的内容和以前不同了。看来get_started例子启动了语音检测,那么就唤醒试试——可以工作。
get_started.PNG

  看看 main.c 里面写了什么。主函数是 app_main()

void app_main()
{
    codec_init();
    rec_rb = rb_init(BUFFER_PROCESS, 8 * 1024, 1, NULL);
#ifdef CONFIG_ESP32_KORVO_V1_1_BOARD
    mase_rb = rb_init(BUFFER_PROCESS, 8 * 1024, 1, NULL);
#else
    ns_rb = rb_init(BUFFER_PROCESS, 8 * 1024, 1, NULL);
#endif
    agc_rb = rb_init(BUFFER_PROCESS, 8 * 1024, 1, NULL);

    model_iface_data_t *model_data = wakenet->create(model_coeff_getter, DET_MODE_90);
    model_data_mn = multinet->create(&MULTINET_COEFF, 4000);

    xTaskCreatePinnedToCore(&recsrcTask, "rec", 2 * 1024, NULL, 8, NULL, 1);
#ifdef CONFIG_ESP32_KORVO_V1_1_BOARD
    xTaskCreatePinnedToCore(&maseTask, "mase", 2 * 1024, NULL, 8, NULL, 1);
#else
    xTaskCreatePinnedToCore(&nsTask, "ns", 2 * 1024, NULL, 8, NULL, 1);
#endif
    xTaskCreatePinnedToCore(&agcTask, "agc", 2 * 1024, NULL, 8, NULL, 1);
    xTaskCreatePinnedToCore(&wakenetTask, "wakenet", 2 * 1024, (void*)model_data, 5, NULL, 0);

    printf("-----------awaits to be waken up-----------\n");
}

  app_main() 做的是初始化和创建语音处理、识别有关的几个任务,然后就结束了。 在 wakenetTask 任务当中,接收语音并处理:

void wakenetTask(void *arg)
{
    model_iface_data_t *model_data = arg;
    int frequency = wakenet->get_samp_rate(model_data);
    int audio_chunksize = wakenet->get_samp_chunksize(model_data);
    int chunk_num = multinet->get_samp_chunknum(model_data_mn);
    printf("chunk_num = %d\n", chunk_num);
    int16_t *buffer = malloc(audio_chunksize * sizeof(int16_t));
    assert(buffer);
    int chunks = 0;
    int mn_chunks = 0;
    bool detect_flag = 0;

    while (1) {
        rb_read(agc_rb, (uint8_t *)buffer, audio_chunksize * sizeof(int16_t), portMAX_DELAY);
        if (detect_flag == 0) {
            int r = wakenet->detect(model_data, buffer);
            if (r) {
                float ms = (chunks * audio_chunksize * 1000.0) / frequency;
                printf("%.2f: %s DETECTED.\n", (float)ms / 1000.0, wakenet->get_word_name(model_data, r));
                detect_flag = 1;
                printf("-----------------LISTENING-----------------\n\n");
                rb_reset(rec_rb);
                rb_reset(ns_rb);
                rb_reset(agc_rb);
            }
        } else {
            int command_id = multinet->detect(model_data_mn, buffer);
            mn_chunks++;
            if (mn_chunks == chunk_num || command_id > -1) {
                mn_chunks = 0;
                detect_flag = 0;
                if (command_id > -1) {
                    speech_commands_action(command_id);
                } else {
                    printf("can not recognize any speech commands\n");
                }

                printf("\n-----------awaits to be waken up-----------\n");
                rb_reset(rec_rb);
                rb_reset(ns_rb);
                rb_reset(agc_rb);
            }
        }
        chunks++;
    }
    vTaskDelete(NULL);
}


  代码和串口打印的内容的确能对应上。后面就可以尝试改代码了。


回复

3339

帖子

1

资源

五彩晶圆(初级)

谢谢分享!

个人签名人已离开,无事别找,找也找不到。

回复
您需要登录后才可以回帖 登录 | 注册

最新文章 更多>>
    关闭
    站长推荐上一条 1/6 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表