freertos移植笔记

环境:keil5;
平台:STM32F103;
freertos源码:FreeRTOSv9.0.0版本
移植前准备:自己新建一个工程,用于freertos移植基础;

一:打开基础工程,确保基础工程编译没错;

在这里插入图片描述

二:在基础工程目录下新建“FreeRtos”文件夹,用于存放freertos相关文件;

在这里插入图片描述

三:在"FreeRtos"目录下新建“include”和“portable”文件夹,用于存放freertos头文件和接口文件;

在这里插入图片描述

四:添加源码;

①:找到官网下载的源码,找到“FreeRTOSv9.0.0\FreeRTOS\Source\include”目录下的头文件,全部复制到我们第三步新建的“include”文件夹下;
在这里插入图片描述
②:复制“Memmang”和“RVDS”文件到我们第三步新建的“portable”文件夹中,然后再 裁剪文夹容(F103是M3的内核,所以RVDS文件下 可以只要“ARM_CM3”的文件);
在这里插入图片描述
③:将“\FreeRTOSv9.0.0\FreeRTOS\Source”目录下的“.c”文件复制到我们自己建 的“FreeRtos”目录下;
在这里插入图片描述
④:到freertos官方源码下的Demo目录下找到我们的F103_keil工程,找到“FreeRtosconfig…h”文件,将这个文件复制到我们的“USER”目录下(也可以找到野火或者正点原子的头文件,里面注释分类都做的比较完善);
在这里插入图片描述

五:在工程中添加文件;

①:在工程中添加分组,并添加文件到分组;
在这里插入图片描述
在这里插入图片描述

②:添加路径;
在这里插入图片描述
③:编译测试看是否通过;
在这里插入图片描述

六:测试移植是否成功;

①:打开"FreeRtosconfig.h"文件添加SVC和pendsv中断宏定义,不然port.c中的函数无法找到中断(如果此时在“USER”目录下找不到"FreeRtosconfig.h"文件,则手动添加文件到“USER”目录中);

#define xPortPendSVHandler  PendSV_Handler
#define vPortSVCHandler     SVC_Handler

在这里插入图片描述

②:修改stm32f10x_it.c文件:屏蔽svc和pend中断,修改滴答定时器中中断,添加头文件;

//在stm32f10x_it.c添加头文件
#include "FreeRTOS.h"
#include "task.h"
.....

//修改滴答定时器中断
extern void xPortSysTickHandler(void);
void SysTick_Handler(void)
{	
	if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
	{
		xPortSysTickHandler();
	}
}

在这里插入图片描述

③:编译查看提示,显示未定义函数,修改宏定义即可;

#define INCLUDE_xTaskGetSchedulerState 1//将宏值改为1

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

④:新建任务,在开发板上通过两个led的闪烁间隔不同判断移植是否成功;
结果:本实验在开发板上可以看到LED0现象为500ms亮一次,LED1为一秒钟亮一次,实验表明移植成功;
逻辑分析仪抓取截图:
在这里插入图片描述

#include "stm32f10x.h"
#include "FreeRTOS.h"
#include "task.h"

#define TASK1_PRIO 1 //任务优先级
#define TASK1_STK_SIZE 128 //任务堆栈大小
TaskHandle_t StartTask_Handler; //任务句柄
void task1(void *pvParameters); //任务函数

#define TASK2_PRIO 1 //任务优先级
#define TASK2_STK_SIZE 128 //任务堆栈大小
TaskHandle_t StartTask2_Handler; //任务句柄
void task2(void *pvParameters); //任务函数

volatile uint8_t task1_flag=0;
volatile uint8_t task2_flag=0;
void LED_Init(void);

int main(void)
{
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	 //初始化io口
	 LED_Init();

	 //创建开始任务
	 xTaskCreate((TaskFunction_t )task1, //任务函数
	 (const char* )"task11", //任务名称
	 (uint16_t )TASK1_STK_SIZE, //任务堆栈大小
	 (void* )NULL, //传递给任务函数的参数
	(UBaseType_t )TASK1_PRIO, //任务优先级
 	(TaskHandle_t* )&StartTask_Handler); //任务句柄


	 xTaskCreate((TaskFunction_t )task2, //任务函数
	 (const char* )"task22", //任务名称
	 (uint16_t )TASK2_STK_SIZE, //任务堆栈大小
	 (void* )NULL, //传递给任务函数的参数
	 (UBaseType_t )TASK2_PRIO, //任务优先级
	 (TaskHandle_t* )&StartTask2_Handler); //任务句柄


	vTaskStartScheduler();
	 while(1)
	 {

	 }
}


 //task2任务LED0(PB5)每500ms亮一次
 void task1(void *pvParameters)
 {
	 while(1)
	 {
		 task1_flag=1;
	  	 GPIOB‐>BRR=GPIO_Pin_5;//LED0亮
		 vTaskDelay(500);
		 task1_flag=0;
	 	 GPIOB‐>BSRR=GPIO_Pin_5;//LED0灭
		 vTaskDelay(500);
	 }
 }

 //task2任务LED1(PE5)每一秒钟亮一次
 void task2(void *pvParameters)
 {
	while(1)
	 {
		 task2_flag=1;
		GPIOE‐>BSRR=GPIO_Pin_5;//LED1灭
		vTaskDelay(1000);
		task2_flag=0;
		GPIOE‐>BRR=GPIO_Pin_5;//LED1亮
		vTaskDelay(1000);
	 }
 }


//初始化PB5和PE5为输出口.并使能这两个口的时钟
//LED IO初始化
void LED_Init(void)
{
 	GPIO_InitTypeDef GPIO_InitStructure;

 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE端口时钟

 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0‐‐>PB.5 端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
 	GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
 	GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1‐‐>PE.5 端口配置, 推挽输出
	GPIO_Init(GPIOE, &GPIO_InitStructure); //推挽输出 ,IO口速度为50MHz
	GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高 
}

七:注意事项;

我刚开始准备在keil中用keil自带的模拟器验证移植是否成功,但是可能由于自己新建工程有些许瑕疵,遇到了如下问题,记录如下:
①:新建工程时编译有问题,报错提示:“…/CMSIS/core_cm3.c(445): error: non-ASM statement in naked function is not supported”
原因:KEIL5版本更新了的缘故,使用了keil5默认的版本6的编译器,而固件库还 是支持版本5的编译器;
解决方法:将编译器修改成版本5就好了;
在这里插入图片描述

②:移植好freertos后,采用keil软件方式模拟,代码一直卡在“SetSysClockTo72”,运行不到main函数处;
原因:KEIL中DEBUG设置不对;
解决方法:
在这里插入图片描述

③:当更改DEBUG选项后测试,发现调试时一直报错:“*** error 65: access violation at 0x0000000C : no ‘read’ permission”
解决方法:
Option->Debug->Use_Simulator->Initialization_File,打开并新建一个.ini文件,里面写上map 0x40000000,0x400FFFFF read write保存即可(MAP不区分大小写,注意read和write中间是空格不是逗号),然后运行DEBUG就可以了,我按照此方法报错问题就解决了。
参考了解:https://blog.youkuaiyun.com/Maple_Leaf_15/article/details/51057991
④:当可以正常软件仿真时,打断点发现代码一直可以运行到task1和task2处,但是keil自带的逻辑分析仪上却没有变量的波形,这个问题目前也没有解决,但是在板子上跑现象是正常的,逻辑分析仪抓取也是正常的,所以可能是我自己建的工程有瑕疵,导致软件仿真的逻辑分析仪有问题。

本文章是记录自己的学习记录·,方便后续自己复习。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值