FreeRTOS-STM32-HAL库一步步移植教程
FreeRTOS-HAL库一步步移植教程
下载FreeRTOS
首先下载FreeRTOS的网址:FreeRTOS网址
打开网址后,选择下载弹出窗口,再次点击 查看更多下载选项和后续步骤
点击就会跳转新的页面 在下载FreeRTOS一栏中 找到 后续步骤内容中的之前版本
选择要下载的版本 FreeRTOSv202212.01.zip(这是2022年12月发布的稳定版本)

裁切文件
将下载的压缩包解压,复制7个C文件,文件在路径 FreeRTOSv202212.01\FreeRTOS\Source
自己创建一个空白的文件夹用来放这7个C文件,例如我的 Middlewares\FreeRTOS\Source,这个Middlewares以后就可以直接复制移植到工程中。
在当前文件夹创建一个 portable 文件夹
这个文件夹里面分别再创建两个文件夹
首先第一个 MemMang ,将官方的文件夹中MemMang里面 heap_4.c文件复制到我们创建的文件夹中
转移到自己创建的
下面是 RVDS 文件夹,直接复制官方的RVDS里面的ARM_CM3这个选择跟芯片有关系
下图是自己创建的
下面移植include文件夹,将官方的include文件夹直接复制到自己的Source文件夹中

最后一个文件路径如下
我先暂时放到FreeRTOS路径下面,等创建好工程再转移到专门放头文件的路径下
创建HAL工程
这里使用cubemx创建工程
配置时钟

配置时钟树

配置时基源

配置NVIC
将时基源优先级设为1(数字越小优先级越高)
配置代码生成 code generstion
这样就不会每次更改cubemx都要进行注释这个两个中断函数了
移植测试引脚

生成Keil工程项目
当前工程还没将FreeRTOS复制过去
移植FreeRTOS到Keil 并配置
直接将 Middlewares 文件夹移动到 FreeRTOS_basic 工程路径下
再将 Middlewares 文件夹中的 FreeRTOSConfig.h 文件移动到 Inc 文件夹中,移动完成后开始配置Keil
配置Keil
添加文件分类
添加 FreeRTOSConfig.h 文件 有利于修改配置
配置include paths
添加这两个路径
FreeRTOSConfig.h 文件添加宏定义
/* FreeRTOS中断服务函数相关定义 */
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
/* 可选函数, 1: 使能 */
#define INCLUDE_xTaskGetSchedulerState 1 /* 获取任务调度器状态 */

stm32f1xx_it.c 文件配置
添加头文件
#include "FreeRTOS.h"
#include "task.h"
配置中断服务函数
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
/* USER CODE BEGIN SysTick_IRQn 1 */
if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
xPortSysTickHandler();
}
/* USER CODE END SysTick_IRQn 1 */
}
引用函数extern void xPortSysTickHandler( void );
创建一个动态任务测试
将LED0每1000ms闪烁一次
#include "freertos_task.h"
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#define START_TASK_PRIO 1 /* 任务优先级 */
#define START_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t StartTask_Handler; /* 任务句柄 */
void start_task(void *pvParameters); /* 任务函数 */
#define TASK1_PRIO 2 /* 任务优先级 */
#define TASK1_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t Task1Task_Handler; /* 任务句柄 */
void task1(void *pvParameters); /* 任务函数 */
void freertos_init(void)
{
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(); /* 进入临界区 */
/* 创建任务1 */
xTaskCreate((TaskFunction_t)task1, /* 任务函数 */
(const char *)"task1", /* 任务名称 */
(uint16_t)TASK1_STK_SIZE, /* 任务堆栈大小 */
(void *)NULL, /* 传入给任务函数的参数 */
(UBaseType_t)TASK1_PRIO, /* 任务优先级 */
(TaskHandle_t *)&Task1Task_Handler); /* 任务句柄 */
vTaskDelete(StartTask_Handler); /* 删除开始任务 */
taskEXIT_CRITICAL(); /* 退出临界区 */
}
void task1(void *pvParameters)
{
while (1)
{
HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);
vTaskDelay(1000);
}
}
在 main 函数中初始化 freertos_init 任务即可创建成功 并执行task1任务 每1s翻转一次电平,此次移植完成
更多推荐
所有评论(0)