背景介绍
ESP32 和 最新的 ESP32-S2 CPU 时钟可以达到 240Mhz, 在通用形单片机中算是比较高的,但是如果进行复杂的计算,有时还是不够用。我最近将之前做过的 ESP32 WiFi无人机项目,移植到 ESP32-S2 ,由于 ESPIDF 对两款芯片在代码库上进行了一致的封装,因此在基本功能的移植上比较通畅,但是在移植光流定点部分时遇到了问题。
由于 ESP32 是双核 CPU,因此在 CPU 资源上有很大空间,在多任务系统的开发上比较友好。ESP32-S2 虽然对 CPU 内核进行了升级,但是毕竟只有一个核,如果存在一个优先级比较高的复杂任务,那低优先级任务将难以获得 CPU 时间。
在本项目中,存在一个 KALMAN
状态估计 task,其中需要用软件实现矩阵乘法运算,均为单精度浮点类型,姿态计算以 10ms 一次的频率进行,但是单是计算时间就花费了 6ms,也就是说只剩 4ms 能够分给其他 task。由于更高优先级的 task 总的运行时间大于 4ms,因此低优先级任务无法获得 CPU 时间,导致系统无法正常工作。
如果连接了串口,芯片会打印 task 看门狗被触发 (不一定是报 KALMAN task 触发看门狗,也可能是任意优先级大于 KALMAN 的 task,可以看ESP32 system 看门狗思考一下为什么,哈哈 )
ESP32-S2 与 ESP32 的不同请参考:ESP32-S2 ESP32 ESP8266参数对比表格
解决方法
- 在
menuconfig
中提高 CPU 主频,最大可以开到240MHz
。 - 在
menuconfig
中开启编译优化,Compiler options>optimize for performance>Optimize for permance
。 - 使用
inline
内联频繁调用的函数,减少函数调用花销,但是应该注意 inline 用法。 - 使用
IRAM_ATTR
宏定义,将频繁调用的代码放在IRAM
中,加快运行速度。参考:ram-instruction-ram
#include "esp_attr.h"
void IRAM_ATTR gpio_isr_handler(void* arg)
{
// ...
}
- 在
menuconfig
中提高flash
频率,提高IROM
中代码读取速率。 - 在
menuconfig
中增加cache
大小,具体增加多少,根据 ram 空间确定,cache
增加会消耗内存空间。 - 利用
ULP
低功耗内核,将简单任务分配其中,减小主 CPU 任务数 - 调整 task,降低高耗时 task 优先级,提高其他关键 task 优先级,关闭不必要的 task 。
- 降低高耗时 task 运行频率