UCOSIII 信號量 的使用和區別


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
    }
}

 

 

 

 

 

 

 

 

                           

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM