BES2300x筆記(1) -- SDK代碼架構與Battery模塊

哈嘍大家好,這是該系列博文的第一篇~ 篇~

<<【系列博文索引】快速通道 >>

首先上一個鏈接:參考鏈接

一、前言

拿到恆玄的SDK源碼之後,結合文檔花了一些時間研究,這篇就先介紹下代碼的框架和模塊之間的解耦處理。

二、代碼架構

1、 根據SDK的目錄可以看出,BES採用的是RTOS(RTX)嵌入式實時操作系統,並且用了ARM的CMSIS_RTOS API接口;
在這裏插入圖片描述
2、 我們知道程序運行開始的地方是RTX_CM_LIB.H裏面的_main_init(),主要是進行內核初始化、堆棧的設置、main線程的創建和開啓內核等。
在這裏插入圖片描述
3、 第一個線程os_thread_def_main就是main,接着看,在main.cpp文件中。
在這裏插入圖片描述
4、 app_os_init()裏有線程創建,這是CMSIS的風格,開發過STM32應該比較熟悉,用來定義線程、定時器和郵箱通訊等;
app_thread_tid = osThreadCreate(osThread(app_thread), NULL);
在這裏插入圖片描述
5、 app_thread爲線程loop函數,OSThread其實是一個宏,就是取地址而已
#define osThread(name) &os_thread_def_##name
在這裏插入圖片描述
一般在文件開頭會看到這樣的定義:osThreadDef其實也是一個宏
osThreadDef(app_thread, osPriorityHigh, 1, 2048, “app_thread”);
在這裏插入圖片描述這裏就是給一個結構體變量初始化賦值,然後把os_thread_def_app_thread的地址傳給os_thread()。結構體類型是:
在這裏插入圖片描述所以OSThreadDef是設置線程名、優先級以及堆棧大小,通過osThread獲取配置的結構體變量的指針,然後作爲參數傳入OSThreadCreate()。
6、 以上創建了另一個重要線程:app_thread,這個線程將是以後應用模塊修改與添加的主要線程。

7、 下面我們看一下app_thread線程裏面的具體做了什麼:
if (mod_handler[msg_p->mod_id])
int ret = mod_handler[msg_p->mod_id] (&(msg_p->msg_body));

在這裏插入圖片描述
8、 我們可以看到在app_thread線程中,通過app_mailbox_get()反覆的在獲取郵箱信息,並傳入mod_handler[]裏面。
static APP_MOD_HANDLER_T mod_handler[APP_MODUAL_NUM];
在這裏插入圖片描述
看其數據類型是一個函數指針數組,再看其數組下標的定義:
在這裏插入圖片描述
在這裏插入圖片描述
9、 全局搜索mod_handler,會找到app_set_threadhandle()接口。
在這裏插入圖片描述
到此,我們瞭解了各個模塊會註冊自己的回調函數,然後app_thread()會根據get的消息回調模塊對應的API進行處理。

10、 我們現在選取一個模塊APP_MODUAL_BATTERY(APP_MODULE_BATTERY),從app_set_threadhandle的調用入手,繼續研究模塊的架構。
在這裏插入圖片描述
可以看到app_battery_open()接口裏調用了
app_set_threadhandle(APP_MODUAL_BATTERY, app_battery_handle_process);
其中,app_battery_handle_process()就是BATTERY模塊的回調處理函數。
11、 app_battery_open()是由app_init()調用,初始化battery模塊。其中battery模塊用到的全局變量爲
在這裏插入圖片描述
從變量的初始化,我們看到定製化的設置都在tgt_hardware.h裏面,還有其他定製化的設置。
在這裏插入圖片描述
12、 在app_battery_handle_process()裏面,我們可以看到:
在這裏插入圖片描述
通過全局搜索APP_BATTERY_STATUS_OVERVOLT,發現是通過app_battery_irqhandler發出的事件
在這裏插入圖片描述
app_battery_measure.cb在app_battery_open()中有定義:
app_battery_measure.cb = app_battery_event_process;

在這裏插入圖片描述
上圖可以看到是通過app_battery_event_process把模塊的消息放到郵箱中。
13、 回到app_battery_irqhandler()
在這裏插入圖片描述
在這裏插入圖片描述

通過搜索,我們發現app_battery_timer_handler是定時器APP_BATTERY的回調函數,

至此,就搞明白了battery模塊的流程:
app_battery_open()配置定時器,對結構體進行初始化,註冊事件回調和模塊處理函數
—>定時調用app_battery_timer_handler()來獲取電池的電壓值
—>再通過app_battery_irqhandler()將轉換之後的電壓值與初始值比較,通過 app_battery_event_process發出不同的電池狀態
—>在app_battery_event_process()把消息放入郵箱中
—>最後app_thread線程取出消息,調用對應模塊的app_battery_handle_process()接口進行處理

14、 我們再回到app_battery_timer_handler()看下hal_gpadc_open()接口。
在這裏插入圖片描述
可以看到,傳入的回調函數指針,賦值給了 gpadc_event_cb[channel] ,另外,用到驅動的地方,要加互斥鎖。
15、 通過搜索gpadc_event_cb,進入hal_gpadc_irq_handler()接口;
在這裏插入圖片描述
gpadc_event_cb[ch])就是再通過app_battery_irqhandler()
通過上圖,看到 gpadc_event_cb調用了app_battery_irqhandler,並傳入了ADC掃描的值。
16、 繼續往下就是hal_gpadc_adc2volt()——> hal_gpadc_adc2volt_calib()等ADC底層接口
在這裏插入圖片描述

17、 另外,通過搜索hal_gpadc_irq_handler()接口,也可以找到hal_gpadc_irq_control()中斷獲取的流程
在這裏插入圖片描述

三、後續擴展

類比BATTERY模塊,可以繼續學習其他模塊,比如按鍵、BT都是同樣的機制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章