STM32+cubeMX+FreeRTOS學習(1)
背景:
最近專案要在STM32L152上移植FreeRTOS輕量級系統,本文將從FreeRTOS的入門知識講起,記錄FreeRTOS的一些基本知識點和學習心得。
硬體平臺:STM32L152 ,備註:PA12連線LED1,PA11連線LED2;
軟體平臺:keil v5和 cubeMx。
內容:
1.FreeRTOS簡介
FreeRTOS是一種輕量級實時作業系統。RTOS:Real Time OperatingSystem實時作業系統。FreeRTOS可拆分為Free + RTOS,前面Free代表一種作業系統型別的名稱,後面RTOS代表實時作業系統。
近幾年,FreeRTOS的排名在嵌入式作業系統的排名中還是比較高的,且有不斷上升趨勢。
2. cubeMX中FreeRTOS的生成及任務建立
首先,開啟CUBEMX軟體,點選NEW Project,選擇晶片STM32L152RC;
2,配置RCC時鐘
3,設定PA12和PA11為GPIO_OUTPUT;
4,使能FREERTOS;
5,設定時鐘樹,本例外部晶振8M,8倍頻,2分頻,得到32M;
6,配置FREERTOS,建立兩個任務;
7,生成基於Keil V5的程式碼。
8,新增LED點亮和熄滅程式;
編譯執行,可以看到LED1和LED2 分別以不同的頻率閃爍。
下面重點分析生成的程式碼:
下面分析MX_FREERTOS_Init()函式;
void MX_FREERTOS_Init(void)
{
osThreadDef(Task_LED1, Func_LED1, osPriorityNormal, 0, 128);//巨集定義,定義了一個名為os_thread_def_Task_LED1的osThreadDef_t型別結構體,並賦值給各個成員變數。
Task_LED0Handle = osThreadCreate(osThread(Task_LED1), NULL);//建立了LED1任務
osThreadDef(Task_LED2, Func_LED2, osPriorityNormal, 0, 128);//巨集定義,定義了一個名為os_thread_def_Task_LED2的osThreadDef_t型別結構體,並賦值給各個成員變數。
Task_LED1Handle = osThreadCreate(osThread(Task_LED2), NULL);//建立了LED2任務
}
go to definition of osThreadDef,該巨集定義如下
#define osThreadDef(name, thread, priority, instances, stacksz) \
const osThreadDef_t os_thread_def_##name = \
{ #name, (thread), (priority), (instances), (stacksz)}
#endif
上訴巨集定義中出現了##和# 符號,其中
##是一個連線符號,用於把引數連在一起;
#是“字串化”的意思。出現在巨集定義中的#是把跟在後面的引數轉換成一個字串。
例如:
#define paster( n ) printf( "token" #n" = %d\n ", token##n )
所以paster(9);就是相當於 printf("token 9 = %d\n",token9);
那麼osThreadDef(Task_LED1, Func_LED1, osPriorityNormal, 0, 128);等價於下面的定義
#defineosThreadDef(Task_LED1, Func_LED1, osPriorityNormal, 0, 128) \
const osThreadDef_t os_thread_def_Task_LED1 = { Task_LED1,Func_LED1,osPriorityNormal, 0, 128}
#endif
總結:
本例中的兩個任務函式Func_LED1和Func_LED2,他們實際佔用CPU的時間很少,在呼叫osDelay()函式之後,它們就進入阻塞狀態了,它們在等待“定時時間到”事件。在使用者任務都進入阻塞狀態時,執行的是空閒任務。空閒任務是啟動排程器時自動建立的。
在除錯過程中,嘗試把兩個任務函式的osDelay都改成500後,觀察現象是LED1和LED2同時同頻率的閃爍,但這和FreeRTOS中的某一任意時刻,只會有一個任務在執行,不會有同時兩個任務在執行的理論相悖。之後分析發現,在呼叫osDelay()函式之後,它們就進入阻塞狀態了,當500ms到時,LED1先切換至執行態,之後LED2切換至執行態,然後進入組態等待下一個500ms。LED1執行和切換到LED2這個時間非常短,以至於表面上看lED1和LED2同時執行,實際上依然是2個任務在不停的切換。