FreeRTOS在STM32F4上移植

2023-05-16

本文是《ALIENTEK STM32F429 FreeRTOS 开发教程》第二章学习笔记
第一章笔记–FreeRTOS简介与源码下载

一、移植

1. 准备工程文件

MCU用的是STM32F429的CORE,用keli创建一个基础工程

在工程中创建一个名为FreeRTOS的文件夹
这里写图片描述

2.文件中添加源码

把FreeRTOS的源码复制到FreeRTOS文件夹里
这里写图片描述
portable文件夹中只保留 keli,MemMang,RVDS三个文件夹即可
这里写图片描述

3.工程分组中添加文件

在工程文件中新建分组FreeRTOS_CORE与FreeRTOS_PORTABLE

把相关内核.c文件添加进分组FreeRTOS_CORE

把RVDS文件夹下的ARM_CM4F中的port.c和MemMang文件夹里的heap_4.c添加进分组FreeRTOS_PORTABLE
这里写图片描述
添加FreeRTOS源码的头文件路径
这里写图片描述

4.添加FreeRTOSConfig.h文件

在FreeRTOS的官方移植工程Demo文件夹下,找到CORTEX_M4F_STM32F407ZG-SK文件夹,打开找到里面的FreeRTOSConfig.h文件
这里写图片描述
添加到自己创建的工程文件FreeRTOS文件夹下的include文件夹里
这里写图片描述

更改SystemCoreClock的条件编译条件

#ifdef __ICCARM__
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif

改为i

#if defined(__ICCARM__) || defined(__CC_ARM) ||defined(__GUNC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif

5. 注释掉重复定义函数

在port.c和stm32f4xx_it.c两个文件中有重复定义的函数,需要注释掉stm32f4xx_it.c中的PendSV_Handler()、SVC_Handler()和Systick_Handler()三个函数

6.关闭钩子函数

复制过来的FreeRTOSConfig.h文件中默认开启了一些钩子函数,都是以Hook结尾,但并未定义,在FreeRTOSConfig.h中把configUSE_IDLE_HOOK、configUSE_TICK_HOOK、configCHECK_FOR_STACK_OVERFLOW和MALLOC_FAILED_HOOK的宏定义改为0

7. 修改sys.h文件

将SYSTEM文件夹下的sys.h文件修改成使用OS

//0,不支持os
//1,支持os
#define SYSTEM_SUPPORT_OS       1       //定义系统文件夹是否支持OS

8. 修改usart.c文件

打开SYSTEM文件夹下usart.c文件,添加FreeRTOS.h头文件

#if SYSTEM_SUPPORT_OS
#include "FreeRTOS.h"                   //os 使用   
#endif

USART1的中断服务函数在使用UCOS时进出中断添加OSIntEnter()与OSIntExit(),使用FreeRTOS则不需要,故注释掉

//串口1中断服务程序
void USART1_IRQHandler(void)                    
{ 
    u32 timeout=0;
    u32 maxDelay=0x1FFFF;
//#if SYSTEM_SUPPORT_OS     //使用OS
//  OSIntEnter();    
//#endif

    HAL_UART_IRQHandler(&UART1_Handler);    //调用HAL库中断处理公用函数

    timeout=0;
    while (HAL_UART_GetState(&UART1_Handler) != HAL_UART_STATE_READY)//等待就绪
    {
     timeout++;////超时处理
     if(timeout>maxDelay) break;        

    }

    timeout=0;
    while(HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1
    {
     timeout++; //超时处理
     if(timeout>maxDelay) break;    
    }
//#if SYSTEM_SUPPORT_OS     //使用OS
//  OSIntExit();                                             
//#endif
} 

9. 修改delay.c文件

打开SYSTEM文件夹里delay.c文件,重新写入所需代码

#include "delay.h"
#include "sys.h"
//////////////////////////////////////////////////////////////////////////////////   
//如果使用OS,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "FreeRTOS.h"                   //FreeRTOS使用     
#include "task.h"
#endif
static u32 fac_us=0;                            //us延时倍乘数

#if SYSTEM_SUPPORT_OS       
    static u16 fac_ms=0;                        //ms延时倍乘数,在os下,代表每个节拍的ms数
#endif


extern void xPortSysTickHandler(void);
//systick中断服务函数,使用OS时用到
void SysTick_Handler(void)
{  
    if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
    {
        xPortSysTickHandler();  
    }
    HAL_IncTick();
}

//初始化延迟函数
//当使用ucos的时候,此函数会初始化ucos的时钟节拍
//SYSTICK的时钟固定为AHB时钟
//SYSCLK:系统时钟频率
void delay_init(u8 SYSCLK)
{
    u32 reload;
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//SysTick频率为HCLK
    fac_us=SYSCLK;                          //不论是否使用OS,fac_us都需要使用
    reload=SYSCLK;                          //每秒钟的计数次数 单位为K    
    reload*=1000000/configTICK_RATE_HZ;     //根据configTICK_RATE_HZ设定溢出时间
                                            //reload为24位寄存器,最大值:16777216,在180M下,约合0.745s左右  
    fac_ms=1000/configTICK_RATE_HZ;         //代表OS可以延时的最少单位     
    SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断
    SysTick->LOAD=reload;                   //每1/configTICK_RATE_HZ断一次  
    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
}                                   

//延时nus
//nus:要延时的us数.  
//nus:0~190887435(最大值即2^32/fac_us@fac_us=22.5)                                        
void delay_us(u32 nus)
{       
    u32 ticks;
    u32 told,tnow,tcnt=0;
    u32 reload=SysTick->LOAD;               //LOAD的值             
    ticks=nus*fac_us;                       //需要的节拍数 
    told=SysTick->VAL;                      //刚进入时的计数器值
    while(1)
    {
        tnow=SysTick->VAL;  
        if(tnow!=told)
        {       
            if(tnow<told)tcnt+=told-tnow;   //这里注意一下SYSTICK是一个递减的计数器就可以了.
            else tcnt+=reload-tnow+told;        
            told=tnow;
            if(tcnt>=ticks)break;           //时间超过/等于要延迟的时间,则退出.
        }  
    };                                      
}  

//延时nms,会引起任务调度
//nms:要延时的ms数
//nms:0~65535
void delay_ms(u32 nms)
{   
    if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
    {       
        if(nms>=fac_ms)                     //延时的时间大于OS的最少时间周期 
        { 
            vTaskDelay(nms/fac_ms);         //FreeRTOS延时
        }
        nms%=fac_ms;                        //OS已经无法提供这么小的延时了,采用普通方式延时    
    }
    delay_us((u32)(nms*1000));              //普通方式延时
}

//延时nms,不会引起任务调度
//nms:要延时的ms数
void delay_xms(u32 nms)
{
    u32 i;
    for(i=0;i<nms;i++) delay_us(1000);
}

由一个初始化滴答定时器和三个延时函数组成

delay_init()完成初始化滴答定时器。FreeRTOS的系统时钟节拍由宏configTICK_RATE_HZ来设置,由于使用HAL库,而HAL库里延时函数需要滴答定时器时间周期为1ms,责FreeRTOS的系统节拍应该设置成1000HZ(即滴答定时器的中断周期为1ms)

delay_us()、delay_ms()和delay_xms()都是延时函数。

delay_ms()是对FreeRTOS中的延时函数vTaskDelay()的封装,使用时会导致任务切换;

delay_us()是us级的延时函数,os系统节拍是1ms,无法提供那么小的延时,直接使用滴答计时器的计数来延时;

delay_xms()在delay_us()的us级累加到ms级形成延时,完成ms级的延时,但不会像delay_ms()导致任务切换

10. 注释掉FreeRTOSConfig.h里的重复定义函数

注释掉FreeRTOSConfig.h里的重复定义函数SysTick_Handler()
这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS在STM32F4上移植 的相关文章

  • 【FreeRTOS开发问题】FreeRTOS内存溢出

    FreeRTOS内存溢出 如下图所示 FreeRTOS编译完成后可以看到 系统提示无法分配内存到堆 Objects Template axf Error L6406E No space in execution regions with A
  • STM32移植FreeRTOS的Tips

    转自 http bbs armfly com read php tid 7140 1 在FreeRTOS的demo文件夹中拷贝对应的FreeRTOSConfig h文件后 需要加入一行 define configUSE MUTEXES 1
  • ZYNQ中FreeRTOS中使用定时器

    使用普通的Timer中断方式时 Timer中断可以正常运行 但是UDP通信进程无法启动 其中TimerIntrHandler是中断服务程序 打印程序运行时间与从BRAM中读取的数据 void SetupInterruptSystem XSc
  • 基于HAL库的FREERTOS----------一.任务

    FreeROTS 就是一个免费的 RTOS 类系统 这里要注意 RTOS 不是指某一个确定的系统 而是指一类系统 比如 UCOS FreeRTOS RTX RT Thread 等这些都是 RTOS 类操作系统 FreeRTOS 是 RTOS
  • FreeRTOS记录(九、一个裸机工程转FreeRTOS的实例)

    记录一下一个实际项目由裸机程序改成FreeRTOS 以前产品的平台还是C8051单片机上面的程序 硬件平台改成了STM32L051 同时使用STM32CubeMX生成的工程 使用FreeRTOS系统 EEPROM数据存储读取函数修改更新 2
  • freeRTOS使用uxTaskGetStackHighWaterMark函数查看任务堆栈空间的使用情况

    摘要 每个任务都有自己的堆栈 堆栈的总大小在创建任务的时候就确定了 此函数用于检查任务从创建好到现在的历史剩余最小值 这个值越小说明任务堆栈溢出的可能性就越大 FreeRTOS 把这个历史剩余最小值叫做 高水位线 此函数相对来说会多耗费一点
  • 基于HAL库的FREERTOS-----------三.队列

    一 队列简介 在实际的应用中 常常会遇到一个任务或者中断服务需要和另外一个任务进行 沟通交流 这个 沟通交流 的过程其实就是消息传递的过程 在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式 但是如果在使用操作系统的应用中用
  • FreeRTOS临界段和开关中断

    http blog sina com cn s blog 98ee3a930102wg5u html 本章教程为大家讲解两个重要的概念 FreeRTOS的临界段和开关中断 本章教程配套的例子含Cortex M3内核的STM32F103和Co
  • STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • stm32f103zet6移植标准库的sdio驱动

    sdio移植 st官网给的标准库有给一个用于st出的评估板的sdio外设实现 但一是文件结构有点复杂 二是相比于国内正点原子和野火的板子也有点不同 因此还是需要移植下才能使用 当然也可以直接使用正点原子或野火提供的实例 但为了熟悉下sdio
  • FreeRTOS笔记(十)中断

    中断 当CPU在执行某一事件A时 发生另外一个更重要紧急的事件B请求CPU去处理 产生了中断 于是CPU暂时中断当前正在执行的事件A任务而对对事件B进行处理 CPU处理完事件B后再返回之前中断的位置继续执行原来的事件A 这一过程统称为中断
  • FreeRTOS死机原因

    1 中断回调函数中没有使用中断级API xxFromISR 函数 xSemaphoreGiveFromISR uart busy HighterTask 正确 xSemaphoreGive uart busy 错误 2 比configMAX
  • 【FreeRTOS 事件】任务通知事件

    普通任务通知事件创建创建及运行 参阅安富莱电子demo define BIT 0 1 lt lt 0 define BIT 1 1 lt lt 1 static TaskHandle t xHandleTaskUserIF NULL sta
  • 单片机通信数据延迟问题排查

    1 问题说明 笔者在最近的项目中 发现系统的响应延迟较高 经过排查 排除了单片机运行卡死的问题 2 原因分析 具体排查过程这里就不细致说明了 直接给出排查后原因 任务执行周期规划不合理 导致freertos队列发送接收到的命令有延迟 为了便
  • FreeRTOS临界段

    1 临界段 在访问共享资源时不希望被其他任务或者中断打断的代码 这段要执行的代码称为临界段代码 2 设置临界段的目的 保护共享资源 例如 全局变量 公共函数 不可重入函数 函数里面使用 了一些静态全局变量 malloc 等 保护外设的实时性
  • FreeRTOS实时操作系统(三)任务挂起与恢复

    系列文章 FreeRTOS实时操作系统 一 RTOS的基本概念 FreeRTOS实时操作系统 二 任务创建与任务删除 HAL库 FreeRTOS实时操作系统 三 任务挂起与恢复 FreeRTOS实时操作系统 四 中断任务管理 FreeRTO
  • FreeRTOS之系统配置

    1 FreeRTOS的系统配置文件为FreeRTOSConfig h 在此配置文件中可以完成FreeRTOS的裁剪和配置 在官方的demo中 每个工程都有一个该文件 2 先说一下 INCLUDE 开始的宏 使用 INCLUDE 开头的宏用来
  • FreeRTOS 配置TICK_RATE_HZ

    我使用的是带有 5 4 版 FreeRTOS 的 MSP430f5438 我有一个有趣的问题 我无法弄清楚 基本上 当我将 configTICK RATE HZ 设置为不同的值时 LED 闪烁得更快或更慢 它应该保持相同的速率 我将 con
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥
  • 如何将 void* 转换为函数指针?

    我在 FreeRTOS 中使用 xTaskCreate 其第四个参数 void const 是传递给新线程调用的函数的参数 void connect to foo void const task params void on connect

随机推荐