本实验使用正点原子的F103精英开发板进行
使用蜂鸣器实验作为模板进行移植
在FreeRTOS官方网站(www.freertos.org)下载源码并解压
删除delay文件夹,FreeRTOS中有延时函数了
创建FreeRTOS文件夹
将source中的文件全部复制到FreeRTOS中
删除其余文件,只留下上图中的文件
工程中添加上列文件,其中port.c在ARM_CM3中,如下图所示:
添加编译路径,然后编译
报错:找不到FreeRTOSConfig.h文件
在源文件demo中找到对应文件,复制到include路径下,编译
sys.h文件夹中设置使用操作系统
`
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
在usart.c文件中作相应修改
测试:
在main.c中加入以下代码
#include "sys.h"
#include "led.h"
#include "beep.h"
#include "FreeRTOS.h"
#include "task.h"
void LED_task(void *pvParameters)
{
while(1)
{
LED0=1;
vTaskDelay(1000);
LED0=0;
vTaskDelay(1000);
}
}
void BEEP_task(void *pvParameters)
{
while(1)
{
BEEP=1;
vTaskDelay(500);
BEEP=0;
vTaskDelay(500);
}
}
int main(void)
{
LED_Init(); //初始化与LED连接的硬件接口
BEEP_Init(); //初始化蜂鸣器端口
xTaskCreate(LED_task,"1",1024,NULL,2,NULL);
xTaskCreate(BEEP_task,"2",1024,NULL,2,NULL);
vTaskStartScheduler(); //开启任务调度
}
但是任务并没有执行,调试发现任务进入了:
解决办法:
在FreeRTOSConfig.h文件中加入:
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler
屏蔽stm32f10x_it.c文件中如下代码:
原因:
PendSV_Handler、SVC_Handler、SysTick_Handler是三个重要的中断处理程序。其中,SysTick_Handler是系统定时器中断服务程序,用于定时器中断的处理;PendSV_Handler是用于任务切换的中断服务程序;SVC_Handler是用于系统调用的中断服务程序。
FreeRTOS已经实现了这三个函数,而且这三个函数与程序原有的函数重名。因此,需要注释掉原有的函数,并添加宏定义来使用FreeRTOS提供的这三个函数.
重新编译下载程序,任务成功执行