STM32_freeRTOS_STM32CubeIDE開發紀錄#1
[TOC]
前言
最近要做的應用對時序比較嚴格,所以就來學習freeRTOS的使用方法了
freeRTOS是一個RTOS,提供了任務排程、同步機制、記憶體管理
詳細的各位在去google,這邊主要紀錄開發流程
本文實現一個雙線程LED Blink 系統
未來會在紀錄透過I2C與光感IC通訊的系統
如果文中措辭有些錯誤的話,歡迎糾正,因為我也是菜鳥...
STM32CubeIDE配置流程
基本配置可以去看我之前紀錄的文章-STM32CubeIDE開發流程
這邊補充freeRTOS的配置
開啟freeRTOS:
調整TOTAL_HEAP_SIZE:
因為宣告了四個任務導致Heap size超標,可以調整TOTAL_HEAP_SIZE
freeRTOS宣告任務:
產生程式碼:
STM32 LED 腳位配置
STM32 GPIO A6 A7 腳位配置:
配置A6、A7腳位
pull down是因為LED正極直接接STM32 Pin腳
freeRTOS task建立
在freertos.c裡面,可以看到此函數
而此函數在Main函數裡被呼叫
因此在呼叫此函數過後便會產生任務
從以下範例可看出產生5個任務
從語意上來看好像產生5個thread
不過就我的理解來說
像是一個thread,但是結合了多工處理與任務排程的機制
任務的優先級可以在宣告任務的時候賦予
/**
* @brief FreeRTOS initialization
* @param None
* @retval None
*/
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* creation of LEDA6 */
LEDA6Handle = osThreadNew(StartTask02, NULL, &LEDA6_attributes);
/* creation of LEDA7 */
LEDA7Handle = osThreadNew(StartTask03, NULL, &LEDA7_attributes);
/* creation of IWDG_refresh */
IWDG_refreshHandle = osThreadNew(StartTask04, NULL, &IWDG_refresh_attributes);
/* creation of getPSdata */
getPSdataHandle = osThreadNew(StartTask05, NULL, &getPSdata_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
}
時序監控
根據以下任務程式
LEDA6週期2 sec,LEDA7週期1 sec
Duty 都是0.5
/* USER CODE BEGIN Header_StartTask02 */
/**
* @brief Function implementing the LEDA6 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask02 */
void StartTask02(void *argument)
{
/* USER CODE BEGIN StartTask02 */
/* Infinite loop */
for(;;)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6, GPIO_PIN_SET);
osDelay(1000);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6, GPIO_PIN_RESET);
osDelay(1000);
}
/* USER CODE END StartTask02 */
}
/* USER CODE BEGIN Header_StartTask03 */
/**
* @brief Function implementing the LEDA7 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask03 */
void StartTask03(void *argument)
{
/* USER CODE BEGIN StartTask03 */
/* Infinite loop */
for(;;)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7, GPIO_PIN_SET);
osDelay(500);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7, GPIO_PIN_RESET);
osDelay(500);
}
/* USER CODE END StartTask03 */
}
實際使用示波器觀察電位
LED 任務時序:
驗證結果正確!
結語
---
這次實驗建構了一個即時的LED循序點燈效果
這樣的實驗結果也許可以用polling的方式實現
但是使用freeRTOS後,可以將任務獨立開來
時序的掌控也更加準確
目前網路上有很多資源說明freeRTOS的機制
但是CMSIS v2的API對我來說還很陌生
若是對於文章內容有任何高見歡迎留言