欢迎光临
我们一直在努力

【FreeRTOS初学者详细教程(一)】—在stm32标准库裸机程序上移植FreeRTOS

(一)FreeRTOS源码的下载

1. FreeRTOS官网下载

FreeRTOS官网:https://www.freertos.org/,但在官网只能下载最新V202406.04版,我们教程用的是经典且更稳定的V9.0.0版

https://www.freertos.org/https://www.freertos.org/

2. 代码托管网站下载

2.1直接跳转到网站:https://sourceforge.net/projects/freertos/files/FreeRTOS/

https://sourceforge.net/projects/freertos/files/FreeRTOS/https://sourceforge.net/projects/freertos/files/FreeRTOS/2.2 然后完成真人验证往下滑,找到V9.0.0版本点击

2.3 点击FreeRTOSv9.0.0.zip,自动即可开始下载,因是国外的网站下载过程较慢,耐心等待一下

(二) FreeRTOS系统移植

1.创建stm32裸机项目工程

1.1任意写一个stm32标准库程序,我这里使用的是最基础的stmf103c8t6的驱动LED闪烁程序

1.2在文件夹根目录下创建一个名为FreeRTOS的文件夹,用来存放FreeRTOS的移植文件

1.3在刚创建的FreeRTOS文件夹中,分别创建include,port,src文件夹,

  • include文件夹用来存放头文件
  • port文件夹用来存放移植平台的相关文件
  • src文件夹用来存放源码

2.解压移植FreeRTOS文件

2.1解压第一步下载的FreeRTOSv9.0.0,

2.2打开FreeRTOS——Source,复制里面的所有文件,粘贴到第一步创建的FreeRTOS文件夹中

点击替换目标中的文件

2.3把这7个.c文件全移动到src文件夹中

2.4打开portable选中MemMang与RVDS复制粘贴到第一步创建的port中,然后删掉portable即可

2.5打开port——MemMang,删除处heap_4.c外的所有文件

2.6去FreeRTOS——Demo——CORTEX_STM32F103_Keil文件夹,复制里面的FreerRTOSConfig.h文件到新建的stm32程序的User文件夹中,至此FreeRTOS文件移植完成

3.添加头文件和微调文件内容

3.1 接着开始添加头文件路径,打开keil软件点击魔术棒,进入C/C++,在Include Paths中添加文件路径,将.\\FreeRTOS\\port\\RVDS\\ARM_CM3、.\\FreeRTOS\\include的路径添加进来3.2将上面创建的文件夹添加到项目工程中,点击魔术棒旁边的三个格子的图标,选择新建组,我们分别新建FreeRTOS\\src、FreeRTOS_port三个组,将工程文件夹src中的所有.c文件添加到FreeRTOS_src中,将工程文件夹inc中的所有.h文件添加到FreeRTOS_inc中(不包括.readme),将工程文件夹port\\RVDS\\ARM_CM3中的文件port.c、portmacro.h与port\\MemMang中的heap_4.c添加到FreeRTOS\\port中

3.3打开项目工程User文件夹中的stm32f10x_it.c,文件夹注释掉STM库函数中的void SVC_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void);这三个中断空函数

void SVC_Handler(void);

void PendSV_Handler(void);

void SysTick_Handler(void);

3.4 完成中断函数的宏定义,打开上面步骤中移植的FreeRTOSConfig.h中,在条件编译中加入以下三条宏定义:

#define xPortPendSVHandler PendSV_Handler

#define vPortSVCHandler SVC_Handler

#define xPortSysTickHandler SysTick_Handler

到这里,FreeRTOS系统移植已经全部完成,可以编译一下,无错误,无警告

(三) FreeRTOS系统运行验证

1.对我们移植后的LED闪烁项目工程.main函数进行简单修改,使其调用移植的FreeRTOS任务调度函数运行程序,(这里需要注意如果裸机工程的Delay函数使用的是SysTick系统滴答定时器,移植FreeRTOS系统之后需要删除掉裸机的Delay函数或者替换成time定时器,因为FreeRTOS 底层依赖的是 SysTick 定时器实现 tick 计数驱动vTaskDelay和任务调度)

#include "FreeRTOS.h"                  // Device header #include "task.h" #include "LED.h" #include "stm32f10x.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);//设置系统中断优先级分组4               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();          //开启任务调度 }

//开始任务任务函数 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_TASK_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_TASK_PRIO,                 (TaskHandle_t*  )&LED1Task_Handler);              vTaskDelete(StartTask_Handler); //删除开始任务     taskEXIT_CRITICAL();            //退出临界区 }

//LED0任务函数  void led0_task(void *pvParameters) {     while(1)     {         LED1_Turn();         vTaskDelay(500);     } }   

//LED1任务函数 void led1_task(void *pvParameters) {     while(1)     {         LED2_ON();         vTaskDelay(800);         LED2_OFF();         vTaskDelay(800);     } }

2.编译无报错烧录到stm32f103c8t6中查看现象,LED1 和LED2分别以以 500ms 和800 ms为周期交替闪缩

3.项目工程文件 链接: https://pan.baidu.com/s/1CETJBsbNktXku6lo-PeXFA?pwd=1314

提取码: 1314

赞(0)
未经允许不得转载:171主机测评 » 【FreeRTOS初学者详细教程(一)】—在stm32标准库裸机程序上移植FreeRTOS
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址