
素材來源:技術讓夢想更偉大
作者:李肖遙
FreeRTOS 是一個可裁剪、可剝奪型的多任務內核,十分好用,而且沒有任務數限制,在此之前分析過很多了,簡單來說,FreeRTOS實時系統能夠創建多個獨立的任務,并且任務之間互不干擾,為了這一點的實現,每個任務都應該有自己的堆棧空間。當任務進行切換,執行環境則保存到該任務的堆棧中,所以,當一段時間后切換回該任務,它能夠精確地回復上次工作時的狀態。
之前也匯總了一些教程,參考精選匯總 | freertos從基礎到高級篇系列
FreeRTOS 提供了實時操作系統所需的所有功能,包括資源管理、同步、任務通信等,本篇主要說一下任務通信,任務創建之后并不是一起運行的,而是通過優先級順序進行任務的調用來實現的。
輪子也造好了,很多我們可以直接拿來用,ARM Cortex 微控制器軟件接口標準是cmsis,且是與供應商無關的硬件抽象層,CMSIS-RTOS是實時操作系統的通用API,簡單來說就是將Freertos、Rtthread等操作系統再進行一次封裝,形成通用的API函數,目的是使移植更方便。這里我們選用接口是CMSIS_V2,之前也講到過stm32CubeIDE中CMSIS_V1和CMSIS_V2選項的區別。

首先創建兩個任務myTask01和myTask02,如下圖所示:

創建2個事件myEvent01,myEvent02,如下圖所示:

拉下來也可以配置以下信息,在此我們默認配置計數信號量、分配方式、控制塊名稱等配置信息。
生成代碼之后任務和事件如下代碼:
/*?Definitions?for?myTask01?*/
osThreadId_t?myTask01Handle;
const?osThreadAttr_t?myTask01_attributes?=?{
??.name?=?"myTask01",
??.stack_size?=?128?*?4,
??.priority?=?(osPriority_t)?osPriorityLow,
};
...
/*?Definitions?for?myEvent02?*/
osEventFlagsId_t?myEvent02Handle;
const?osEventFlagsAttr_t?myEvent02_attributes?=?{
??.name?=?"myEvent02"
};
這個是創建任務的句柄,代碼如下:
??/*?creation?of?myTask01?*/
??myTask01Handle?=?osThreadNew(StartTask01,?NULL,?&myTask01_attributes);
??/*?creation?of?myTask02?*/
??myTask02Handle?=?osThreadNew(StartTask02,?NULL,?&myTask02_attributes);
我們改寫代碼,實現task2往task發送信號,實現簡單的任務通信,代碼如下。
/*?USER?CODE?END?Header_StartTask01?*/
void?StartTask01(void?*argument)
{
????/*?USER?CODE?BEGIN?StartTask01?*/
????/*?Infinite?loop?*/
????osStatus_t?os_Status;
???while(1)
???{
????os_Status?=?osEventFlagsWait(myTask02Handle,???/*?事件標志組ID?*/
????????????COMM2_EVENT,???????/*?等待事件標志位0與事件標志位1?*/
????????????osFlagsWaitAny,????/*?邏輯或?*/
???????????????osWaitForever??????/*?一直等待?*/
????????????);
????if(os_Status?==?COMM1_EVENT)
????{
???????printf("startTask02?is?running.\r\n");
????}
???}
????/*?USER?CODE?END?StartTask01?*/
}
/*?USER?CODE?BEGIN?Header_StartTask02?*/
osEventFlagsWait函數的具體實現以及定義如下圖所示:

osEventFlagsSet就是往某個任務的句柄發送一個信號,實現如下
/*?USER?CODE?END?Header_StartTask02?*/
void?StartTask02(void?*argument)
{
?/*?USER?CODE?BEGIN?StartTask02?*/
?/*?Infinite?loop?*/
?for(;;)
?{
???osEventFlagsSet(myEvent01Handle,?COMM1_EVENT);
???osDelay(1);
?}
?/*?USER?CODE?END?StartTask02?*/
}最后就可以實現多個任務間的通信了。
???????????????? ?END ????????????????
關注我的微信公眾號,回復“加群”按規則加入技術交流群。
點擊“閱讀原文”查看更多分享,歡迎點分享、收藏、點贊、在看。