1. 程式人生 > >STM32+cubeMX+FreeRTOS學習(1)

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個任務在不停的切換。