CMSIS-RTOS API是ARM公司為RTOS內(nèi)核制定的一套通用接口協(xié)議,它提供了一套「標(biāo)準(zhǔn)的API接口」,可以移植到各種各樣的RTOS上,使得上層的軟件、中間件、庫以及其他組件在不同的RTOS之上都可以正常工作。
這套API表現(xiàn)為兩個(gè)文件:cmsis-os.h和cmsis-os.c,也就是說,不同的RTOS內(nèi)核分別用自己的一套東西去適配.c文件中的接口,而用戶只需要調(diào)用.h文件中給出的API編寫應(yīng)用。
本文會(huì)列舉性的給出CMSIS-RTOS有哪些API和宏定義,并給出每類API的使用demo,學(xué)習(xí)者只需要了解這些東西,能看懂用CMSIS-RTOS API編寫的應(yīng)用程序即可~
基于TencentOS-tiny的CMSIS-RTOS API v1.02版本實(shí)現(xiàn):
cmsis_os.h
cmsis_os.c
基于TencentOS-tiny的CMSIS-RTOS API v2.1.3版本實(shí)現(xiàn):
cmsis_os2.h
cmsis_os2.c
CMSIS-RTOS API的整體架構(gòu)如下圖:
2. CMSIS-RTOS API列表
下面列出了 CMSIS-RTOS API v1.02 版本提供的所有API。
CMSIS-RTOS 所有API使用的錯(cuò)誤碼(cmsis-os.h):
typedefenum{
osOK=0,///CMSIS-RTOS API一些可選項(xiàng)控制是否開啟(cmsis-os.h):
#defineosFeature_MainThread1///
#defineosFeature_Pool1///2.1. 內(nèi)核信息和控制
API | 描述 |
---|---|
osKernelInitialize | 初始化RTOS內(nèi)核 |
osKernelStart | 啟動(dòng)RTOS內(nèi)核 |
osKernelRunning | Query if the RTOS kernel is running |
osKernelSysTick (可選) | Get RTOS kernel system timer counter |
osKernelSysTickFrequency (可選) | RTOS kernel system timer frequency in Hz |
osKernelSysTickMicroSec (可選) | Convert microseconds value to RTOS kernel system timer value |
osKernelInitialize
osStatusosKernelInitialize(void);
返回值:status code
osKernelStart
osStatusosKernelStart(void);
返回值:status code
osKernelRunning
int32_tosKernelRunning(void);
返回值:0表示RTOS未啟動(dòng),1表示RTOS已經(jīng)啟動(dòng)
osKernelSysTick
uint32_tosKernelSysTick(void);
返回值:RTOS內(nèi)核系統(tǒng)當(dāng)前的時(shí)間
2.2. 線程管理
?
##連接符的作用是連接兩個(gè)字符串,合為一個(gè)字符串。
?
CMSIS-RTOS API 存放線程參數(shù)管理的結(jié)構(gòu)體如下:typedefstructos_thread_def{
char*name;///CMSIS-RTOS API 定義線程的宏如下:
#defineosThreadDef(name,priority,instances,stacksz)
k_task_ttask_handler_##name; k_stack_ttask_stack_##name[(stacksz)]; constosThreadDef_tos_thread_def_##name= {#name,(os_pthread)(name),(osPriority)(priority),(instances), (&((task_stack_##name)[0])),(stacksz),((k_timeslice_t)0u),(&(task_handler_##name))}?
宏定義中的 instances 表示基于此任務(wù)參數(shù),創(chuàng)建出幾個(gè)任務(wù)實(shí)例,比如instances為2,則會(huì)創(chuàng)建出兩個(gè)任務(wù)。
?
CMSIS-RTOS API定義的獲取線程參數(shù)結(jié)構(gòu)體的宏如下:
#defineosThread(name)
&os_thread_def_##name管理線程參數(shù)的API如下:
API | 描述 |
---|---|
osThreadCreate | 創(chuàng)建線程并開始執(zhí)行 |
osThreadTerminate | 停止線程執(zhí)行 |
osThreadYield | 線程主動(dòng)讓出 |
osThreadGetID | 獲取當(dāng)前正在運(yùn)行線程的ID |
osThreadSetPriority | 改變線程優(yōu)先級(jí) |
osThreadGetPriority | 獲取線程優(yōu)先級(jí) |
osThreadCreate
osThreadIdosThreadCreate(constosThreadDef_t*thread_def,void*argument);
其中osThreadId被定義為k_task_t指針類型:typedefk_task_t*osThreadId;
返回值:TencentOS-tiny中的任務(wù)控制塊類型指針。
osThreadTerminate
osStatusosThreadTerminate(osThreadIdthread_id);
返回值:osStatus
osThreadYield
osStatusosThreadYield(void);
返回值:osStatus
osThreadGetID
osThreadIdosThreadGetId(void);
osThreadSetPriority
osStatusosThreadSetPriority(osThreadIdthread_id,osPrioritypriority);
osThreadGetPriority
osPriorityosThreadGetPriority(osThreadIdthread_id);
?
使用時(shí)需要特別注意,在TencentOS-tiny中,調(diào)用CMSIS-RTOS API提供的優(yōu)先級(jí)選項(xiàng)設(shè)置之后,實(shí)際設(shè)置的任務(wù)值是不同的。
?
CMSIS-RTOS API提供的線程優(yōu)先級(jí)宏定義如下:
typedefenum{
osPriorityIdle=-3,///statick_prio_tpriority_cmsis2knl(osPriorityprio)
{ if(prio==osPriorityError){ returnK_TASK_PRIO_INVALID; } return(k_prio_t)(3-prio); } staticosPrioritypriority_knl2cmsis(k_prio_tprio) { return(osPriority)(3-prio); }比如創(chuàng)建線程時(shí)設(shè)置為 osPriorityNormal=0,則「實(shí)際設(shè)置的任務(wù)優(yōu)先級(jí)為3」。
2.3. 通用等待函數(shù)
CMSIS-RTOS提供的等待函數(shù)API如下:
API | 描述 |
---|---|
osDelay | 等待指定的時(shí)間 |
osWait(可選) | 等待信號(hào)、消息、郵箱的某個(gè)事件 |
osDelay
osStatusosDelay(uint32_tmillisec);
返回值:osStatus。
2.4. 軟件定時(shí)器管理
CMSIS-RTOS API提供的存儲(chǔ)定時(shí)器參數(shù)的結(jié)構(gòu)體如下:typedefstructos_timer_def{
os_ptimercb;///CMSIS-RTOS API提供的定義一個(gè)軟件定時(shí)器的宏定義如下:
#defineosTimerDef(name,function)
k_timer_ttimer_handler_##name; constosTimerDef_tos_timer_def_##name= {(os_ptimer)(function),(&(timer_handler_##name))}CMSIS-RTOS API定義的獲取軟件定時(shí)器參數(shù)結(jié)構(gòu)體的宏如下:
#defineosTimer(name)
&os_timer_def_##nameCMSIS-RTOS API提供的軟件定時(shí)器管理API如下:
API | 描述 |
---|---|
osTimerCreate | 創(chuàng)建一個(gè)軟件定時(shí)器 |
osTimerStart | 啟動(dòng)軟件定時(shí)器 |
osTimerStop | 停止軟件定時(shí)器 |
osTimerDelete | 刪除軟件定時(shí)器 |
osTimerCreate
osTimerIdosTimerCreate(constosTimerDef_t*timer_def,os_timer_typetype,void*argument);
其中osTimerId被定義為k_timer_t指針類型:
typedefk_timer_t*osTimerId;
type參數(shù)為 os_timer_type 類型,表示軟件定時(shí)器的類型為單次觸發(fā)或者周期觸發(fā):
typedefenum{
osTimerOnce=0,///osTimerStart
osStatusosTimerStart(osTimerIdtimer_id,uint32_tmillisec);
返回值:osStatus。
osTimerStop
osStatusosTimerStop(osTimerIdtimer_id)
返回值:osStatus。
osTimerDelete
osStatusosTimerDelete(osTimerIdtimer_id);
返回值:osStatus。
2.5. 信號(hào)量管理
CMSIS-RTOS API提供的存儲(chǔ)信號(hào)量參數(shù)的結(jié)構(gòu)體如下:
typedefstructos_semaphore_def{
uint32_tdummy;///CMSIS-RTOS API提供的定義一個(gè)信號(hào)量的宏定義如下:
#defineosSemaphoreDef(name)
k_sem_tsem_handler_##name; constosSemaphoreDef_tos_semaphore_def_##name={0,(&(sem_handler_##name))}CMSIS-RTOS API定義的獲取信號(hào)量參數(shù)結(jié)構(gòu)體的宏如下:
#defineosSemaphore(name)
&os_semaphore_def_##nameCMSIS-RTOS API提供的信號(hào)量管理API如下:
API | 描述 |
---|---|
osSemaphoreCreate | 創(chuàng)建一個(gè)信號(hào)量 |
osSemaphoreWait | 等待信號(hào)量 |
osSemaphoreRelease | 釋放信號(hào)量 |
osSemaphoreDelete | 刪除信號(hào)量 |
osSemaphoreCreate
osSemaphoreIdosSemaphoreCreate(constosSemaphoreDef_t*semaphore_def,int32_tcount);
其中 osSemaphoreId 被定義為k_sem_t指針類型:
typedefk_sem_t*osSemaphoreId;
osSemaphoreWait
int32_tosSemaphoreWait(osSemaphoreIdsemaphore_id,uint32_tmillisec);
返回值:int32_t ,正常返回當(dāng)前count數(shù),失敗返回-1。
如果需要阻塞延時(shí),參數(shù)應(yīng)該設(shè)置為CMSIS-RTOS API提供的宏定義 osWaitForever :
#defineosWaitForever0xFFFFFFFF///
osSemaphoreRelease
osStatusosSemaphoreRelease(osSemaphoreIdsemaphore_id);
返回值:osStatus。
osSemaphoreDelete
osStatusosSemaphoreDelete(osSemaphoreIdsemaphore_id);
返回值:osStatus。
2.6. 互斥鎖管理
CMSIS-RTOS API提供的存儲(chǔ)互斥鎖參數(shù)的結(jié)構(gòu)體如下:
typedefstructos_mutex_def{
uint32_tdummy;///CMSIS-RTOS API提供的定義一個(gè)互斥鎖的宏定義如下:
#defineosMutexDef(name)
k_mutex_tmutex_handler_##name; constosMutexDef_tos_mutex_def_##name={0,(&(mutex_handler_##name))}CMSIS-RTOS API定義的獲取互斥鎖參數(shù)結(jié)構(gòu)體的宏如下:
#defineosMutex(name)
&os_mutex_def_##nameCMSIS-RTOS API提供的互斥鎖管理API如下:
API | 描述 |
---|---|
osMutexCreate | 創(chuàng)建一個(gè)互斥鎖 |
osMutexWait | 等待獲取互斥鎖 |
osMutexRelease | 釋放互斥鎖 |
osMutexDelete | 刪除互斥鎖 |
osMutexCreate
osMutexIdosMutexCreate(constosMutexDef_t*mutex_def);
其中 osMutexId 被定義為k_mutex_t指針類型:
typedefk_mutex_t*osMutexId;
osMutexWait
osStatusosMutexWait(osMutexIdmutex_id,uint32_tmillisec);
返回值:osStatus 。
如果需要阻塞延時(shí),參數(shù)應(yīng)該設(shè)置為CMSIS-RTOS API提供的宏定義 osWaitForever :
#defineosWaitForever0xFFFFFFFF///
osMutexRelease
osStatusosMutexRelease(osMutexIdmutex_id);
返回值:osStatus。
osMutexDelete
osStatusosMutexDelete(osMutexIdmutex_id);
返回值:osStatus。
2.7. 靜態(tài)內(nèi)存池管理
CMSIS-RTOS API提供的存儲(chǔ)靜態(tài)內(nèi)存池參數(shù)的結(jié)構(gòu)體如下:
typedefstructos_pool_def{
uint32_tpool_sz;///CMSIS-RTOS API提供的定義一個(gè)互斥鎖的宏定義如下:
#defineosPoolDef(name,no,type)
k_mmblk_pool_tmmblk_pool_handler_##name; uint8_tmmblk_pool_buf_##name[(no)*sizeof(type)]; constosPoolDef_tos_pool_def_##name= {(no),sizeof(type),(&((mmblk_pool_buf_##name)[0])),(&(mmblk_pool_handler_##name))}CMSIS-RTOS API定義的獲取互斥鎖參數(shù)結(jié)構(gòu)體的宏如下:
#defineosPool(name)
&os_pool_def_##nameCMSIS-RTOS API提供的互斥鎖管理API如下:
API | 描述 |
---|---|
osPoolCreate | 創(chuàng)建一塊固定大小的靜態(tài)內(nèi)存池 |
osPoolAlloc | 申請分配內(nèi)存 |
osPoolCAlloc | 申請分配一塊內(nèi)存并全部初始化為0 |
osPoolFree | 申請回收內(nèi)存 |
osPoolCreate
osPoolIdosPoolCreate(constosPoolDef_t*pool_def);
其中 osPoolId 被定義為 k_mmblk_pool_t 指針類型:
typedefk_mmblk_pool_t*osPoolId;
osPoolAlloc
void*osPoolAlloc(osPoolIdpool_id);
osPoolCAlloc
void*osPoolCAlloc(osPoolIdpool_id);
osPoolFree
osStatusosPoolFree(osPoolIdpool_id,void*block);
返回值:osStatus。
2.8. 消息隊(duì)列管理
CMSIS-RTOS API提供的存儲(chǔ)消息隊(duì)列參數(shù)的結(jié)構(gòu)體如下:
typedefstructos_messageQ_def{
uint32_tqueue_sz;///CMSIS-RTOS API提供的定義一個(gè)消息隊(duì)列的宏定義如下:
#defineosMessageQDef(name,queue_sz,type)
k_msg_q_tmsg_q_handler_##name; constosMessageQDef_tos_messageQ_def_##name= {(queue_sz),sizeof(type),NULL,(&(msg_q_handler_##name))}CMSIS-RTOS API定義的獲取消息隊(duì)列參數(shù)結(jié)構(gòu)體的宏如下:
#defineosMessageQ(name)
&os_messageQ_def_##nameCMSIS-RTOS API提供的消息隊(duì)列管理API如下:
API | 描述 |
---|---|
osMessageCreate | 初始化一個(gè)消息隊(duì)列 |
osMessagePut | 向消息隊(duì)列中加入數(shù)據(jù) |
osMessageGet | 從消息隊(duì)列中取出數(shù)據(jù) |
osMessageCreate
osMessageQIdosMessageCreate(constosMessageQDef_t*queue_def,osThreadIdthread_id);
其中 osMessageQId 被定義為 k_msg_q_t 指針類型:
typedefk_msg_q_t*osMessageQId;
osMessagePut
osStatusosMessagePut(osMessageQIdqueue_id,uint32_tinfo,uint32_tmillisec);
返回值:osStatus 。
?
因?yàn)門encentOS-tiny中消息隊(duì)列實(shí)現(xiàn)機(jī)制的不同,此API中的 millisec 參數(shù)未用到。
?
osMessageGet
osEventosMessageGet(osMessageQIdqueue_id,uint32_tmillisec);
返回值:osEvent ,其中包含了事件信息和錯(cuò)誤碼,以及消息隊(duì)列收到的值。
如果需要阻塞延時(shí),參數(shù)應(yīng)該設(shè)置為CMSIS-RTOS API提供的宏定義 osWaitForever :
#defineosWaitForever0xFFFFFFFF///
3. 使用示例
3.1. 任務(wù)創(chuàng)建示例
#include
voidtask1_entry(void*arg) { while(1) { printf("task1isrunning... "); osDelay(1000); } } osThreadDef(task1_entry,osPriorityNormal,1,512); voidtask2_entry(void*arg) { while(1) { printf("task2isrunning... "); osDelay(1000); } } osThreadDef(task2_entry,osPriorityNormal,1,512); voidapplication_entry(void*arg) { osThreadCreate(osThread(task1_entry),NULL); osThreadCreate(osThread(task2_entry),NULL); return; }
任務(wù)運(yùn)行結(jié)果如下:
task1isrunning... task2isrunning... task1isrunning... task2isrunning... task1isrunning... task2isrunning...
3.2. 軟件定時(shí)器使用示例
#includevoidtimer1_cb(void*arg) { printf("timer1istimeout! "); } voidtimer2_cb(void*arg) { printf("timer2istimeout! "); } osTimerDef(timer1,timer1_cb); osTimerDef(timer2,timer2_cb); voidapplication_entry(void*arg) { osTimerIdtimer1; osTimerIdtimer2; timer1=osTimerCreate(osTimer(timer1),osTimerOnce,NULL); timer2=osTimerCreate(osTimer(timer2),osTimerPeriodic,NULL); osTimerStart(timer1,5000); osTimerStart(timer2,1000); return; }
運(yùn)行結(jié)果如下:
timer2istimeout! timer2istimeout! timer2istimeout! timer2istimeout! timer1istimeout! timer2istimeout! timer2istimeout! timer2istimeout! timer2istimeout!
3.3. 信號(hào)量使用示例
#includeosSemaphoreIdsync_sem_id; osSemaphoreDef(sync_sem); voidtask1_entry(void*arg) { while(1) { printf("task1iswaitingsemforever... "); osSemaphoreWait(sync_sem_id,osWaitForever); printf("task1getsem! "); } } osThreadDef(task1_entry,osPriorityNormal,1,512); voidtask2_entry(void*arg) { while(1) { printf("task2willreleaseasem... "); osSemaphoreRelease(sync_sem_id); osDelay(1000); } } osThreadDef(task2_entry,osPriorityNormal,1,512); voidapplication_entry(void*arg) { sync_sem_id=osSemaphoreCreate(osSemaphore(sync_sem),0); osThreadCreate(osThread(task1_entry),NULL); osThreadCreate(osThread(task2_entry),NULL); return; }
運(yùn)行結(jié)果為:
task1iswaitingsemforever... task1getsem! task1iswaitingsemforever... task2willreleaseasem... task1getsem! task1iswaitingsemforever... task2willreleaseasem... task1getsem! task1iswaitingsemforever... task2willreleaseasem... task1getsem! task1iswaitingsemforever... task2willreleaseasem... task1getsem! task1iswaitingsemforever...
3.4. 互斥鎖使用示例
#include
osMutexIdsync_mutex_id; osMutexDef(sync_mutex); voidtask1_entry(void*arg) { while(1) { osMutexWait(sync_mutex_id,osWaitForever); printf("task1getmutex,doingsth... "); HAL_Delay(1000);//死循環(huán)占用CPU printf("task1finishdosth! "); osMutexRelease(sync_mutex_id); osDelay(1000); } } osThreadDef(task1_entry,osPriorityHigh,1,512); voidtask2_entry(void*arg) { while(1) { osMutexWait(sync_mutex_id,osWaitForever); printf("task2getmutex,doingsth... "); HAL_Delay(2000);//死循環(huán)占用CPU printf("task2finishdosth! "); osMutexRelease(sync_mutex_id); osDelay(1000); } } osThreadDef(task2_entry,osPriorityNormal,1,512); voidapplication_entry(void*arg) { sync_mutex_id=osMutexCreate(osMutex(sync_mutex)); osThreadCreate(osThread(task1_entry),NULL); osThreadCreate(osThread(task2_entry),NULL); return; }
運(yùn)行結(jié)果為:
task1getmutex,doingsth... task1finishdosth! task2getmutex,doingsth... task2finishdosth! task1getmutex,doingsth... task1finishdosth! task1getmutex,doingsth... task1finishdosth! task2getmutex,doingsth...
3.5. 動(dòng)態(tài)內(nèi)存使用示例
#includetypedefstructblk_st{ intid; char*payload; }blk_t; #defineMMBLK_BLK_NUM10 osPoolDef(MemPool,MMBLK_BLK_NUM,blk_t); osPoolIdmem_pool_id; voidtask1_entry(void*arg) { blk_t*ptr=NULL; osStatuserr; /*打印出一個(gè)塊的大小*/ printf("blocksizeis%dbytes ",sizeof(blk_t)); /*申請一個(gè)塊*/ ptr=osPoolAlloc(mem_pool_id); if(ptr==NULL){ printf("ammblkallocfail "); return; } else{ printf("ammblkallocsuccess "); } /*使用該塊*/ ptr->id=1; ptr->payload="hello"; printf("mmblkid:%dpayload:%s ",ptr->id,ptr->payload); /*使用完畢之后釋放*/ err=osPoolFree(mem_pool_id,ptr); if(err!=osOK){ printf("ammblkfreefail,err=%d ",err); return; } else{ printf("ammblkfreesuccess "); } while(1){ tos_task_delay(1000); } } #defineSTK_SIZE_TASK11024 osThreadDef(task1_entry,osPriorityNormal,1,STK_SIZE_TASK1); voidapplication_entry(void*arg) { //初始化靜態(tài)內(nèi)存池 mem_pool_id=osPoolCreate(osPool(MemPool)); if(mem_pool_id==NULL){ printf("mmblkpoolcreatefail "); return; } else{ printf("mmblkpoolcreatesuccess "); } //創(chuàng)建任務(wù) osThreadCreate(osThread(task1_entry),NULL); return; }
運(yùn)行結(jié)果為:
mmblkpoolcreatesuccess blocksizeis8bytes ammblkallocsuccess mmblkid:1payload:hello ammblkfreesuccess
3.6. 消息隊(duì)列使用示例
#include#defineSTK_SIZE_TASK_RECEIVER512 #defineSTK_SIZE_TASK_SENDER512 #defineMESSAGE_MAX10 osMessageQIdmsg_q_id; osMessageQDef(msg_q,MESSAGE_MAX,uint32_t); voidtask_receiver_entry(void*arg) { osEventevent; osStatusret; uint32_tvalue; while(1) { event=osMessageGet(msg_q_id,osWaitForever); ret=event.status; if(ret==osOK) { value=event.value.v; printf("receiver:msgincoming[%s] ",(char*)value); } } } osThreadDef(task_receiver_entry,osPriorityNormal,1,STK_SIZE_TASK_RECEIVER); voidtask_sender_entry(void*arg) { char*msg_prio_0="msg0"; char*msg_prio_1="msg1"; char*msg_prio_2="msg2"; printf("sender:postamessgae:[%s] ",msg_prio_2); osMessagePut(msg_q_id,(uint32_t)msg_prio_2,0); printf("sender:postamessgae:[%s] ",msg_prio_1); osMessagePut(msg_q_id,(uint32_t)msg_prio_1,0); printf("sender:postamessgae:[%s] ",msg_prio_0); osMessagePut(msg_q_id,(uint32_t)msg_prio_0,0); } osThreadDef(task_sender_entry,osPriorityNormal,1,STK_SIZE_TASK_SENDER); voidapplication_entry(void*arg) { msg_q_id=osMessageCreate(osMessageQ(msg_q),NULL); osThreadCreate(osThread(task_receiver_entry),NULL); osThreadCreate(osThread(task_sender_entry),NULL); return; }
運(yùn)行結(jié)果為:
sender:postamessgae:[msg2] sender:postamessgae:[msg1] sender:postamessgae:[msg0] receiver:msgincoming[msg2] receiver:msgincoming[msg1] receiver:msgincoming[msg0]
-
內(nèi)核
+關(guān)注
關(guān)注
3文章
1372瀏覽量
40291 -
API
+關(guān)注
關(guān)注
2文章
1501瀏覽量
62025 -
CMSIS
+關(guān)注
關(guān)注
0文章
40瀏覽量
11907
原文標(biāo)題:CMSIS RTOS API,內(nèi)核通用API接口
文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
評(píng)論