日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FreeRTOS任务通知

發(fā)布時(shí)間:2023/12/1 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FreeRTOS任务通知 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從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è)

  • xTaskNotify
  • BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
    • TaskHandle_t xTaskToNotify: 任務(wù)句柄,指定任務(wù)通知是發(fā)送給那個(gè)任務(wù)的
    • uint32_t ulValue:任務(wù)通知值
    • eNotifyAction eAction:任務(wù)通知更新的方法,是一個(gè)枚舉類型
    typedef enum {eNoAction = 0, /* Notify the task without updating its notify value. */eSetBits, /* Set bits in the task's notification value.更新指定的bit */eIncrement, /* Increment the task's notification value.通知值加1 */eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. 覆寫的方式更新通知值*/eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task.不覆寫通知值 */ } eNotifyAction;
  • xTaskNotifyFromISR
  • BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
    • BaseType_t *pxHigherPriorityTaskWoken:退出此函數(shù)是否要進(jìn)行任務(wù)切換
  • xTaskNotifyGive
  • BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
    • TaskHandle_t xTaskToNotify:指定通知是發(fā)送給那個(gè)任務(wù)的
  • vTaskNotifyGiveFromISR
  • void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
  • xTaskNotifyAndQuery
  • xTaskNotifyAndQuery( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t*pulPreviousNotificationValue);
    • TaskHandle_t xTaskToNotify:任務(wù)句柄,指定任務(wù)通知是發(fā)送給那個(gè)任務(wù)的
    • uint32_t ulValue:任務(wù)通知值
    • eNotifyAction eAction:任務(wù)通知更新方法
    • uint32_t* pulPreviousNotificationValue:用來保存更新前的任務(wù)通知值
  • xTaskNotifyAndQueryFromISR
  • xTaskNotifyAndQueryFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t*pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken);

    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ù)
    uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait )
    • 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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。