网站收录,网站开发语言手册,大连建设监察执法网站,中国企业网是什么级别的媒体[TOC](3.1 FreeRTOS详细移植步骤(自己的实操)) 自己使用阿波罗F767的内存管理实验和定时器实验#xff0c;进行复刻。 FreeRTOS源码版本是FreeRTOS 202212.01。官网和Github都有下载。 按照STM32F767FreeRTOS开发手册V1.1进行移植复刻。 注:这个开发手册不是开发指南。跟视频里…[TOC](3.1 FreeRTOS详细移植步骤(自己的实操)) 自己使用阿波罗F767的内存管理实验和定时器实验进行复刻。 FreeRTOS源码版本是FreeRTOS 202212.01。官网和Github都有下载。 按照STM32F767FreeRTOS开发手册V1.1进行移植复刻。 注:这个开发手册不是开发指南。跟视频里用的教程开发手册有出入。 新建FreeRTOS的工程方法可以分为 1、CubeMX生成带FreeRTOS的HAL库工程。CSDN有一篇文章介绍简单 2、已有HAL库的基础工程将FreeRTOS移植进该工程。步骤复杂 3、已有标准固件库的基础工程将FreeRTOS移植进该工程。步骤复杂
本文记录“已有HAL库的基础工程将FreeRTOS移植进该工程”的方法。 计划完成FreeRTOS基础工程移植后 再完成“任务创建与恢复”实验看看代码的含义。 完成后续视频中的实验。 由于没有开发板实验只编程没有报错即可不看实验现象。 虽然是一种不好的学习方法 1 准备
1 阿波罗F767的内存管理实验 作为基础工程 2 阿波罗F767的定时器实验 用到里面的设备驱动代码 3 FreeRTOS源码 官网或github下载。2.24.5.24下载的是V202212.01版本。
4可选 正点原子的“FreeRTOS移植实验”这个是移植完成的工程可当作参考。 没找到HAL的FreeRTOS工程。只有固件库的FreeRTOS工程可按照教程修改使之支持HAL 库。
2 移植
2.1 STM32F7xx_DFP
keil5编辑STM32F系列的工程时需要添加STM32F7xx_DFP的packCSDN上已记录添加步骤。
2.2 建立基础工程
使用内存管理实验作为基础工程。 将内存管理实验复制一份并命名为“FreeRTOS_Demo”。
修改名字非必须并编译。 会发现0error0warning。
2.3 FreeRTOS源码文件处理
2.3.1 源码文件解压
略
2.3.2 源码文件简化
源码解压后的文件夹是FreeRTOSv202212.01找到其中的Source文件夹是各源码文件有一些文件用不到所以就删了。 有以上绿色下划线的五个文件FreeRTOS就可以用起来了。 不用其他功能对应的.c文件可不添加。 这里就全部保留了。 再将portable文件夹中的文件进行删除。 只留下下面三个文件夹用其他编辑器或MCU根据实际情况选择留下的文件夹
2.4 添加FreeRTOS源码文件
将FreeRTOS源码文件添加至工程。过程简单不再展示图片。 第一步在基础工程中新建一个名为 FreeRTOS 的文件夹。
第二步将Source文件夹下的所有源码文件复制进第一步新建的文件夹中。
第三步在keil中新建两个“分组”分别是 FreeRTOS_CORE和FreeRTOS_PORTABLE。 新建分组不等于新建文件夹。 第四步在keil中为 FreeRTOS_CORE添加c文件
添加完成后
第五步在keil中为FreeRTOS_PORTABLE添加c文件 这个分组中添加两个文件port.c和heap_4.c。 port.c与所用的芯片有关这个选用了STM32F767所以要选择RVDS文件夹下的ARM_CM7中的port.c文件。 heap_4.c是内存管理算法选择MemMang文件夹下的heap_4.c文件。 添加完成后如下图。
第六步添加头文件路径 在上两步中添加了c文件还要添加FreeRTOS的头文件路径要不keil找不到头文件会报错。
完成以上六步后点击编译会报错提示没有“FreeRTOSConfig.h”配置文件。 所以进行2.5小节。
2.5 添加FreeRTOS配置文件
FreeRTOSConfig.h是一个配置文件在这个文件中通过宏定义完成对系统功能的配置和裁剪。共有三个方法。推荐第三种。 方法一自己创建并编写。 略 方法二从官方demo中移植。 在官方demo中找到针对F7的KEIL工程。
上面的文件夹中即可找到FreeRTOSConfig.h配置文件。 Cortex就是ARM公司一个系列处理器的名称。 比如英特尔旗下处理器有酷睿奔腾赛扬。 ARM在最初的处理器型号都用数字命名最后一个是ARM11系列在应用ARMv7架构后推出了Cortex这一系列老式的则命名为Classic系列。 其中“A”系列面向尖端的基于虚拟内存的操作系统和用户应用“R”系列针对实时系统“M”系列对微控制器。 方法三从“FreeRTOS移植实验”中获取推荐 从正点原子的“FreeRTOS移植实验”中获取带注释的配置文件更方便学习。 在扩展例程中找到该实验。
找到后将文件复制粘贴到移植工程中FreeRTOS文件夹下的Include中放在USER下也行灵活点这样就不需要再添加“头文件路径”了。
此时再编译工程仍会报错。 按照下面的步骤继续进行修改逐渐的消除错误信息完成移植。
2.6 修改system文件
修改其中的sys.hdelay.cuart.c三个文件。 这三个文件大部分是针对UCOS的所以要进行修改。 使之支持FreeRTOS。
2.6.1 修改sys.h文件
打开sys.h文件 使用了FreeRTOS所以将SYSTEM_SUPPORT_OS修改为1。
//0,不支持os
//1,支持os
#define SYSTEM_SUPPORT_OS 1 //定义系统文件夹是否支持OS2.6.2 修改uart.c文件
有两部分需要进行修改 第一部分添加FreeRTOSConfig.h头文件 默认添加的是UCOS的“includes.h”头文件将其删除添加为“FreeRTOSConfig.h”的头文件。
//如果使用os,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
//#include includes.h //UCOS 使用
#include FreeRTOSConfig.h //FreeRTOS使用
#endif
第二部分修改USART1的中断服务函数 uart.c文件默认支持UCOS的UCOS进出中断时需要添加OSIntEnter()和 OSIntExit()使用 FreeRTOS 的话就不需要了所以将这两行代码删除掉。 看了下本工程的uart.c文件中该代码用了条件编译。如下。
#if SYSTEM_SUPPORT_OS //使用OSOSIntEnter();
#endif所以直接删除也行宏前面加个叹号也行。 这里直接删除。 重新学习一下宏定义看看#if和#ifdef的区别是什么 删除后的代码为
//串口1中断服务程序 FreeRTOS
void USART1_IRQHandler(void)
{ u32 timeout0;u32 maxDelay0x1FFFF;HAL_UART_IRQHandler(UART1_Handler); //调用HAL库中断处理公用函数timeout0;while (HAL_UART_GetState(UART1_Handler)!HAL_UART_STATE_READY)//等待就绪{timeout;超时处理if(timeoutmaxDelay) break; }timeout0;while(HAL_UART_Receive_IT(UART1_Handler,(u8 *)aRxBuffer, RXBUFFERSIZE)!HAL_OK)//一次处理完成之后重新开启中断并设置RxXferCount为1{timeout; //超时处理if(timeoutmaxDelay) break; }}
注意在我这里用的这个例程中USART1的中断服务函数是针对UCOS的即使删除了OSIntEnter()和 OSIntExit()也可能不对。 但在下方有一个被注释的USART1中断服务函数这个是针对FreeRTOS的。就是上面删除后的代码。这段代码也是跟指南中的代码一致的 所以一定要跟上面的代码对应。 还可以将上面的代码复制对“USART1的中断服务函数”进行替换。
2.6.3 修改delay.c文件
同理delay.c文件中的程序是支持UCOS的经过对比发现不适合将程序修改后适配FreeRTOS所以将delay.c文件的代码全部删除然后将固件库的“FreeRTOS移植实验”delay.c文件代码复制过来。复制过来之后再稍作修改使之支持HAL库。
因为delay.c文件涉及到 FreeRTOS 的系统时钟所以修改比较大。 delay.c文件中有5个函数将所以的代码复制经过修改后支持HAL的FreeRTOS中的delay.c代码如下。 以后使用时直接将下面的代码复制到delay.c中即可。 注意倒数第二个函数void delay_ms(u32 nms)形参改变了需要在.h中重新声明一下。 #include delay.h
#include sys.h
//
//如果使用OS,则包括下面的头文件即可
#if SYSTEM_SUPPORT_OS
#include FreeRTOS.h //FreeRTOS使用
#include task.h
#endif
//
//使用SysTick的普通计数模式对延迟进行管理(支持OS)
//包括delay_us,delay_ms
//********************************************************************************static u8 fac_us0; //us延时倍乘数
static u16 fac_ms0; //ms延时倍乘数,在os下,代表每个节拍的ms数extern void xPortSysTickHandler(void);//systick中断服务函数,使用OS时用到
void SysTick_Handler(void)
{ if(xTaskGetSchedulerState()!taskSCHEDULER_NOT_STARTED)//系统已经运行{xPortSysTickHandler(); }HAL_IncTick();
}//初始化延迟函数
//当使用FreeRTOS时此函数会初始化FreeRTOS的时钟节拍。
//SYSTICK的时钟固定为AHB时钟基础例程里面SYSTICK时钟频率为AHB/8
//这里为了兼容FreeRTOS所以将SYSTICK的时钟频率改为AHB的频率
//SYSCLK:系统时钟频率
void delay_init(u8 SYSCLK)
{u32 reload;//SysTick 频率为 HCLKHAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);fac_usSYSCLK; //不论是否使用OS,fac_us都需要使用reloadSYSCLK; //每秒钟的计数次数 单位为M reload*1000000/configTICK_RATE_HZ; //根据configTICK_RATE_HZ设定溢出时间//reload为24位寄存器,最大值:16777216,在168M下,约合0.0998s左右 fac_ms1000/configTICK_RATE_HZ; //代表OS可以延时的最少单位 SysTick-CTRL|SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断SysTick-LOADreload; //每1/configTICK_RATE_HZ断一次 SysTick-CTRL|SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
} //延时nus
//nus:要延时的us数.
//nus:0~204522252(最大值即2^32/fac_usfac_us168)
void delay_us(u32 nus)
{ u32 ticks;u32 told,tnow,tcnt0;u32 reloadSysTick-LOAD; //LOAD的值 ticksnus*fac_us; //需要的节拍数 toldSysTick-VAL; //刚进入时的计数器值while(1){tnowSysTick-VAL; if(tnow!told){ if(tnowtold)tcnttold-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.else tcntreload-tnowtold; toldtnow;if(tcntticks)break; //时间超过/等于要延迟的时间,则退出.} };
}
//延时nms 会引起任务调度
//nms:要延时的ms数
//nms:0~65535
void delay_ms(u32 nms)
{ if(xTaskGetSchedulerState()!taskSCHEDULER_NOT_STARTED)//系统已经运行{ if(nmsfac_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(i0;inms;i) delay_us(1000);
}
修改完成后点击编译。
2.7 修改中断相关文件
编译后会报错
这三个函数在port.c和stm32f7xx_it.c中被多次定义了。 所以选在将stm32f7xx_it.c中的这三个函数注释掉。 用条件编译注释掉如下
#if (!SYSTEM_SUPPORT_OS)
void SVC_Handler(void)
{
}
#endif注意SYSTEM_SUPPORT_OS这个宏在sys.h中所以要在stm32f7xx_it.c包含这个头文件。
完成后再点击编译。
2.8 小节
编译后没有错误。 但是还需要编写应用程序进行验证。 移植步骤大体就是这样。 看开发手册中不同芯片还会有其他错误等实际遇到时再去改吧。
2.9 验证移植是否成功
需要编写应用程序。