FreeRTOS任务通知
從v8.2.0版本開始,FreeRTOS新增了任務(wù)通知這個(gè)功能,可以使用任務(wù)通知來代替信號量、消息隊(duì)列、事件標(biāo)志組等這些東西,使用任務(wù)通知的話效率會更高。
任務(wù)通知在FreeRTOS是一個(gè)可選的選項(xiàng),要使用任務(wù)通知的話就需要將宏configUSE_TASK_NOTIFICATIONS定義為1 。FreeRTOS的每個(gè)任務(wù)都有一個(gè)32位的通知值,任務(wù)控制塊中的成員變量ulNotifiedValue就是這個(gè)通知值。任務(wù)通知是一個(gè)事件,可以提高速度,減少RAM的使用,但是任務(wù)通知也是有限的,FreeRTOS的任務(wù)通知只能有一個(gè)接收任務(wù),接收任務(wù)可以因?yàn)槿蝿?wù)通知而進(jìn)入阻塞態(tài),但是發(fā)送任務(wù)不會因?yàn)槿蝿?wù)通知發(fā)送失敗而阻塞。
0x01 發(fā)送任務(wù)通知
任務(wù)通知函數(shù)有6個(gè)
- TaskHandle_t xTaskToNotify: 任務(wù)句柄,指定任務(wù)通知是發(fā)送給那個(gè)任務(wù)的
- uint32_t ulValue:任務(wù)通知值
- eNotifyAction eAction:任務(wù)通知更新的方法,是一個(gè)枚舉類型
- BaseType_t *pxHigherPriorityTaskWoken:退出此函數(shù)是否要進(jìn)行任務(wù)切換
- TaskHandle_t xTaskToNotify:指定通知是發(fā)送給那個(gè)任務(wù)的
- TaskHandle_t xTaskToNotify:任務(wù)句柄,指定任務(wù)通知是發(fā)送給那個(gè)任務(wù)的
- uint32_t ulValue:任務(wù)通知值
- eNotifyAction eAction:任務(wù)通知更新方法
- uint32_t* pulPreviousNotificationValue:用來保存更新前的任務(wù)通知值
0x02 獲取任務(wù)通知
獲取任務(wù)通知的函數(shù)有兩個(gè)
- ulTaskNotifyTake():獲取任務(wù)通知,可以設(shè)置在退出此函數(shù)的時(shí)候?qū)⑷蝿?wù)通知值清理或者減1.當(dāng)任務(wù)通知用作二值信號量或者計(jì)數(shù)信號量的時(shí)候使用此函數(shù)來獲取信號量。
- xTaskNotifyWait():等待任務(wù)通知,比ulTaskNotifyTake更為強(qiáng)大,全功能版任務(wù)通知獲取函數(shù)
- BaseType_t xClearCountOnExit:為pdFALSE的話,在退出函數(shù)的時(shí)候,任務(wù)通知值減1,類似計(jì)數(shù)型信號量,當(dāng)為pdTRUE的話,在退出函數(shù)的時(shí)候任務(wù)通知清零,類似二值信號量
- TickType_t xTicksToWait:阻塞時(shí)間
返回值:任務(wù)通知值減少值或者清零之前的值
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait )- uint32_t ulBitsToClearOnEntry:當(dāng)沒有接收到任務(wù)通知的時(shí)候,將任務(wù)通知與此參數(shù)的取反值進(jìn)行按位與運(yùn)算,當(dāng)此參數(shù)為0xffffffff或者ULONG_MAX的時(shí)候就會將任務(wù)通知值清零
- uint32_t ulBitsToClearOnExit:如果接收到了任務(wù)通知,在做完相應(yīng)的處理退出函數(shù)之前將任務(wù)通知與此參數(shù)的取反值進(jìn)行按位與運(yùn)算,當(dāng)此參數(shù)為0xffffffff或者ULONG_MAX的時(shí)候就會將任務(wù)通知值清零
- uint32_t *pulNotificationValue:此參數(shù)來保存任務(wù)通知值
- TickType_t xTicksToWait :阻塞時(shí)間
返回值:
pdTRUE:獲取了任務(wù)通知
pdFALSE:任務(wù)通知獲取失敗
實(shí)驗(yàn) 任務(wù)通知模擬二值信號量
獲取任務(wù)通知值,如果獲取到的話,則進(jìn)行邏輯處理
//DataProcess_task函數(shù) void DataProcess_task(void *pvParameters) {u8 len=0;u8 CommandValue=COMMANDERR;u32 NotifyValue;u8 *CommandStr;POINT_COLOR=BLUE;while(1){NotifyValue=ulTaskNotifyTake(pdTRUE,portMAX_DELAY); //獲取任務(wù)通知if(NotifyValue==1) //清零之前的任務(wù)通知值為1,說明任務(wù)通知有效{len=USART_RX_STA&0x3fff; //得到此次接收到的數(shù)據(jù)長度CommandStr=mymalloc(SRAMIN,len+1); //申請內(nèi)存sprintf((char*)CommandStr,"%s",USART_RX_BUF);CommandStr[len]='\0'; //加上字符串結(jié)尾符號LowerToCap(CommandStr,len); //將字符串轉(zhuǎn)換為大寫 CommandValue=CommandProcess(CommandStr); //命令解析if(CommandValue!=COMMANDERR){LCD_Fill(10,90,210,110,WHITE); //清除顯示區(qū)域LCD_ShowString(10,90,200,16,16,CommandStr); //在LCD上顯示命令printf("命令為:%s\r\n",CommandStr);switch(CommandValue) //處理命令{case LED1ON: LED1=0;break;case LED1OFF:LED1=1;break;case BEEPON:BEEP=0;break;case BEEPOFF:BEEP=1;break;}}else{printf("無效的命令,請重新輸入!!\r\n");}USART_RX_STA=0;memset(USART_RX_BUF,0,USART_REC_LEN); //串口接收緩沖區(qū)清零myfree(SRAMIN,CommandStr); //釋放內(nèi)存}else {vTaskDelay(10); //延時(shí)10ms,也就是10個(gè)時(shí)鐘節(jié)拍 }} }接收到了數(shù)據(jù),發(fā)送任務(wù)通知,vTaskNotifyGiveFromISR的第一個(gè)參數(shù)是DataProcess_task任務(wù)的任務(wù)句柄DataProcess_Handler
//串口1中斷服務(wù)程序 void USART1_IRQHandler(void) { u32 timeout=0;u32 maxDelay=0x1FFFF;BaseType_t xHigherPriorityTaskWoken;HAL_UART_IRQHandler(&UART1_Handler); //調(diào)用HAL庫中斷處理公用函數(shù)timeout=0;while (HAL_UART_GetState(&UART1_Handler) != HAL_UART_STATE_READY)//等待就緒{timeout++;超時(shí)處理if(timeout>maxDelay) break; }timeout=0;while(HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次處理完成之后,重新開啟中斷并設(shè)置RxXferCount為1{timeout++; //超時(shí)處理if(timeout>maxDelay) break; }//發(fā)送任務(wù)通知if((USART_RX_STA&0x8000)&&(DataProcess_Handler!=NULL))//接收到數(shù)據(jù),并且接收任務(wù)通知的任務(wù)有效{vTaskNotifyGiveFromISR(DataProcess_Handler,&xHigherPriorityTaskWoken);//發(fā)送任務(wù)通知portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//如果需要的話進(jìn)行一次任務(wù)切換} }總結(jié)
以上是生活随笔為你收集整理的FreeRTOS任务通知的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 代理记账一般多少钱啊?
- 下一篇: The FreeRTOS Distrib