程序架構:
和普通單片機程序的比較
(1)普通單片機的程序運行時基於“主循環”的方式
Main.c文件中:
Int main(void)
{
初始化…………… //IO口,定時器,設置中斷………..
While(1)
{
……..
}
Return 0;
}
Void xxx_interrupt(void) //中斷處理函數
{
………………… //執行中斷處理
}
_____________________________________________________________________
_____________________________________________________________________
(2)ESP8266的SDK編程是基於“內核回調”的方式
User_main.c文件中:
Void user_init(void) //ESP8266內核爲用戶提供的初始化接口:用戶的【應用功能初始化入口】
{
初始化…………… //IO口,定時器,設置中斷………..
}
用戶看不見不能修改
-------------------------------------------------------------------------------------------------------
{
User_init(); //執行 用戶的【應用功能初始化】
while(1)//類似主循環
{
執行內核功能……..
執行用戶功能…….. //eg:用戶初始化中設定了1秒定時,那麼這裏將會執行定時器定時
}
}
-------------------------------------------------------
回調函數 //當滿足某條件時,內核調用這些回調函數
-------------------------------------------------------
Void xxx_cd(void) //eg:這是1S定時器的回調函數,那麼內核1S計時完成,將會調用此函數
{
LED閃爍…….. //eg:在此函數中用戶可以讓LED燈以2S的頻率閃爍
}
------------------------------------------------------------------------------------------------------------------------------------------
任務函數 //如果安排了任務,在系統空閒時,內核會調用任務函數
-------------------------------------------------------------------------------------------------------------------------------------------
Void xxx_task(void)
{
……………………………
}
Void xxx_interrupt(void) //中斷處理函數
{
………………… //執行中斷處理
}
------------------------------------------------------------------------------------------------------------------
注意事項:
ESP8266 物聯⽹平臺的所有⽹絡功能均在庫中實現,對⽤戶不透明。⽤戶應⽤的初始化
功能可以在 user_main.c 中實現。
void user_init(void) 是上層程序的⼊⼝函數,給⽤戶提供⼀個初始化接⼝,⽤戶可在
該函數內增加硬件初始化、⽹絡參數設置、定時器初始化等功能。
void user_init(void) 是上層程序的⼊⼝函數,給⽤戶提供⼀個初始化接⼝,⽤戶可在
該函數內增加硬件初始化、⽹絡參數設置、定時器初始化等功能。
對於 ESP8266_NONOS_SDK_v1.5.2 及之後版本,請在 user_main.c 增加函數 void
user_rf_pre_init(void) 和 uint32 user_rf_cal_sector_set(void),可參考
IOT_Demo 的 user_main.c。⽤戶可在 user_rf_pre_init 中配置 RF 初始化,相關 RF 設
置接⼝爲 system_phy_set_rfoption,或者在 Deep-sleep 前調⽤
system_deep_sleep_set_option。如果設置爲 RF 不打開,則 ESP8266 Station 及 SoftAP
均⽆法使⽤,請勿調⽤ Wi-Fi 相關接⼝及⽹絡功能。RF 關閉時,Wi-Fi 射頻功能和⽹絡堆
棧管理 API 均⽆法使⽤。
對於 ESP8266_NONOS_SDK_v2.1.0 及之後版本,⽤戶如果並未使⽤ DIO-To-QIO flash,
可以在 user_main.c 中增加空函數 void user_spi_flash_dio_to_qio_pre_init(void)
來優化 iRAM 空間。
SDK 中提供了對 JSON 包的處理 API,⽤戶也可以採⽤⾃定義數據包格式,⾃⾏對數據進
⾏處理
• Non-OS SDK 不像基於 RTOS 的應⽤程序⽀持任務調度。Non-OS SDK 使⽤四種類
型的函數:
- 應⽤函數
- 回調函數
- ⽤戶任務
- 中斷服務程序 (Interrupt Service Routines, ISR)
應⽤函數類似於嵌⼊式 C 編程中的常⽤ C 函數。這些函數必須由另⼀個函數調⽤。
應⽤函數在定義時建議添加 ICACHE_FLASH_ATTR 宏,相應程序將存放在 flash 中,被
調⽤時才加載到 cache 運⾏。⽽如果添加了 IRAM_ATTR 宏的函數,則會在上電啓動
時就加載到 iRAM 中。
回調函數是指不直接從⽤戶程序調⽤的函數,⽽是當某系統事件發⽣時,相應的回
調函數由 non-OS SDK 內核調⽤執⾏。這使得開發者能夠在不使⽤ RTOS 或者輪詢
事件的情況下響應實時事件。
要編寫回調函數,⽤戶⾸先需要使⽤相應的 register_cb API 註冊回調函數。回調
函數的示例包括定時器回調函數和⽹絡事件回調函數。
中斷服務程序 (ISR) 是⼀種特殊類型的回調函數。發⽣硬件中斷時會調⽤這些函數。
當使能中斷時,必須註冊相應的中斷處理函數。請注意,ISR 必須添加 IRAM_ATTR。
⽤戶任務可以分爲三個優先級:0、1、2。任務優先級爲 2 > 1 > 0。即 Non-OS
SDK 最多隻⽀持 3 個⽤戶任務,優先級分別爲 0、1、2。
⽤戶任務⼀般⽤於函數不能直接被調⽤的情況下。要創建⽤戶任務,請參閱本⽂檔
中的 system_os_task() 的 API 描述。例如,espconn_disconnect() API 不能直接
在 espconn 的回調函數中調⽤,因此建議開發者可以在 espconn 回調中創建⽤戶任
務來執⾏ espconn_disconnect。
• 如前所述,non-OS SDK 不⽀持搶佔任務或進程切換。因此開發者需要⾃⾏保證程
序的正確執⾏,⽤戶代碼不能⻓期佔⽤ CPU。否則會導致看⻔狗復位,ESP8266 重
啓。
如果某些特殊情況下,⽤戶線程必須執⾏較⻓時間(⽐如⼤於 500 ms),建議經常
調⽤ system_soft_wdt_feed() API 來喂軟件看⻔狗,⽽不建議禁⽤軟件看⻔狗。
• 請注意,esp_init_data.bin 和 blank.bin ⽂件⾄少需要燒錄⼀次,以⽤於正確的初
始化系統。應⽤程序必須在 user_rf_cal_sector_set 中設置 RF 校準扇區。
詳細參考:
ESP8266 Non-OS SDK API