KeilMDK環境 stm32f10x快速移值FreeRTOSv9.0

stm32f10x快速移值FreeRTOS

FreeRTOS由於其短小精悍,開源免費被廣泛的應用。在使用FreeRTOS之前不可避免的就是移值。在這裏分享一個快速簡單、親測可用的freertos移值教程。其他類型的編譯器和單片機也可做爲參考。

準備工作

在進行FreeRTOS移值之前首先得先拿到FreeRTOS源碼,並分析它得目錄結構。
源碼可以在FreeRTOS官網獲得,下載下來爲一個可執行文件,雙擊解壓可獲得源碼。
根目錄我們將要使用的是FreeRTOS裏的文件,另一個FreeRTOS-Plus不必管它,它包含了FreeRTOS的其他一下可選和擴展功能。
在這裏插入圖片描述
Demo文件夾包含了官方提供的大量的基於不同硬件和編譯器的例程,有很大的參考價值。在移值程序的時候可以用到。
Source裏包含了移值所必須的文件如下圖:
在這裏插入圖片描述
紅框標出的是操作系統內核正常工作所需要的必要文件。其他的爲一些可選功能:事件組,協程,軟件定時器等。
include爲頭文件需要在工程中包含該文件夾
protable文件夾中的文件不是所有是必須的,只需要選擇對應處理器和平臺的文件夾中的文件使用即可。
在這裏插入圖片描述
框選出來的爲必須選的,MemMang中的heap_x.c是不同的內存管理方案,任意選擇一種即可,這裏選擇heap_4.c,關於他們之間的差異可以自行百度。
由於在Keil文件夾下See-also-the-RVDS-directory.txt文件明確說了去RVDS找,於是乎還需要RVDS文件夾中的 \RVDS\ARM_CM3文件夾中的源代碼。

最後需要準備的是例程裏的FreeRTOSConfig.h源碼,這個頭文件已經將大部分配置工作給做好了,大大簡化了移值。可以在 \FreeRTOS\Demo\CORTEX_STM32F103_Keil找到。
在這裏插入圖片描述
到這裏需要的文件就準備齊了。將他們複製到已有的工程目錄下,然後添加進工程,幷包含頭文件所在位置。如圖所示:
在這裏插入圖片描述
添加源文件到工程裏面。並索引頭文件所在位置。
在這裏插入圖片描述

移值

添加完程序,還需要少量修改。

將一些中斷向量交給操作系統內核管理

FreeRTOSConfig.h中添加宏定義:

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

在這裏插入圖片描述爲了避免重定義,我們將stm32f10x_it.h中的申明給註釋掉。
在這裏插入圖片描述然後進行編譯。

測試程序

#include "stm32f10x.h" 
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
//定義相關參數
#define START_TASK_PRIO		1
#define START_STK_SIZE 		128  
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);

#define LED0_TASK_PRIO		2
#define LED0_STK_SIZE 		50  
TaskHandle_t LED0Task_Handler;
void led0_task(void *pvParameters);

#define LED1_TASK_PRIO		3
#define LED1_STK_SIZE 		50  
TaskHandle_t LED1Task_Handler;
void led1_task(void *pvParameters);

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);    			
	uart_init(115200);				
	LED_Init();		  				
	
    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();      
}

void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();        //進入臨界區
    xTaskCreate((TaskFunction_t )led0_task,     	  //創建led0任務
                (const char*    )"led0_task",   	
                (uint16_t       )LED0_STK_SIZE, 
                (void*          )NULL,				
                (UBaseType_t    )LED0_TASK_PRIO,	
                (TaskHandle_t*  )&LED0Task_Handler);   

    xTaskCreate((TaskFunction_t )led1_task,     //創建led1任務
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler);         
    vTaskDelete(StartTask_Handler);//刪除開始任務
    taskEXIT_CRITICAL();       //推出臨界區
}

void led0_task(void *pvParameters)
{
    while(1)
    {
        LED0=~LED0;
        vTaskDelay(500);
    }
}   

void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
    }
}

一共創建三個任務,在開始任務中創建了led0閃爍和led1閃爍任務。然後在主函數中創建開始任務,並刪除開始任務,最後啓動任務調度。

總結

統過宏定義的方法,可以免去在啓動文件中進行修改,簡單快速。提高開發效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章