本文介绍如何在ESP8266开发板上移植C-SDK4.0,并用demo连接至阿里云物联网平台。
准备工作
为完成实践,您需要准备:
- 开发板。本文使用的开发板为ESP-LAUNCHER, 即官方提供的ESP8266EX_Demo_Board。
- USB连接线。
- 运行Windows,Linux或者macOS的计算机。使用的主机开发平台为macOS。
搭建开发环境
建议用户先阅读乐鑫SDK Readme以加快开发环境搭建,下面关于macOS环境搭建请参见以下步骤:
- 安装必要的软件
执行
sudo easy_install pip
安装pip。执行
sudo pip install pyserial
安装pyserial。 - 克隆esp-idf官方仓库执行脚本如下所见:
cd ~ mkdir esp && cd esp git clone https://github.com/espressif/ESP8266_RTOS_SDK.git -b release/v3.3
下载完成后需要执行脚本
export IDF_PATH=~/esp/ESP8266_RTOS_SDK
配置idf sdk路径。说明- 本次移植演示使用
release/v3.3
分支,对应commit id为fd785ab0c50009ab93503ae785814136f6d1009b
。 - ESP8266_RTOS_SDK在v3.0之后的版本已做了esp-idf框架的改造,对于v3.0之前的非esp-idf框架版本,用户可自行调整并参见此教程完成对接。
- 本次移植演示使用
- 安装工具链和编译工具
手动下载macOS工具链, 将工具链解压存放在
~/esp
目录下:mkdir -p ~/esp cd ~/esp tar -xzf ~/Downloads/xtensa-lx106-elf-macos-1.22.0-100-ge567ec7-5.2.0.tar.gz
其他平台的工具链可在ESP8266 SDK GitHub页面获取。
配置工具链系统路径:
export PATH=$PATH:$HOME/esp/xtensa-lx106-elf/bin
用户可参见以下脚本在
$HOME/.bash_profile
中添加所有环境变量的配置:set_esp8266 () { exprot IDF_PATH=$HOME/esp/ESP8266_RTOS_SDK export PATH=$PATH:$HOME/esp/xtensa-lx106-elf/bin }
-
连接开发板
获取串口端口名,macOS可使用
ls /dev/cu.*
命令查询,本演示中的串口端口名为/dev/cu.usbserial-AH06UHLH
。 -
配置项目、编译、烧写和串口监视
- 所有配置必须在项目路径下完成,所以先执行脚本
cd examples/wifi/simple_wifi/
进入到examples/wifi/simple_wifi/目录中。 - esp-idf使用
make menuconfig
进行项目配置, 详情请参见下方移植思路。 - 配置完成后运行
make all
编译固件。 - 编译完成后运行
make flash
命令烧写固件(请确保开发板已进入下载模式)。 - 烧写成功后运行
make monitor
打开串口打印信息监视器(请确保开发板已进入工作模式)。
至此,用户已经完成了ESP8266开发环境的搭建,并完成了wifi station例程的编译烧写。
说明 请确保开发板已工作正常再进行下面的步骤。 - 所有配置必须在项目路径下完成,所以先执行脚本
-
移植C-SDK4.0
移植C-SDK的过程主要包括了SDK代码的导入,SDK port层文件配置和编译系统的配置。
SDK的
portfiles
目录已经包含了ESP8266的portfile,因此用户只需要导入SDK源码,配置编译系统即可完成移植工作。建议提前阅读idf的编译系统介绍以理解移植过程。用户需要先了解idf的一些基本概念:
- project:项目目录,仅包含了所有用于构建app的源文件和配置文件。
- components:功能独立的模块化代码, 将会编译成.a静态库并链接到APP,这些模块化的组件存放在idf的components目录下,用户可以添加自定义component。
ESP8266-sdk的编译系统默认使用GUN make,我们只需移入C-SDK代码, 编写C-SDK对应的
.mk
编译配置文件即可将C-SDK加入编译。
移植思路
移植思路有以下两种:
- 方法一: 在project目录中引入C-SDK,将SDK源码与用户app源码共同编译。
- 方法二: 将C-SDK作为idf自定义组件引入到idf的components目录中。
我们推荐用第二种方法, 将C-SDK作为独立组件有助于在不同项目中复用,并解除与用户app代码的耦合。主要的步骤如下:
-
添加C-SDK自定义组件
- 获取SDK。
- 用户需要下载附件posix_port.c(适配了esp8266), 用它将LinkSDK中portfiles/aiot_port/posix_port.c替换掉。
- LinkSDK与idf中都有mbedtls库,避免引用库冲突,修改文件$IDF_PATH/components/C-SDK/core/sysdep/core_adapter.c, 关闭CORE_ADAPTER_MBEDTLS_ENABLED宏定义。
- 将SDK复制到
$IDF_PATH/components
目录下, 在SDK目录下添加构建文件component.mk
,文件内容如下所见:COMPONENT_ADD_INCLUDEDIRS := core core/sysdep core/utils components/ota COMPONENT_SRCDIRS := core core/utils core/sysdep components/ota portfiles/aiot_port/ external
-
移植demo程序
我们通过修改
examples/wifi/simple_wifi/
下的example来完成mqtt上云的演示。原生的例程主要演示使用wifi station模式接入特定的wifi热点, 用户可下载附件源文件覆盖原有的
simple_wifi.c
-
项目配置、编译和烧写
进入
examples/wifi/simple_wifi/
项目路径, 运行make menuconfig
配置项目, 主要配置如下- 进入
SDK tool configuration
菜单,确保Compiler toolchain path/prefix
正确配合为xtensa-lx106-elf-
。 - 进入
Serial flasher config
菜单, 修改ESP8266开发板的默认串口端口名。 - 进入
Example Configuration
菜单, 配置使用Station模式,配置WiFi SSID/Password和最大重连次数。 - 调整主程序栈空间大小,进入
Component config
菜单的ESP8266-specific
子菜单,将Main task stack size
配置为4096
,保存并退出配置。
MBEDTLS配置
若用户要使用PSK作为TLS密钥交换方法, 则需要
- 进入
Component config
菜单的mbedTLS
子菜单, 进入TLS Key Exchange Methods
配置项。 - 打开
Enable pre-shared-key ciphersuites
开关。 - 同时在mbedtls组件的
component.mk
中添加CFLAGS += -DMBEDTLS_PSK_MAX_LEN=64
。
如下所示:
COMPONENT_ADD_INCLUDEDIRS := port/include mbedtls/include port/esp8266/include COMPONENT_SRCDIRS := mbedtls/library port port/esp8266 COMPONENT_OBJEXCLUDE := mbedtls/library/net_sockets.o COMPONENT_SUBMODULES += mbedtls CFLAGS += -DMBEDTLS_PSK_MAX_LEN=64
配置完成后,运行
make all
,make flash
完成编译和烧写。 - 进入
-
运行和日志信息
运行
make monitor
打开串口监视器,重启设备可以查看到以下日志:...... I (274) esp_image: segment 1: paddr=0x00073818 vaddr=0x40273810 size=0x0e5fc ( 58876) map I (300) esp_image: segment 2: paddr=0x00081e1c vaddr=0x3ffe8000 size=0x00a3c ( 2620) load I (301) esp_image: segment 3: paddr=0x00082860 vaddr=0x40100000 size=0x00a50 ( 2640) load I (308) esp_image: segment 4: paddr=0x000832b8 vaddr=0x40100a50 size=0x05854 ( 22612) load I (325) boot: Loaded app from partition at offset 0x10000 I (349) system_api: Base MAC address is not set, read default base MAC address from EFUSE I (359) system_api: Base MAC address is not set, read default base MAC address from EFUSE phy_version: 1155.0, 6cb3053, Nov 11 2019, 17:31:08, RTOS new I (413) phy_init: phy ver: 1155_0 I (418) reset_reason: RTC reset 1 wakeup 0 store 0, reason is 1 I (425) simple wifi: ESP_WIFI_MODE_STA I (473) simple wifi: wifi_init_sta finished. I (479) simple wifi: connect to ap SSID:C_SDK_Test password:1234abcd I (614) wifi: state: 0 -> 2 (b0) I (659) wifi: state: 2 -> 3 (0) I (671) wifi: state: 3 -> 5 (10) I (676) wifi: pm start, type: 2 I (2320) event: sta ip: 192.168.0.101, mask: 255.255.255.0, gw: 192.168.0.1 I (2329) simple wifi: got ip:192.168.0.101 I (2334) simple wifi: connected to ap SSID:C_SDK_Test password:1234abcd I (2342) simple wifi: Start linkkit main [1.990][LK-0313] MQTT user calls aiot_mqtt_connect api, connect [2.000][LK-0317] mqtt_basic_demo&a13FNXXXXXX [2.000][LK-0318] 4780A5F17990D8DC4CCAD392683ED80160C4C2A1FFA649425CD0E2666A8593EB [2.010][LK-0319] a13FNXXXXXX.mqtt_basic_demo|timestamp=2524608000000,_ss=1,_v=sdk-c-4.0.0,securemode=2,signmethod=hmacsha256,ext=1,| [2.020][LK-031A] devicename|hmacsha256|a13FNXXXXXX&mqtt_basic_demo|2524608000000 [2.020][LK-031A] 3A27B38E1BAB95462F8EA659C15EE26319286EB1CB7B372451EE82A30A9E7FDF establish mbedtls connection with server(host='a13FNXXXXXX.itls.cn-shanghai.aliyuncs.com', port=[1883]) [2.450][LK-0313] MQTT connect success in 460 ms AIOT_MQTTEVT_CONNECT [2.450][LK-0309] sub: /sys/a13FNXXXXXX/mqtt_basic_demo/thing/event/+/post_reply [2.460][LK-0309] pub: /sys/a13FNXXXXXX/mqtt_basic_demo/thing/event/property/post [LK-030A] > 7B 22 69 64 22 3A 22 31 22 2C 22 76 65 72 73 69 | {"id":"1","versi [LK-030A] > 6F 6E 22 3A 22 31 2E 30 22 2C 22 70 61 72 61 6D | on":"1.0","param [LK-030A] > 73 22 3A 7B 22 4C 69 67 68 74 53 77 69 74 63 68 | s":{"LightSwitch [LK-030A] > 22 3A 30 7D 7D | ":0}} suback, res: -0x0000, packet id: 1, max qos: 1 [2.530][LK-0309] pub: /sys/a13FNXXXXXX/mqtt_basic_demo/thing/event/property/post_reply [LK-030A] < 7B 22 63 6F 64 65 22 3A 32 30 30 2C 22 64 61 74 | {"code":200,"dat [LK-030A] < 61 22 3A 7B 7D 2C 22 69 64 22 3A 22 31 22 2C 22 | a":{},"id":"1"," [LK-030A] < 6D 65 73 73 61 67 65 22 3A 22 73 75 63 63 65 73 | message":"succes [LK-030A] < 73 22 2C 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 | s","method":"thi [LK-030A] < 6E 67 2E 65 76 65 6E 74 2E 70 72 6F 70 65 72 74 | ng.event.propert [LK-030A] < 79 2E 70 6F 73 74 22 2C 22 76 65 72 73 69 6F 6E | y.post","version [LK-030A] < 22 3A 22 31 2E 30 22 7D | ":"1.0"} pub, qos: 0, topic: /sys/a13FNXXXXXX/mqtt_basic_demo/thing/event/property/post_reply pub, payload: {"code":200,"data":{},"id":"1","message":"success","method":"thing.event.property.post","version":"1.0"} heartbeat response heartbeat response heartbeat response ......
日志说明
I (2342) simple wifi: Start linkkit main
为demo中添加的,用于标识C-SDK开始工作的日志信息。- 包含
[LK-XXXX]
的日志由C-SDK提供, 其中[2.450][LK-0313] MQTT connect success in 460 ms
表示MQTT建连成功,同时输出了建连用时。