一、下载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 中断都会调用 vApplicationTickHook()

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。
用于:xTaskCreatexQueueCreatexSemaphoreCreatexTimerCreate 动态申请内存。
configMAX_TASK_NAME_LEN 任务名称字符串最大长度,字节数。
configUSE_TRACE_FACILITY

任务追踪功能开关。

1:编译uxTaskGetSystemState()、uxTaskGetStackHighWaterMark()、vTaskList()。

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)
//{
//}

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐