本文是《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
#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则不需要,故注释掉
void USART1_IRQHandler(void)
{
u32 timeout=0;
u32 maxDelay=0x1FFFF;
HAL_UART_IRQHandler(&UART1_Handler);
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)
{
timeout++;
if(timeout>maxDelay) break;
}
}
9. 修改delay.c文件
打开SYSTEM文件夹里delay.c文件,重新写入所需代码
#include "delay.h"
#include "sys.h"
#if SYSTEM_SUPPORT_OS
#include "FreeRTOS.h" //FreeRTOS使用
#include "task.h"
#endif
static u32 fac_us=0;
#if SYSTEM_SUPPORT_OS
static u16 fac_ms=0;
#endif
extern void xPortSysTickHandler(void);
void SysTick_Handler(void)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
{
xPortSysTickHandler();
}
HAL_IncTick();
}
void delay_init(u8 SYSCLK)
{
u32 reload;
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
fac_us=SYSCLK;
reload=SYSCLK;
reload*=1000000/configTICK_RATE_HZ;
fac_ms=1000/configTICK_RATE_HZ;
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;
SysTick->LOAD=reload;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
}
void delay_us(u32 nus)
{
u32 ticks;
u32 told,tnow,tcnt=0;
u32 reload=SysTick->LOAD;
ticks=nus*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;
}
};
}
void delay_ms(u32 nms)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
{
if(nms>=fac_ms)
{
vTaskDelay(nms/fac_ms);
}
nms%=fac_ms;
}
delay_us((u32)(nms*1000));
}
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(使用前将#替换为@)