1. 一般信號量 共享資源 同時訪問
定義 : OS_SEM MY_SEM
創建 :OSSemCreate( (OS_SEM *) &MY_SEM,
(CPU_CHAR*) "MY_SEM",
(OS_SEM_CTR)1, // 重要 創建1個信號量 0 的話必須先發送一個信號量 才能請求
(OS_ERR* )&err);
使用 :OSSemPend("信號量地址",“超時tick 默認是5ms的倍數”,OS_OPT_PEND_BLOCKING (沒請求到信號量任務掛起),0(時間戳),&err)
OS_OPT_PEND_NON_BLOCKING (沒請求到信號量任務不掛起)
OS_OPT_PEND_BLOCKING (沒請求到信號量任務掛起)
釋放信號量 OSSemPost (&MY_SEM,OS_OPT_POST_1,&err); //發送信號量
* OS_OPT_POST_1 POST and ready only the highest priority task waiting on semaphore (if tasks are waiting). 僅等待的最高級別的一個任務
* OS_OPT_POST_ALL POST to ALL tasks that are waiting on the semaphore 所有等待該信號量的任務
* OS_OPT_POST_NO_SCHED Do not call the scheduler 不引起任務調度
* Note(s): 1) OS_OPT_POST_NO_SCHED can be added with one of the other options.
2,任務同步信號量
創建 :OSSemCreate( (OS_SEM *) &MY_SEM,
(CPU_CHAR*) "MY_SEM",
(OS_SEM_CTR)0, // 重要
(OS_ERR* )&err);
發送 信號量 :-----》OSSemPost(&SYNC_SEM,OS_OPT_POST_1,&err); //發送信號量
等待的任務 --------》OSSemPend(&SYNC_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //請求信號量
接收到信號量 開始工作 創建的 默認信號量是0 所以一般 工作信號量 超時都是 0 就是 沒有發送信號量就阻塞 在這里
3 互斥信號量
解決 優先級反轉 的問題 (只能 發一個信號量) 多個信號 要創建多個 對象 (低優先級在執行時候被打斷 ,在其他需要使用信號量的 高優先級的任務在使用信號量時候會自動提升 低優先級的任務 執行完 釋放信號量,高優先級的會繼續執行)
OS_MUTEX TEST_MUTEX; //定義一個互斥信號量
//創建一個互斥信號量
OSMutexCreate((OS_MUTEX* )&TEST_MUTEX,
(CPU_CHAR* )"TEST_MUTEX",
(OS_ERR* )&err);
使用 //請求互斥信號量
OSMutexPend (&TEST_MUTEX,0,OS_OPT_PEND_BLOCKING,0,&err); //超時是0 沒請求到會一直等待
{ 任務1 。。。}
//釋放互斥信號量
OSMutexPost(&TEST_MUTEX,OS_OPT_POST_NONE,&err);
4.任務內嵌 信號量
task 創建的任務自帶的 不用創建 直接 發送和請求 就行
當前任務只能 請求自己的信號量 ,可以給其他任務發送信號量
//任務2的任務函數
void task2_task(void *p_arg)
{
u8 num;
OS_ERR err;
while(1)
{
OSTaskSemPend(0,OS_OPT_PEND_BLOCKING,0,&err); //請求任務內建的信號量 只能是自己的
num++;
LCD_ShowxNum(150,111,Task2_TaskTCB.SemCtr,3,16,0); //顯示任務內建信號量值
LCD_Fill(6,131,233,313,lcd_discolor[num%14]); //刷屏
LED1=!LED1;
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延時1s
}
}
//任務1的任務函數 void task1_task(void *p_arg) { u8 key; u8 num; OS_ERR err; while(1) { key = KEY_Scan(0); //掃描按鍵 if(key==WKUP_PRES) { OSTaskSemPost(&Task2_TaskTCB,OS_OPT_POST_NONE,&err);//使用系統內建信號量向任務task2發送信號量 LCD_ShowxNum(150,111,Task2_TaskTCB.SemCtr,3,16,0); //顯示信號量值 } num++; if(num==50) { num=0; LED0=!LED0; } OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err); //延時10ms } }