上篇文章中使用的uart做了APP試驗,今天對其代碼做一下簡單的分析,上代碼:
解析:
一、文件中的結構體
/*app代碼中需要加入APP_CFG段 begin*/
#pragma arm section rodata = "APP_CFG"
APP_ENTRY_FLAG
#pragma arm section rodata
/*EAT app代碼中需要加入APP_CFG段 end*/
#pragma arm section rodata="APPENTRY" // APP函數入口
#pragma arm section rodata //入口段結束
二、具體任務說明:
EAT_USER_0,EAT_USER_1,EAT_USER_2 …EAT_USER_8 是用戶可使用的9個線程,如果在結構體EatEntry_st 數據中的成員被賦值,同時系統沒有在升級過程中,則該入口會被調用,同時系統分配task相關的信息。
如下示例,app_main,app_func_ext1,app_user1,app_user3會被調用:
const EatEntry_st AppEntry =
{
app_main,
app_func_ext1,
(app_user_func)app_user1,//app_user1,
(app_user_func)app_user2,//app_user2,
(app_user_func)app_user3,//app_user3,
(app_user_func) EAT_NULL,//app_user4,
(app_user_func) EAT_NULL,//app_user5,
(app_user_func) EAT_NULL,//app_user6,
(app_user_func) EAT_NULL,//app_user7,
(app_user_func) EAT_NULL,//app_user8,
……
};
三、多線程功能描述
平臺提供多線程功能,目前支持1個主線程和最多8個子線程,主線程用於和系統通信,如接收系統事件。
高優先級的suspend的線程,在滿足運行條件時,會優於正在運行的低優先級的線程得到調度。
系統啓動後先檢測是否存在app_main存在,若存在則休眠3秒,然後進行EAT 模塊初始化,進入app_main函數內
在Msg loop內循環。緊接着,系統檢測是否存在app_user函數且不在升級的情況下,若存在則休眠3.1秒,然後進入app_user1
函數等待線程內的事件觸發。其他app_user依次類推。
uart文件中,APP函數啓動步驟如上圖所示,先進行app_main的初始化,再進入app_func_ext1,然後最後進入app_user1
進行運行。此時app_main和app_user1兩處線程共同在等待事件的觸發。
觸發對應的事件,就會執行不同的case。電腦與SIM800C之間的串口通信的流程圖如下圖所示:
在發送完成後,會觸發EAT_EVENT_UART_SEND_COMPLETE和EAT_EVENT_UART_READY_WR兩個事件。
而在SIM800C與modem進行UART的通訊之會觸發EAT_EVENT_MDM_READY_WR一個事件,如下圖所示:
四. 使用注意事項
1) 對於消息發送,函數eat_send_msg_to_user 可以在app_main 及app_user1 app_user2 …app_user8之間使用。
2) 系統消息可以發送給子線程,遵循的原則是從哪個線程調用的API,則對應的消息就發送給哪個線程。
例如在user1中調用eat_uart_open(EAT_UART_1)打開串口1,則當串口1收到數據時,EAT_EVENT_UART_READY_RD(event.uart.uart=EAT_UART_1)消息會上報到user1中。
例如:在app_main中調用eat_timer_start(EAT_TIMER_1),在user1中調用eat_timer_start(EAT_TIMER_2),則當EAT_TIMER_1時間到後,EAT_EVENT_TIMER(event.timer.timer_id = EAT_TIMER_1)消息會發送到app_main,當EAT_TIMER_2時間到後,EAT_EVENT_TIMER(event.timer.timer_id=EAT_TIMER_2)消息會發送到user1中。
例如:在user1中調用eat_modem_write(“AT\r\n”,4)發送AT指令到Core,則AT指令執行結果通過消息EAT_EVENT_MDM_READY_RD上報到user1。此後AT的URC上報也會發送到user1,直到其他線程,例如user2發送AT指令,此後AT執行結果及URC消息會發送到user2。
開機過程中的AT URC消息(EAT_EVENT_MDM_READY_RD)默認上報到main線程,可以通過eat_modem_set_poweron_urc_dir( )設置開機URC發送到指定線程。
3) eat_get_event或者eat_get_event_for_user 是同步接口,當調用該接口時,如果該線程有EVENT,則立即返回,如果沒有,則線程會掛起。
如果不需要線程掛起,則可以先用eat_get_event_num()或者eat_get_event_num_for_user(EAT_USER_x)獲取當前線程事件隊列中事件個數,如果爲0,則不調用eat_get_event(_for_user)接口,大於0再調用該接口。