本文介紹如何在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自訂群組件
- 擷取C Link 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建連成功,同時輸出了建連用時。