一、esp-open-rtos概要

Esp-open-rtos是开源的、基于freertos的、用于ESP8266固件的开发支持环境。最早是从乐鑫官方的ESP8266_RTOS_SDK基础上fork而来,但是目前的代码、框架已经和原SDK相去甚远,有了大幅的变化。从代码结构、编译方法、支撑库等均有不同,而且内置了更多的常见传感器驱动,以及MQTT、TLS、甚至OTA等常用的功能模块。相比官方同样的RTOS SDK、感觉更好用、更便利、开发应用速度更快。
目前,esp-open-rtos在github上获得了550多个STAR,足以证明其被认可的程度。
Github地址:https://github.com/SuperHouse/esp-open-rtos

Esp8266的项目较多,容易混淆,总结如下:

  • 1) esp-open-sdk esp8266编译工具链
  • 2) esp-open-rtos 基于FreeRTOS的esp8266固件
  • 3) ESP8266_NONOS_SDK 乐鑫官方非OS版本固件、带AT固件
  • 4) ESP8266_RTOS_SDK 乐鑫官方RTOS固件(基于FreeRTOS)
  • 5) nodemcu-firmware NodeMCU的lua固件
  • 2~5均使用同样的编译工具链1。

二、esp-open-rtos安装

1、编译工具链的建立(toolchain)
交叉编译工具链和乐鑫官方SDK相同,均使用esp-open-sdk。
安装方法可参照前面文章:【ESP8266固件的编译1(交叉编译工具链的建立)】。
简便起见,推荐使用【make STANDALONE=y】。

2. 代码下载
如下命令从github上下载代码。

git clone --recursive https://github.com/Superhouse/esp-open-rtos.git
使用recursive,可以将依赖的第三方代码一起获取。

三、代码编译

乐鑫官方的RTOS SDK是先编译底层支撑代码,以库的形式提供。
应用层通过连接库的的方式和底层代码链接在一起,build为bin,存在两个阶段。
具体可参照前文:
【ESP8266固件的编译5(RTOS SDK固件)】

但eps-open-rtos采用了另外一种方式,它没有底层代码编译库的过程。
而是以应用为中心,每个应用都会将所有底层代码复制一份
(从FreeRTOS到lwip,再到各种依赖库和应用层代码)每个应用都会复制并编译属于自己的这份,
并和自身的应用层代码一起编译。(其实最终也会通过库的形式,但是编译过程是一体化的)

另外Esp-open-rtos的编译采用make,摆脱了cmake,感觉清爽、瘦身很多。
编译时可通过make help来看到编译相关的帮助,尤其是make flash。

非常重要的是,
Esp-open-rtos在examples目录下提供了很多例子(很赞),上手可以很快。

1、编译准备
在编译之前,需要在include目录下,创建private_ssid_config.h文件,
来预定义系统默认wifi参数,内容如下:

#define WIFI_SSID "mywifissid"#
define WIFI_PASS "my secret password"

2. mqtt_client的编译
上面已经说明过,esp-open-rtos以应用为中心编译,
下面以mqtt_client为例进行说明

编译方法1,在esp-open-rtos根目录下,执行

make -C examples/mqtt_client/

编译方法2,进入到examples/mqtt_client目录下,直接执行

make

3. esp8266的相关参数设定
系统默认的esp8266相关的参数,如SPI类型、Flash大小等,定义在根目录下的parameters.mk中,如下:

FLASH_SIZE ?= 16
FLASH_MODE ?= qio
FLASH_SPEED ?= 40123

?= 是make的语法,意为如果没有定义,就使用=后的值做赋值,相当于默认参数。
如果目标硬件(ESP8266模组)固定,可以直接修改此文件。
若目标硬件经常变化,如经常切换ESP01和ESP12,也可以修改应用目录下的Makefile文件进行配置:

PROGRAM=mqtt_client
FLASH_SIZE ?= 32
FLASH_MODE ?= qio

EXTRA_COMPONENTS = extras/paho_mqtt_c
include ../../common.mk123456

因使用安信可的ESP12F模块,所以将FLASH_SIZE修改为32,
如使用nodeMCU,除FLASH_SIZE外,还要将FLASH_MODE改为dio。

注意EXTRA_COMPONENTS宏,是esp-open-rtos的Make体系中指明依赖组件的宏,
所有需要依赖的扩展都要定义在该宏中(空格分隔)
这里可以看出,mqtt的协议是使用的Apache Paho(根据esp8266移植过)

MQTT本身的参数设定,可在在mqtt_client.c中修改。

编译成功后,在examples/mqtt_client/ firmware目录下,
会生成名为mqtt_client.bin的固件文件。

4. mqtt_client代码解析
mqtt_client的代码简单且结构清晰:
主函数启动3个task,分别是:

  • wifi管理task
  • mqtt管理task
  • 以及mqtt连接成功后定时pub的测试task

wifi_alive是一个信号灯(semaphore),用于协调wifi task和 mqtt task,以保证网络正常后再进行mqtt处理。
publish_queue是一个消息队列,用于beat_task和mqtt task间的数据传递,用于定时向【/beat】主题发布。
另外,mqtt task中在mqtt连接建立后,会订阅【esptopic】主题,并显示收到的消息。
下面是入口函数user_init的实现。

void user_init(void)
{
    uart_set_baud(0, 115200);
    printf("SDK version:%s¥n", sdk_system_get_sdk_version());

    vSemaphoreCreateBinary(wifi_alive);
    publish_queue = xQueueCreate(3, PUB_MSG_LEN);
    xTaskCreate(&wifi_task, "wifi_task",  256, NULL, 2, NULL);
    xTaskCreate(&beat_task, "beat_task", 256, NULL, 3, NULL);
    xTaskCreate(&mqtt_task, "mqtt_task", 1024, NULL, 4, NULL);
}1234567891011

四、固件下载(刷写)

因为esp-open-rtos内置了esptool.py,可用make flash进行直接做固件刷新。
但在windows上,还是使用官方的下载工具更加方便。
关于固件下载工具的使用,可参照前文【ESP8266固件的编译5(RTOS SDK固件)】。
和其他固件的刷新方法一样,但写入地址方面,和乐鑫官方、nodemcu差别较大。

观察make flash的命令输出:

esptool.py -p /dev/ttyUSB0 --baud 115200 write_flash -fs 32m -fm qio -ff 40m
0x0 ../../bootloader/firmware_prebuilt/rboot.bin 0x1000 ../../bootloader/firmware_prebuilt/blank_config.bin 0x2000 ./firmware/mqtt_client.bin12

可以看到,出mqtt_client.bin外,还要刷入预置的,
存放于bootloader/firmware_prebuilt目录下rboot.bin和blank_config.bin。

其写入地址为:

rboot.bin               0x0000
blank_config.bin        0x1000
mqtt_client.bin         0x2000

刷入后,如网络征程,即可以看到wifi连接成功后,mqtt的通信状况。
ESP8266侧如图:

框内内容分别是,wifi接入,mqtt接入,和收到mqtt消息。

服务端可用如下命令测试(mosquitto):

发布:
mosquitto_pub -u test -P test -t /esptopic -m "hello world"

接收:
mosquitto_sub -u test -P test -t /beat

可以看到收到连续的beat消息。

如上,mqtt在esp8266上非常容易的便可被实现,而且还有多task的支持。
增加传感器,将读取数据通过mqtt送出,即可实现简单的IoT系统。
而且,esp-open-rtos对常见传感器(温度、光线 etc.)的驱动支持也相当不错。
examples目录下有例子,extras目录下有协议实现。

Last modification:May 6, 2021
如果觉得我的文章对你有用,请帮忙点一下上面的广告