【开发环境】
硬件:mac OS 15.2

代码编辑:Vscode
编译工具:arm-none-eabi gcc 14.2
【移植步骤】
1、下载官方示例,在示例中有FreeRTOS的源码,在目录3rdPartySoftwarePorting/FreeRTOS目录下面。
2、把该目录的FreeRTOS-KernelV10.5.1复制到工程目录下面,并重命名为FreeRTOS
3、复制Demos/FreeRTOS_Blinky目录下面的FreeRTOSConfig.h到app目录下面。
工程文件如下图所示:

4、编写FreeRTOS下面的makefile.mk如下:
# 模块名_DIR 是上一层传递下来的参数, # 是从工程根目录到该模块文件夹的路径 # 向 C_SOURCES 中添加需要编译的源文件 C_SOURCES += $(wildcard $(FreeRTOS_DIR)/*.c) C_SOURCES += $(wildcard $(FreeRTOS_DIR)/portable/GCC/ARM_CM33_NTZ/non_secure/*.c) C_SOURCES += $(wildcard $(FreeRTOS_DIR)/portable/MemMang/heap_4.c) # 向 C_INCLUDES 中添加头文件路径 C_INCLUDES += -I$(FreeRTOS_DIR)/include C_INCLUDES += -I$(FreeRTOS_DIR)/portable/GCC/ARM_CM33_NTZ/non_secure
意思是把FreeRTOS下面所有的.c,portable/GCC/ARM_CM33_NTZ/non_secure目录下面所有的.c 以及portable/MemMang/heap_4.c添加进编译。同时添加include 、portable/GCC/ARM_CM33_NTZ/non_secure头文件到工程中。
5、注释掉mm32f5370_it.c中的三个函数SVCall_Handler、PendSV_Handler、SysTick_Handler。
【测试代码】
#define _MAIN_C_
/* Files include */
#include "platform.h"
#include "main.h"
#include "FreeRTOS.h"
#include "task.h"
#include "stdio.h"
/***********************************************************************************************************************
* @brief This function is main entrance
* @note main
* @param none
* @retval none
*********************************************************************************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_STK_SIZE 256
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define LED1_TASK_PRIO 2
//任务堆栈大小
#define LED1_STK_SIZE 256
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
//任务优先级
#define LED2_TASK_PRIO 3
//任务堆栈大小
#define LED2_STK_SIZE 256
//任务句柄
TaskHandle_t LED2Task_Handler;
//任务函数
void led2_task(void *pvParameters);
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
PLATFORM_InitConsole(115200);
PLATFORM_InitLED();
PLATFORM_PrintInfo();
//创建开始任务
xTaskCreate( start_task , //任务函数
(const char* )"start_task", //任务名称
(uint16_t )START_STK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
vTaskStartScheduler(); //开启任务调度
while (1)
{
}
}
//开始任务任务函数
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建LED0任务
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);
//创建LED1任务
xTaskCreate((TaskFunction_t )led2_task,
(const char* )"led2_task",
(uint16_t )LED2_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED2_TASK_PRIO,
(TaskHandle_t* )&LED2Task_Handler);
vTaskDelete(StartTask_Handler); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//LED0任务函数
void led1_task(void *pvParameters)
{
while(1)
{
printf("led1_task\r\n");
GPIO_WriteBit(GPIOB, GPIO_Pin_15, 0);
vTaskDelay(500);
GPIO_WriteBit(GPIOB, GPIO_Pin_15, 1);
vTaskDelay(500);
}
}
//LED1任务函数
void led2_task(void *pvParameters)
{
while(1)
{
printf("task2\r\n");
GPIO_WriteBit(GPIOB, GPIO_Pin_14, 0);
vTaskDelay(200);
GPIO_WriteBit(GPIOB, GPIO_Pin_14, 1);
vTaskDelay(200);
}
}【测试效果】
下载到开发板后,可以看到两个LED灯以不同频率显示,同时串口也打印出相关的任务:

【总结】
我在前面移植过MM32F5260的FreeRTOS工程,这次移植也是不尽相同,所以上手比较快。注意的是,不要再执行PLATFORM_InitDelay这个初始化函数,否则会卡死在printf里面。
我要赚赏金
