1)實驗平臺:正點原子APM32E103最小系統板
2)平臺購買地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套實驗源碼+手冊+視頻下載地址: http://www.openedv.com/docs/boards/xiaoxitongban
第五十五章 FreeRTOS移植實驗
前面章節中的實驗都是在裸機環境下實現,本章將介紹FreeRTOS的簡單使用,對RTOS感興趣的讀者,可以參考正點原子推出的FreeRTOS或μC/OS-III的全套教程資料,包含教學視頻、開發指南并配套有例程源碼。通過本章的學習,讀者將學習到FreeRTOS的簡單應用。
本章分為如下幾個小節:
55.1 硬件設計
55.2 程序設計
55.3 下載驗證
55.1 硬件設計
55.1.1 例程功能
- LED0由LED0任務控制80毫秒亮,920毫秒滅
- LED1由LED1任務控制300毫秒亮,300毫秒滅
55.1.2 硬件資源 - LED
LED0 - PB5
LED1 - PE5
55.1.3 原理圖
本章實驗使用的FreeRTOS為軟件庫,因此沒有對應的連接原理圖。
55.2 程序設計
55.2.1 FreeRTOS的移植
FreeRTOS的源碼可參考正點原子推出的《FreeRTOS開發指南》或相關的配套教學視頻至FreeRTOS的官網下載,也可在A盤6,軟件資料FreeRTOS學習資料中找到。
FreeRTOS的移植請讀者參考正點原子推出的《FreeRTOS開發指南》或相關的配套教學視頻,在上述資料中,對FreeRTOS的移植和使用都做了非常詳細地介紹,是入門FreeRTOS的一個非常好的選擇。
55.2.2 實驗應用代碼
本章實驗的應用代碼,如下所示:
/* START_TASK任務配置* 包括: 任務句柄 任務優先級 堆棧大小 創建任務*/
#define START_TASK_PRIO 1 /* 任務優先級 */
#define START_STK_SIZE 128 /* 任務堆棧大小 */
TaskHandle_t StartTask_Handler; /* 任務句柄 */
void start_task(void *pvParameters); /* 任務函數 *//* LED0任務配置* 包括: 任務句柄 任務優先級 堆棧大小 創建任務*/
#define LED0_PRIO 2 /* 任務優先級 */
#define LED0_STK_SIZE 128 /* 任務堆棧大小 */
TaskHandle_t LED0Task_Handler; /* 任務句柄 */
void led0_task(void *pvParameters); /* 任務函數 *//* LED1任務配置* 包括: 任務句柄 任務優先級 堆棧大小 創建任務*/
#define LED1_PRIO 2 /* 任務優先級 */
#define LED1_STK_SIZE 128 /* 任務堆棧大小 */
TaskHandle_t LED1Task_Handler; /* 任務句柄 */
void led1_task(void *pvParameters); /* 任務函數 */int main(void)
{NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_4); /* 設置中斷優先級分組為組4 */sys_apm32_clock_init(15); /* 配置系統時鐘 */delay_init(120); /* 初始化延時功能 */usart_init(115200); /* 初始化串口 */led_init(); /* 初始化LED */xTaskCreate((TaskFunction_t )start_task, /* 任務函數 */(const char* )"start_task", /* 任務名稱 */(uint16_t )START_STK_SIZE, /* 任務堆棧大小 */(void* )NULL, /* 傳入給任務函數的參數 */(UBaseType_t )START_TASK_PRIO, /* 任務優先級 */(TaskHandle_t* )&StartTask_Handler); /* 任務句柄 */vTaskStartScheduler();
}
從上面的代碼中可以看出,在完成必要的初始化后,便創建了“start_task”任務,隨后便開始了任務調度,“start_task”任務的入口函數為函數start_task(),如下所示:
/*** @brief start_task* @param pvParameters: 傳入參數(未用到)* @retval 無*/
void start_task(void *pvParameters)
{taskENTER_CRITICAL(); /* 進入臨界區 *//* 創建LED0任務 */xTaskCreate((TaskFunction_t )led0_task,(const char* )"led0_task",(uint16_t )LED0_STK_SIZE,(void* )NULL,(UBaseType_t )LED0_PRIO,(TaskHandle_t* )&LED0Task_Handler);/* 創建LED1任務 */xTaskCreate((TaskFunction_t )led1_task,(const char* )"led1_task",(uint16_t )LED1_STK_SIZE,(void* )NULL,(UBaseType_t )LED1_PRIO,(TaskHandle_t* )&LED1Task_Handler);vTaskDelete(StartTask_Handler); /* 刪除開始任務 */taskEXIT_CRITICAL(); /* 退出臨界區 */
}
從上面的代碼中可以看出,“start_task”任務主要用于創建“led0_task”和“led1_task”任務,這兩個任務的入口函數,如下所示:
/*** @brief LED0任務* @param pvParameters: 傳入參數(未用到)* @retval 無*/
void led0_task(void *pvParameters)
{while(1){LED0(0);vTaskDelay(80);LED0(1);vTaskDelay(920);}
}/*** @brief LED1任務* @param pvParameters: 傳入參數(未用到)* @retval 無*/
void led1_task(void *pvParameters)
{while(1){LED1(0);vTaskDelay(300);LED1(1);vTaskDelay(300);}
}
可以看到,兩個任務分別控制開發板板載的兩個LED閃爍,但其閃爍的頻率和亮滅時間都不相同,因此因該能看到開發板板載的兩個LED以不同的頻率和不同的亮滅時間進行閃爍。
55.3 下載驗證
在完成編譯和燒錄操作后,可以看到開發板板載的兩個LED以不用的頻率和不同的亮滅時間閃爍著,其中LED0在一個閃爍周期內的亮滅時間約分別為80毫秒和920毫秒,LED1在一個閃爍周期內的亮滅時間約分別為300毫秒和300毫秒。