[APM32F1] APM32F103的FreeRTOS移植介绍(基于官网资料)
·
1. RTOS介绍
FreeRTOS 是一款免费、开源、轻量级的实时操作系统(RTOS),专为微控制器(MCU)和小型嵌入式系统设计,使用相当广泛,同时易于使用。
官网:https://wap.freertos.org/
官网有详细的FreeRTOS介绍,包含移植教程。以下则基于官网的下图所示移植说明进行移植。

2. 硬件
APM32F103VB MINI板
3. 移植介绍
在开始移植前,需确保有一个完全能正确执行的裸机代码环境。

如下为本次移植的裸机代码环境:

官网提供最新版本的OS代码下载。部分.c源文件是必须使用的,可选的.c源文件则根据自己的情况酌情添加,实际代码位于FreeRTOS/FreeRTOS-Kernel目录内。


此处,我们将.c源文件拷贝工程的/lib/FreeRTOS/kernel目录内:

因为我们使用的是Keil编译环境,所以port.c应该从FreeRTOS/FreeRTOS-Kernel/portable/Keil中拷贝使用,但Keil目录内提示“See-also-the-RVDS-directory”,所以实际从目录:FreeRTOS/FreeRTOS-Kernel/portable/RVDS拷贝即可,且APM32F103为Cortex-M3内核,所以port最终拷贝的目录为:FreeRTOS/FreeRTOS-Kernel/portable/RVDS/ARM_CM3:

代码拷贝到工程的lib/FreeRTOS/portable目录中:

heap_x.c位于源码的FreeRTOS/FreeRTOS-Kernel/portable/MemMang目录内,此处拷贝到工程的lib/FreeRTOS/MemMang目录中:


.c源文件拷贝完成,还有部分头文件需要拷贝,将整个include文件夹拷贝到工程目录中:


其中配置文件FreeRTOSConfig.h位于目录:
FreeRTOS/FreeRTOS-Kernel/examples/template_configuration

同时,注意官网的提示:It is therefore specific to the application, not the RTOS, and should be located in an application directory, not in one of the RTOS kernel source code directories.
配置文件是应用特定的文件,不是RTOS的一部分,应该放到应用的文件夹内,所以我们放在工程的src/app文件夹内:

至此,文件的拷贝完成,添加到工程中,并添加对应的头文件路径(选择使用heap_4.c,其他版本可从官网查看差异并根据自己的情况选择):

因为是通用的配置文件,因此不可能一次性编译成功,还需要修改FreeRTOSConfig.h,首次编译后出现多个errors,都是配置文件的问题,配置文件各个宏定义不理解含义,则可以在官网点进去查看,里面有绝大部分宏定义的解析,另外也可以借助AI工具查找资料辅助理解:


具体FreeRTOSConfig.h如何修改,大家根据编译提示和官网的解析,做对应的更改即可,同时功能裁剪也是配置文件的工作。
最后,要注意到平台移植port.c文件内部:
复制
/** Exception handlers.*/void xPortPendSVHandler( void );void xPortSysTickHandler( void );void vPortSVCHandler( void );
已经实现了三个中断服务函数,这三个中断服务函数非常重要,我们需要屏蔽apm32f10x_int.c文件中的对应版本,改为使用port.c内的代码:
复制
/*!* @brief This function handles SVCall exception** @param None** @retval None**///void SVC_Handler(void)//{//}/*!* @brief This function handles PendSV_Handler exception** @param None** @retval None**///void PendSV_Handler(void)//{//}/*!* @brief This function handles SysTick Handler** @param None** @retval None**///void SysTick_Handler(void)//{//}
因为startup.s启动文件的中断服务函数名与apm32f10x_int.c中是一致的,所以为了改为使用port.c内的中断服务函数名,需要在FreeRTOSConfig.h文件添加如下宏定义:
复制
/* 每次任务切换都执行, 保存 / 恢复上下文,完成任务切换 */#define xPortPendSVHandler PendSV_Handler/* 系统启动时仅执行一次, 启动第一个任务,切换到线程模式 */#define vPortSVCHandler SVC_Handler/* cmsis_os2.c 已经实现新的版本 *//* 提供OS运行的节拍 */#define xPortSysTickHandler SysTick_Handler
此时,FreeRTOS的移植就已经全部完成,我们可以直接按照OS的代码写法要求写代码测试即可。
下面介绍一个使用FreeRTOS更便利的方案:
如果了解FreeRTOS,会知道,同一个功能,在中断环境下和非中断环境下,调用的OS接口是不一样的,例如,获取信号量,中断环境下需要调用xSemaphoreTakeFromISR,而非中断环境下需要调用xSemaphoreTake。ARM为此提供了一个解决方案,屏蔽了这种差异,让中断和非中断环境下,都是调用同一个接口函数。
拷贝cmsis_os2的代码到OS目录中,只有3个文件:

打开cmsis_os2.c,查看获取信号量部分的代码,osSemaphoreAcquire函数内部会调用IS_IRQ检查当前是否处于中断环境,如果是则调用xSemaphoreTakeFromISR接口,否则调用xSemaphoreTake接口,而我们在编程时,不管是中断或非中断环境下,都是统一调用osSemaphoreAcquire接口即可,非常便利。
其他的功能也有一样的处理方式。

有cmsis_os加入后,编程需要使用到OS的功能,都统一从cmsis_os.h/cmsis_os2.h中取接口函数使用即可,不用再使用原生的FreeRTOS接口。
因为cmsis_os2.c中重新实现了SysTick_Handler中断服务函数,所以FreeRTOSConfig.h需要屏蔽掉xPortSysTickHandler宏定义,使用cmsis_os2.c中的版本即可。


4. 测试
测试创建两个任务,分别翻转1个LED进行测试:
复制
/* LED_D2 */TaskHandle_t *led_d2_task_handle;const osThreadAttr_t led_d2_task_att = {.name = "LED_D2",.priority = (osPriority_t)10,.stack_size = (1024),};/* LED_D3 */TaskHandle_t *led_d3_task_handle;const osThreadAttr_t led_d3_task_att = {.name = "LED_D3",.priority = (osPriority_t)11,.stack_size = (1024),};/** @brief LED D2 任务** @param None** @retval None**/static void led_d2_task(void *argument){(void)argument;while (1) {bsp_gpio_toggle(OUTPUT_LED2);osDelay(100);}}/** @brief LED D3 任务** @param None** @retval None**/static void led_d3_task(void *argument){(void)argument;while (1) {bsp_gpio_toggle(OUTPUT_LED3);osDelay(300);}}/** @brief 任务创建** @param None** @retval None**/void task_create(void){led_d2_task_handle = osThreadNew(led_d2_task, NULL, &led_d2_task_att);led_d3_task_handle = osThreadNew(led_d3_task, NULL, &led_d3_task_att);}
复制
// 外设初始化void bsp_init(void){NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_4);bsp_gpio_init();}
复制
// 应用初始化void app_init(void){osKernelInitialize();task_create();osKernelStart();}// 应用任务void app_task(void){}
LED翻转的间隔时间与程序使用的osDelay延时一致。

另外,NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_4)将优先级分组配置为4,则中断优先级全部为抢占,而没有子优先级,方便OS管理中断。
5.详细代码

FreeRTOS.zip (5.94 MB, 下载次数: 0)






















。
---------------------
作者:口天土立口
链接:https://bbs.21ic.com/icview-3509353-1-1.html?_dsign=7f5afd4e
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)