之前写过一篇博文是讲的<<Thread入坑(一):在ESP32上实现Thread(外接NRF52840做RCP)>>,当时的ESP-IDF与RCP的固件版本用的比较旧,这次更新一下.

首先是RCP端(NRF52840),用的库是这个:https://github.com/openthread/ot-nrf528xx

编译的流程可以参照这边:https://github.com/openthread/ot-nrf528xx/blob/main/src/nrf52840/README.md

其实就是先安装环境:

./script/bootstrap

然后编译:

./script/build nrf52840 UART_trans

然后bin文件转hex文件就行:

arm-none-eabi-objcopy -O ihex build/bin/ot-rcp ot-rcp.hex

另外值得一提的是,如果需要修改RCP所使用的的串口参数(tx rx的pin之类的),可以在ot-nrf528xx/src/nrf52840/transport-config.h文件里改,改好再编译就行.

但是transport-config.h中有一个设置需要注意(这玩意默认是会开串口硬件流控的):

#ifndef UART_HWFC_ENABLED
#define UART_HWFC_ENABLED 1
#endif

编译出来的hex大概141KB,烧进MCU里大概是50.3KB左右.

用新固件的RCP连接到之前的ESP32以后,ESP32启动会报错:

I (9I(968) OPENTHREAD:[INFO]-PLAT----: RCP reset: RESET_SOFTWARE
I (998) wifi: ESP_WIFI_MODE_STA
I(998) OPENTHREAD:[NOTE]-PLAT----: RCP API Version: 4
E(998) OPENTHREAD:[CRIT]-PLAT----: RCP API Version 4 is not in the supported range [1-3]
E(1018) OPENTHREAD:[CRIT]-PLAT----: CheckRcpApiVersion() at /mnt/hgfs/OneDrive/Workspace/thread_gateway/esp-idf/components/openthread/openthread/src/lib/spinel/radio_sp

abort() was called at PC 0x40103f4e on core 0

Backtrace:0x40090983:0x3ffd5840 0x40091155:0x3ffd5860 0x4009812e:0x3ffd5880 0x40103f4e:0x3ffd58f0 0x401eb41a:0x3ffd5910 0x4013bfda:0x3ffd5930 0x4013c126:0x3ffd5970 0x4013c24d:0x3ffd59b0 0x4013b506:0x3ffd59e0 0x400ff774:0x3ffd5a00 0x400947dd:0x3ffd5aa0

大概意思就是现在的RCP的API版本太高了,是RCP API Version: 4 ,ESP32端只支持1到3.

然后开始改ESP32端,先clone下来最新的ESP-IDF.

然后把之前的工程挪到新的ESP-IDF下编译.

目前看来新的ESP-IDF与旧的在Thread API这边有一些差异:

1.otMasterKey结构体在新IDF里改名成了otNetworkKey

2.esp_openthread_platform_init()函数改名成了esp_openthread_init()

3.没有了那套esp_openthread_platform_update(),esp_openthread_platform_process(),esp_openthread_platform_deinit()搭配的死循环处理机制.取而代之的是esp_openthread_launch_mainloop()+esp_vfs_eventfd_unregister()

4.另外新的IDF貌似是把openthread的实现部分用lib代替,估计是认证方面会方便..

然后再改了亿点点配置,编译出新IDF的固件后下到ESP32里运行,神奇的是所支持的RCP API版本还是没变......恩,行吧,那就降低RCP的版本吧,在ot-nrf528xx库里选一个早一点的提交,然后checkout到那个早点的提交,并且更新子模块到对应版本的状态(RCP的API版本主要取决于ot-nrf528xx库中的openthread子模块版本).

然后,编译运行,看重启ESP32端,啪,RCP API是版本3,一切OK~

I (798) cpu_start: App version:      v4.4-dev-2594-ga20df743f1-dirty
I (805) cpu_start: Compile time:     Aug 20 2021 01:41:31
I (811) cpu_start: ELF file SHA256:  732e8c913248c21b...
I (817) cpu_start: ESP-IDF:          v4.4-dev-2594-ga20df743f1-dirty
I (825) heap_init: Initializing. RAM available for dynamic allocation:
I (832) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (838) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (844) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (850) heap_init: At 3FFCFBB0 len 00010450 (65 KiB): DRAM
I (856) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (862) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (869) heap_init: At 4009D1D8 len 00002E28 (11 KiB): IRAM
I (876) spi_flash: detected chip: gd
I (879) spi_flash: flash io: dio
I (885) cpu_start: I(20) OPENTHREAD:[INFO]-PLAT----: RCP reset: RESET_SOFTWARE
I (951) wifi: ESP_WIFI_MODE_STA
I (961) wifi:wifi driver task: 3ffd97e0, prio:23, stack:6656, core=0
I (961) system_api: Base MAC address is not set
I (961) system_api: read default base MAC address from EFUSE
I(971) OPENTHREAD:[NOTE]-PLAT----: RCP API Version: 3
I (981) wifi:wifi firmware version: 70f0192
I (981) wifi:wifi certification version: v7.0
I (991) wifi:config NVS flash: enabled
I (991) wifi:config nano formating: disabled
I (991) wifi:Init data frame dynamic rx buffer num: 32
I (1001) wifi:Init management frame dynamic rx buffer num: 32
I (1001) wifi:Init management short buffer num: 32
I (1011) wifi:Init dynamic tx buffer num: 32
I (1011) wifi:Init static rx buffer size: 1600
I (1021) wifi:Init static rx buffer num: 10
I (1021) wifi:Init dynamic rx buffer num: 32
I (1051) wifi_init: rx ba win: 6
I (1051) wifi_init: tcpip mbox: 32
I (1051) wifi_init: udp mbox: 6
I (1051) wifi_init: tcp mbox: 6
I(1061) OPENTHREAD:[NOTE]-MLE-----: Role Disabled -> Detached
I(1061) OPENTHREAD:[INFO]-MLE-----: AttachState Idle -> StartI (1061) wifi_init: tcp tx win: 5744


另外后面用了下RCP的log功能,感觉在关键时候还是很有用的,用法就是在编译RCP固件的时候的编译命令后加个参数:

-DOT_FULL_LOGS=1

变成这样:



 ./script/build nrf52840 UART_trans -DOT_FULL_LOGS=1

然后通过RTT就可以看到RCP端的log了.