FreeRTOS-STM32-HAL库一步步移植教程
FreeRTOS-HAL库一步步移植教程下载FreeRTOS裁切文件创建HAL工程配置时钟配置时钟树配置时基源配置NVIC配置代码生成 code generstion移植测试引脚生成Keil工程项目移植FreeRTOS到Keil 并配置配置Keil配置include pathsFreeRTOSConfig.h 文件添加宏定义stm32f1xx_it.c 文件配置创建一个动态任务测试下载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中断服务函数相关定义 */#definexPortPendSVHandlerPendSV_Handler#definevPortSVCHandlerSVC_Handler/* 可选函数, 1: 使能 */#defineINCLUDE_xTaskGetSchedulerState1/* 获取任务调度器状态 */stm32f1xx_it.c 文件配置添加头文件#includeFreeRTOS.h#includetask.h配置中断服务函数voidSysTick_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闪烁一次#includefreertos_task.h#includeFreeRTOS.h#includetask.h#includemain.h#defineSTART_TASK_PRIO1/* 任务优先级 */#defineSTART_STK_SIZE128/* 任务堆栈大小 */TaskHandle_t StartTask_Handler;/* 任务句柄 */voidstart_task(void*pvParameters);/* 任务函数 */#defineTASK1_PRIO2/* 任务优先级 */#defineTASK1_STK_SIZE128/* 任务堆栈大小 */TaskHandle_t Task1Task_Handler;/* 任务句柄 */voidtask1(void*pvParameters);/* 任务函数 */voidfreertos_init(void){xTaskCreate((TaskFunction_t)start_task,/* 任务函数 */(constchar*)start_task,/* 任务名称 */(uint16_t)START_STK_SIZE,/* 任务堆栈大小 */(void*)NULL,/* 传入给任务函数的参数 */(UBaseType_t)START_TASK_PRIO,/* 任务优先级 */(TaskHandle_t*)StartTask_Handler);/* 任务句柄 */vTaskStartScheduler();}voidstart_task(void*pvParameters){taskENTER_CRITICAL();/* 进入临界区 *//* 创建任务1 */xTaskCreate((TaskFunction_t)task1,/* 任务函数 */(constchar*)task1,/* 任务名称 */(uint16_t)TASK1_STK_SIZE,/* 任务堆栈大小 */(void*)NULL,/* 传入给任务函数的参数 */(UBaseType_t)TASK1_PRIO,/* 任务优先级 */(TaskHandle_t*)Task1Task_Handler);/* 任务句柄 */vTaskDelete(StartTask_Handler);/* 删除开始任务 */taskEXIT_CRITICAL();/* 退出临界区 */}voidtask1(void*pvParameters){while(1){HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);vTaskDelay(1000);}}在 main 函数中初始化 freertos_init 任务即可创建成功 并执行task1任务 每1s翻转一次电平此次移植完成