Arduino开发ESP32程序注意点
在重构嵌入式项目中使用了 PlatformIO 开发 Arduino ESP32 .相比于传统的用C语言开发 , 这里 Arduino ESP32 框架的 API 比较简洁 , 用 C++ 也可以更加面向对象编程 , 对于熟悉以往应用层软件的同学更好切入 . 这里记录下一些开发中遇到的细节点.
前言
首先大致梳理下项目有哪些功能
- 蓝牙GATT
- WiFI连接
- MQTT
- LCD TFT屏幕绘制
- 串口读取
- OTA
串口读取
串口读取最好不要是轮询去取 , 而是事件回调中处理
1 | Serial1.onReceive(onSerialDataReceived); |
回调处理
蓝牙 , MQTT 等会遇到在回调中处理业务 . 这里不能直接在回调中进行耗时操作 . 部分回调是使用的中断进程 , 如果进行耗时操作则会遇到报错 , 或者影响后面的业务. 笔者这里是用了 FREERTOS 队列. 在回调中将业务消息发到队列然后等待操作.
多线程问题
笔者这里使用的是 ESP32 . 因为是双核 , 所以定义了两个队列分别运行在独立的核上 . 这里就会遇到资源竞争的问题 . 通常有几种做法 ,
1. 资源手动隔离
比如 CORE1 只处理 MQTT 相关的业务 , CORE0 只处理蓝牙的 . 而一个核心上只有一个队列 , 因此不会有竞争的情况 . 不过这个不太适用笔者的场景.
2. 加锁
这里针对 WiFi 和 蓝牙的操作定义了两个锁
1 | SemaphoreHandle_t wifiMutex; |
在使用开始和结束分别进行占用和释放操作
OTA
OTA升级这里是通过 HTTP 请求资源然后更新升级 . 本来是放在队列中 , 后面发现下载速度比较慢甚至因为其它任务停掉 , 后面用任务做时发现对任务栈的需求挺大不太合适. 最终是检查更新后写入变量 , 在 main.cpp
中去检查变量 , 然后停掉任务和队列专注进行OTA升级 , 速度比较块 . 固件包大小1.3M , 1min不到可以完成更新
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Halcyon Days!