FreeRTOS移植
一、下载FreeRTOS操作系统
下载链接:https://github.com/FreeRTOS/FreeRTOS/releases
选择合适版本后下载并解压
二、文件移植
由于系统文件版本的不同,可能文件名不完全一样,但大概含义是相同的。
1.通用文件:source/src文件夹所有的*.c文件

2.通用头文件:include 文件夹里的所有文件

3.port/portable文件夹:MemMang文件夹下的文件(一般使用heap_4.c)、RVDS的文件夹所有文件(根据芯片类型选择对应的文件)


4.在demo文件夹中根据单片机芯片类型和编译器类型选择对应的FreeRTOSConfig.h文件,以STM32芯片和Keil编译器为例。

以上文件,为移植必备文件
三、文件内容修改
1.FreeRTOSConfig.h

| configUSE_PREEMPTION | 1:抢占式调度(高优先级抢占低优先级)。 0:协作式调度,任务必须主动让出 CPU,高优先级也不能抢。 |
| configUSE_IDLE_HOOK | 空闲任务工作函数。FreeRTOS 优先级最低的任务,当没有任何就绪任务可以运行时,调度器就会运行空闲任务。适合放一些不重要、没有时间要求、CPU 有空才执行的代码。最长用在低功耗模式 0:关闭钩子函数 1:必须实现钩子函数, void vApplicationIdleHook(void);空闲任务每次循环都会调用它 |
| configUSE_TICK_HOOK |
系统节拍中断钩子。 0:关闭 1:每一次 SysTick 中断都会调用 |
| configCPU_CLOCK_HZ | CPU 内核时钟频率,单位 Hz。 |
| configTICK_RATE_HZ | 系统节拍频率(滴答定时器),例如1000=1000Hz,1ms一次中断 |
| configMAX_PRIORITIES | 最大任务优先级数量(0--x-1),数字越大,优先级越高。 |
| configMINIMAL_STACK_SIZE | 空闲任务的栈深度,单位word(4字节STM下)。128 word × 4 = 512 字节空闲任务栈。 |
| configTOTAL_HEAP_SIZE | FreeRTOS 堆总大小。例如:17KB。 用于: xTaskCreate、xQueueCreate、xSemaphoreCreate、xTimerCreate 动态申请内存。 |
| configMAX_TASK_NAME_LEN | 任务名称字符串最大长度,字节数。 |
| configUSE_TRACE_FACILITY |
任务追踪功能开关。 1:编译 |
| configUSE_16_BIT_TICKS |
系统节拍计数器宽度。 0:32 位 TickType_t。节拍计数器可以计数很久才溢出,STM32 必选 0。 1:16 位,最多 65 秒左右 Tick 就溢出,一般不用。 |
| configIDLE_SHOULD_YIELD | 空闲任务让步开关。
当有多个任务优先级 = 0(和空闲任务同优先级): 1:空闲任务运行一次后主动让出 CPU,给其他优先级 0 任务轮流执行(时间片轮转)。 0:空闲任务会一直占着 CPU,其他优先级 0 任务很难抢到时间。 |
2.根据实际使用,修改FreeRTOS.h相关宏定义(以下是举例)
| configUSE_MUTEXES | 互斥锁开关 |
| configUSE_TIMERS |
软件定时器 |
| configUSE_COUNTING_SEMAPHORES |
开启 计数信号量(Counting Semaphore) 功能 |
3.修改全局中断入口文件(存放所有外设、内核中断的中断服务函数(ISR)),以stm32f10x_it为例
SysTick 中断服务函数是 FreeRTOS 中至关重要的核心函数。FreeRTOS 所有与时间相关的调度逻辑,都依靠 SysTick 中断来完成,SysTick 相当于 FreeRTOS 的心跳时钟,驱动整个操作系统正常运行。一旦 FreeRTOS 的心跳中断失效,内核就会停止任务调度,程序卡死,所有任务都无法继续执行。因此移植 FreeRTOS 时,必须正确配置并开启 SysTick 心跳时钟。
心跳时钟的初始化工作,FreeRTOS 已经在 port.c 文件内完成封装:函数 vPortSetupTimerInterrupt() 负责完成 SysTick 定时器的配置与启动;SysTick 的中断处理逻辑也已经在 port.c 中通过 xPortSysTickHandler() 实现。 基于以上,开发者仅需在芯片的中断文件 stm32f10x_it.c 中,编写平台对应的 SysTick_Handler() 中断服务函数,并在函数内部调用 xPortSysTickHandler(),即可完成心跳对接。
extern void xPortSysTickHandler(void);
//systick中断服务函数
void SysTick_Handler(void)
{
#if (INCLUDE_xTaskGetSchedulerState == 1 )
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
#endif /* INCLUDE_xTaskGetSchedulerState */
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
}
#endif /* INCLUDE_xTaskGetSchedulerState */
}
除 SysTick 以外,任务切换所依赖的 PendSV_Handler()、系统调用所需的 SVC_Handler() 两个核心中断函数,FreeRTOS 同样已经在 port.c 文件中给出了实现,对应函数分别为 xPortPendSVHandler() 和 vPortSVCHandler(),无需开发者自行编写。 所以在移植操作中,需要注释掉 stm32f10x_it.c 文件中原有的 PendSV_Handler() 与 SVC_Handler() 两个中断服务函数,避免出现函数重定义冲突。
/**
* @brief This function handles SVCall exception.
* @param None
* @retval None
*/
//void SVC_Handler(void)
//{
//}
/**
* @brief This function handles PendSVC exception.
* @param None
* @retval None
*/
//void PendSV_Handler(void)
//{
//}
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)