現(xiàn)成輪子OSAL操作系統(tǒng)抽象層的移植
簡單介紹一下Z-STACK中的OSAL,值得一看的現(xiàn)成輪子;
什么是 OSAL?
今天同學(xué)忽然問我有沒有搞過OSAL
,忽然間一頭霧水,于是在搜索引擎上找到了答案,發(fā)現(xiàn)這是一個十分實(shí)用的東西。
OSAL(operating system abstraction layer
),操作系統(tǒng)抽象層,是一種以實(shí)現(xiàn)多任務(wù)為核心的系統(tǒng)資源管理機(jī)制,實(shí)現(xiàn)了類似RTOS
的某些功能,但并不能稱之為真正意義上的RTOS
,因?yàn)槠浔旧磉€不支持任務(wù)的掛起,任務(wù)的搶占等等功能。
但是這種機(jī)制,實(shí)現(xiàn)的代碼十分精簡,占用資源也非常少,對于資源十分緊張的嵌入式平臺,也可以完成比較復(fù)雜的邏輯功能。
在TI CC2530
的ZIGBEE
協(xié)議棧Z-STACK
中可以找到OSAL的身影,可以在官網(wǎng)上搜索z-stack
下載相關(guān)的源碼,其中就包含了OSAL
實(shí)現(xiàn)的源碼;
移除掉一些無關(guān)功能的代碼之后,剩下OSAL的源碼總共約1100多行代碼,全部由C語言實(shí)現(xiàn),資源占用約為
-
RAM:512Byte -
ROM:2KB
理論上可以移植到絕大多數(shù)的芯片平臺上。
源碼安裝
目前官網(wǎng)上最新的版本,下載安裝到本地;
安裝完成之后,可以到安裝目錄下,找到相應(yīng)的源碼,不過這里基本上是zigbee
的協(xié)議棧,所以OSAL
相關(guān)的部分在下圖所示的路徑中;
進(jìn)入到osal
路徑下的文件結(jié)構(gòu)如下圖所示;
這個OSAL
操作系統(tǒng)抽象層用于保護(hù)協(xié)議棧軟件組件不受程序硬件細(xì)節(jié)的影響,減少程序的耦合性,提高可移植性和復(fù)用性。它可以獨(dú)立于程序環(huán)境,并且提供了以下功能。
-
任務(wù)注冊、初始化、啟動; -
任務(wù)間的消息交換; -
任務(wù)同步; -
中斷處理; -
計時器; -
內(nèi)存分配;
Linux 上OSAL的移植
可以嘗試把OSAL
的框架移植到單片機(jī)上,進(jìn)行測試,這里是GitHub
上fork
的一個倉庫OSAL ,已經(jīng)具體的移植方法,可以在Linux
平臺上進(jìn)行測試,
void osal_main(void)
{
//系統(tǒng)硬件、外設(shè)等初始化
//禁止中斷
HAL_DISABLE_INTERRUPTS();
//osal操作系統(tǒng)初始化
osal_init_system();
//添加任務(wù)
osal_add_Task(print_task_init, print_task_event_process, 1);
osal_add_Task(statistics_task_init, statistics_task_event_process, 2);
//添加的任務(wù)統(tǒng)一進(jìn)行初始化
osal_Task_init();
osal_mem_kick();
//允許中斷
HAL_ENABLE_INTERRUPTS();
//設(shè)置初始任務(wù)事件,上電就需要自動輪詢的任務(wù)事件可在此添加
//啟動osal系統(tǒng),不會再返回
osal_start_system();
}
STM32上OSAL的移植
如果直接使用ti
官方的代碼改動會相對比較大,這里直接在github
上找到一份移植到stm32
的工程,直接fork了一份改成HAL
庫,可以參考一下stm32-osal, 克隆代碼之后,直接復(fù)制osal
文件夾到CubeIDE
工程目錄下,然后對工程文件列表進(jìn)行刷新,可以看到如下圖所示;
下面是作者基于ti
的osal
的移植說明:
-
完成 OSAL\hal\timer.c
文件,為系統(tǒng)提供時鐘; -
修改 OSAL\include\type.h
文件中的全局中斷開關(guān)函數(shù)(可以為空),添加芯片對應(yīng)的頭文件,根據(jù)需要修改數(shù)據(jù)類型重定義,根據(jù)芯片字長修改halDataAlign_t類型; -
根據(jù)需要修改 OSAL\osal\osal_memory.h
文件中的內(nèi)存池大小定義,文件中osalMemHdr_t類型需要確保長度為16bit或以上,非8位單片機(jī)需要設(shè)定內(nèi)存池的字節(jié)對齊; -
添加任務(wù)函數(shù)中的任務(wù)優(yōu)先級數(shù)值大的任務(wù)則優(yōu)先級高; -
根據(jù)需要修改 OSAL\include\osal_memory.h
文件中的OSALMEM_METRICS定義,有效則開啟內(nèi)存統(tǒng)計功能;
關(guān)鍵點(diǎn)
總體來說,因?yàn)檎驹诰奕说募绨蛏?,整體的代碼需要修改的部分已經(jīng)很少了。首先這個機(jī)制是根據(jù)時間片輪詢調(diào)度的,所以會對每個任務(wù)分配一個ID以及一個任務(wù)專屬的定時器,同時,使用一個鏈表管理每個任務(wù)的定時器,同樣的,每個定時器會更加任務(wù)ID來進(jìn)行匹配,所以,需要在hal增加對定時器更新的函數(shù);如下所示;
因?yàn)槭褂肅ubeMX修改配置,重新生成代碼后會覆蓋原文件stm32f1xx_it.c
,所以,重新生成的時候,注意添加osal_update_timers()
,如果對其他內(nèi)容感興趣的話,可以參考一下源碼;
測試代碼
使用串口3進(jìn)行任務(wù)測試,定義了兩個任務(wù),先貼出其中的一部分,詳細(xì)的可以全部的工程代碼;
int osal_main(void)
{
HAL_DISABLE_INTERRUPTS();
osal_init_system();
osal_add_Task(Serial_Task_Init,Serial_Task_EventProcess, 1);
osal_add_Task(Serial_Task_02_Init,Serial_Task_02_EventProcess, 2);
osal_Task_init();
osal_mem_kick();
HAL_ENABLE_INTERRUPTS();
//"hello task 01\r\n";
osal_start_reload_timer( Serial_TaskID, PRINTF_STR, 100);
//"hello task 02\r\n";
osal_start_reload_timer( Serial_Task_02_ID, PRINTF_STR_TASK_02, 500);
osal_start_system();
}
下面是運(yùn)行結(jié)果:
結(jié)語
如果不使用RTOS
,那么OSAL
也是不錯的選擇,不過還需要對其源碼需要進(jìn)一步的理解,這樣在出現(xiàn)問題的時候,才可以對癥下藥。
附件
該工程基于CubeIDE 1.3
:
百度網(wǎng)盤:https://pan.baidu.com/s/1zXkEp7jNoO-ODqMtU5YxBA)
提取碼:ncry
Github:https://github.com/hotsauce1861/osal.git
長按下圖二維碼關(guān)注,獨(dú)自前進(jìn),走得快;結(jié)伴而行,走得遠(yuǎn);在這里除了肝出來的文章,還有一步一個腳印學(xué)習(xí)的點(diǎn)點(diǎn)滴滴;
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!