准备工作
- FreeRTOS系统源码
- 基础工程,这里我们用跑马灯实验
1.在工程里面添加FreeRTOS源码
在工程里面新建一个名为FreeROTS的文件夹 将FreeRTOS源码添加到这个文件夹里面 protable里面只需留下Keil、MemMang、RVDS文件夹
2、向工程分组中添加文件
FreeRTOS_CORE的文件在FreeRTOS源码的首目录下,FreeRTOS_PORTABLE的port.c在RVDS文件夹下的ARM_CM4F中,heap_4.c在MenMang中,是内存管理方法
3、添加相应的头文件路径
4、添加FreeRTOSConfig.h文件
放在include文件夹下,这个文件官方的例程有,是FreeRTOS的配置文件 打开FreeRTOSConfig.h文件,修改下图代码为
#if defined(__ICCARM__) || defined(__CC_ARM ) || defined (__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
4、屏蔽port.c和stmf32f4xx_it.c重复定义的函数
void PendSV_Handler(void)
void SysTick_Handler(void)
void PPP_IRQHandler(void)
5、修改system文件
5.1 sys.h
SYSTEM_SUPPORT_OS修改成1
#define SYSTEM_SUPPORT_OS 1
5.2 usart.c
修改成以下内容
#include "usart.h"
#include "delay.h"
#if SYSTEM_SUPPORT_OS
#include "FreeRTOS.h"
#endif
#if 1
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);
USART1->DR = (u8) ch;
return ch;
}
#endif
#if EN_USART1_RX
u8 USART_RX_BUF[USART_REC_LEN];
u16 USART_RX_STA=0;
u8 aRxBuffer[RXBUFFERSIZE];
UART_HandleTypeDef UART1_Handler;
void uart_init(u32 bound)
{
UART1_Handler.Instance=USART1;
UART1_Handler.Init.BaudRate=bound;
UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;
UART1_Handler.Init.StopBits=UART_STOPBITS_1;
UART1_Handler.Init.Parity=UART_PARITY_NONE;
UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;
UART1_Handler.Init.Mode=UART_MODE_TX_RX;
HAL_UART_Init(&UART1_Handler);
HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);
}
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_Initure;
if(huart->Instance==USART1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
GPIO_Initure.Pin=GPIO_PIN_9;
GPIO_Initure.Mode=GPIO_MODE_AF_PP;
GPIO_Initure.Pull=GPIO_PULLUP;
GPIO_Initure.Speed=GPIO_SPEED_FAST;
GPIO_Initure.Alternate=GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_10;
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
#if EN_USART1_RX
HAL_NVIC_EnableIRQ(USART1_IRQn);
HAL_NVIC_SetPriority(USART1_IRQn,3,3);
#endif
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART1)
{
if((USART_RX_STA&0x8000)==0)
{
if(USART_RX_STA&0x4000)
{
if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;
else USART_RX_STA|=0x8000;
}
else
{
if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;
}
}
}
}
}
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;
}
}
#endif
5.3 delay.c
修改成以下内容
#include "delay.h"
#include "sys.h"
#if SYSTEM_SUPPORT_OS
#include "FreeRTOS.h"
#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);
}
编译一下,如果没有错误就可以了
测试
main.c文件内容如下
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#define START_TASK_PRIO 1
#define START_STK_SIZE 128
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);
#define LED0_TASK_PRIO 2
#define LED0_STK_SIZE 50
TaskHandle_t LED0Task_Handler;
void led0_task(void *pvParameters);
#define LED1_TASK_PRIO 3
#define LED1_STK_SIZE 50
TaskHandle_t LED1Task_Handler;
void led1_task(void *pvParameters);
#define FLOAT_TASK_PRIO 4
#define FLOAT_STK_SIZE 128
TaskHandle_t FLOATTask_Handler;
void float_task(void *pvParameters);
int main(void)
{
HAL_Init();
Stm32_Clock_Init(360,25,2,8);
delay_init(180);
LED_Init();
uart_init(115200);
xTaskCreate((TaskFunction_t )start_task,
(const char* )"start_task",
(uint16_t )START_STK_SIZE,
(void* )NULL,
(UBaseType_t )START_TASK_PRIO,
(TaskHandle_t* )&StartTask_Handler);
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL();
xTaskCreate((TaskFunction_t )led0_task,
(const char* )"led0_task",
(uint16_t )LED0_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED0_TASK_PRIO,
(TaskHandle_t* )&LED0Task_Handler);
xTaskCreate((TaskFunction_t )led1_task,
(const char* )"led1_task",
(uint16_t )LED1_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED1_TASK_PRIO,
(TaskHandle_t* )&LED1Task_Handler);
xTaskCreate((TaskFunction_t )float_task,
(const char* )"float_task",
(uint16_t )FLOAT_STK_SIZE,
(void* )NULL,
(UBaseType_t )FLOAT_TASK_PRIO,
(TaskHandle_t* )&FLOATTask_Handler);
vTaskDelete(StartTask_Handler);
taskEXIT_CRITICAL();
}
void led0_task(void *pvParameters)
{
while(1)
{
LED0=~LED0;
vTaskDelay(500);
}
}
void led1_task(void *pvParameters)
{
while(1)
{
LED1=0;
vTaskDelay(200);
LED1=1;
vTaskDelay(800);
}
}
void float_task(void *pvParameters)
{
static float float_num=0.00;
while(1)
{
float_num+=0.01f;
printf("float_num的值为: %.4f\r\n",float_num);
vTaskDelay(1000);
}
}
编译,将程序烧录到开发板中,可以发现LED0、LED1闪烁,移植成功
|