FreeRTOS学习笔记(二):深入探索与理解

FreeRTOS移植

一、获取FreeRTOS源码

1.1官网下载

进入官网直接下载

官网:https://www.freertos.org/zh-cn-cmn-s/

1.2 正点原子网盘下载

正点原子资料v10.4.6

例程git : https://gitee.com/yuan-zhenbin/freertos-code-repository.git

FreeRTOS资料网盘: http://www.openedv.com/docs/book-videos/zdyzshipin/4free/newfreertos.html

二、源码内容

名称 内容
Free RTOS 内核
Free RTOS-PLUS 组件
tools 工具
Github-Free RTOS-Home Github仓库链接
Quick_Start_Guide 快速入门官方指南
Upgrading-to-FreeRTOS-xxx 升级指定版本文档链接
History 历史更新记录
其他 其他

2.1 FreeRTOS内核

名称 描述
Demo FreeRTOS演示例程
License 相关许可
Source **FreeRTOS内核源码
Test 公用以及移植层测试代码
2.1.1 Demo

支持多种芯片架构,多种不同型号芯片

2.1.2 Source
名称 描述
include 包含头文件✔
portable 包含移植文件✔
croutine.c 协程相关文件
event_groups.c 事件相关文件
list.c 列表相关文件✔
queue.c 队列相关文件✔
stream_buffer.c 流式缓冲区相关文件
tasks.c 任务相关文件✔
timer.c 软件定时器相关文件
portable文件夹

建立软件硬件的桥梁,根据硬件和编译器选择文件:这里选择Keil、MemMang、RVDS。

名称 描述
Keil 指向RVDS文件夹
RVDS 不同内核芯片的移植文件
MemMang 内存管理文件

三、FreeRTOS移植

3.1 准备内容

Free RTOS源码

基础工程

3.2 移植步骤

  1. 添加FreeRTOS源码

  2. 添加FreeRTOS.h

  3. 修改SYSTEM文件夹中的sys.c 、 delay.c 、usart.c

  4. 修改中断相关文件,Systick中断、 SVC中断、 PendSV中断

  5. 添加应用程序,验证是否成功

3.3 进行移植

3.3.1添加RTOS文件

这里选择HAL库内存管理例程作为基础工程

在Middlewares新建FreeRTOS文件夹

将FreeRTOS源码部分拷贝进文件夹

可以选择删除portable中的文件夹,这里只保留Keil、MemMang、RVDS。

3.3.2将文件添加到工程

打开基础工程,新建两个文件分组。Middlewares/FreeRTOS_CORE和Middlewares/FreeRTOS_PORT

CORE添加对应的文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

PORT添加对应的文件

添加头文件路径,将include和portable中对应的内核版本添加到头文件路径中

3.3.3 添加FreeRTOSConfig.h文件

裁剪不需要的功能,节约内存资源,有三种获取方式

  • 用户自行缩写,

  • 参考官方demo配置

  • 用正点原子官方写好的

  • 拷贝到基础工程文件的User文件夹

    3.3.4 修改system文件
    修改sys.h

    使其支持OS

    修改usart.c

    Free RTOS没有 µC/OS对于中断的处理机制。删除osintenter和osintexit

    删除下列代码

    修改delay.c

    删除35行到112

    添加Free RTOS相关代码

    extern void xPortSysTickHandler(void);
    

    修改中断函数

    改为

    void SysTick_Handler(void)
    {
     uint32_t ulPreviousMask;
    
     HAL_IncTick();
     /* OS 开始跑了,才执行正常的调度处理 */
     if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
     {
     ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
     {
     /* Increment the RTOS tick. */
     if( xTaskIncrementTick() != pdFALSE )
     {
     /* Pend a context switch. */
     portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
     }
     }
     portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
     }
    }
    

    修改延时初始化函数

    改为

    void delay_init(uint16_t sysclk)
    {
    #if SYS_SUPPORT_OS
     uint32_t reload;
    #endif
     HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
     g_fac_us = sysclk;
    
    #if SYS_SUPPORT_OS
     reload = sysclk;
     /* 使用 configTICK_RATE_HZ 计算重装载值
     * configTICK_RATE_HZ 在 FreeRTOSConfig.h 中定义
     */
     reload *= 1000000 / configTICK_RATE_HZ;
     /* 删除不用的 g_fac_ms 相关代码 */
     SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
     SysTick->LOAD = reload;
     SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
    #endif
    }
    
    

    修改微秒函数

    改为

    void delay_us(uint32_t nus)
    {
     uint32_t ticks;
     uint32_t told, tnow, tcnt = 0;
     uint32_t reload = SysTick->LOAD;
     /* 删除适用于 µC/OS 用于锁定任务调度器的自定义函数 */
     ticks = nus * g_fac_us;
     told = SysTick->VAL;
     while (1)
     {
     tnow = SysTick->VAL;
     if (tnow != told)
     {
     if (tnow < told)
     {
     tcnt += told - tnow;
     }
     else
     {
     tcnt += reload - tnow + told;
     }
     told = tnow;
     if (tcnt >= ticks)
     {
     break;
     }
     }
     }
     /* 删除适用于 µC/OS 用于解锁任务调度器的自定义函数 */
    }
    
    
    

    修改毫秒函数

    改为

    void delay_ms(uint16_t nms)
    {
     uint32_t i;
    
     for (i=0; i<nms; i++)
     {
     delay_us(1000);
     }
    }
    
    

    修改头文件

    /* 添加公共头文件 (FreeRTOS 需要用到) */
    #include "FreeRTOS.h"
    #include "task.h"
    
    修改中断相关文件

    在stm32f4xx_it.c中将HAL库提供的system,SVC,PendSV进行宏开关

    导入sys.h

    /* Includes --------------------------------------*/
    /* 导入 sys.h 头文件 */
    #include "./SYSTEM/SYS/sys.h"
    

    将几个中断更改为条件编译

    SVC

    /**
     * @brief This function handles SVCall exception.
     * @param None
     * @retval None
     */
    /* 加入宏开关 */
    #if (!SYS_SUPPORT_OS)
    void SVC_Handler(void)
    {
    }
    #endif
    

    PendSV

    /**
     * @brief This function handles PendSVC exception.
     * @param None
     * @retval None
     */
    /* 加入宏开关 */
    #if (!SYS_SUPPORT_OS)
    void PendSV_Handler(void)
    {
    }
    #endif
    

    SysTick

    #if (!SYS_SUPPORT_OS)
    void SysTick_Handler(void)
    {
     HAL_IncTick();
    }
    #endif
    
    
    最后一步

    FreeRTOSconfig.h中,通过该定义找到需要修改的文件,此处为stm32f429xx.h

    将4U改为4

    编译

    还可以做的事

    修改工程目标名称

    移除USMART调试组件,删除main.c的引用。

    添加定时器驱动

    结束

    烧入程序测试是否成功

    作者:维叶莫

    物联沃分享整理
    物联沃-IOTWORD物联网 » FreeRTOS学习笔记(二):深入探索与理解

    发表回复