FreeRTOS+STM32F103系列--1.移植
—-Done is better than perfect
1.前言
用了一年多FreeRTOS,感觉还是不能很好的掌握这个系统,可能是自己从来没有认真去研究过它吧!为了不这样含含糊糊的用着,我决定开始深入研究下FreeRTOS,探索它背后的原理,掌握其编程方法,避免其缺陷和陷阱,并将它安全的用在将来的项目中。
先移植个闪灯程序把系统先跑起来,go…
开发板: ALIENTEK战舰STM32开发板
CPU: STM32F103ZET6
FreeRTOS版本: FreeRTOSv9.0.0
编译软件: keil5
2.如何创建一个新的FreeRTOS工程
参考FreeRTOS官网创建一个新工程http://www.freertos.org/Creating-a-new-FreeRTOS-project.html例子。
-
源文件 .c
最小FreeRTOS只需要包含五个文件,分别是tasks.c、queue.c、list.c、port.c、heap_x.c(x是1,2,3,4,5任意选一个)
头文件 .h
需要的头文件路径
FreeRTOS/Source/include
FreeRTOS/Source/portable/[compiler]/[architecture].配置文件 FreeRTOSConfig.h
FreeRTOS官网提供了很多平台演示例程,STM32F103的演示例程也提供了,可以根据下面路径,拷贝一份出来:
FreeRTOSv9.0.0\FreeRTOS\Demo\CORTEX_STM32F103_Keil\FreeRTOSConfig.h安装中断向量
每个RTOS端口都使用一个定时器生成周期性的滴答中断。许多端口使用额外的中断来管理上下文切换。RTOS端口需要的中断请求由RTOS端口源文件提供。
这个部分很重要,我刚开始移植一直失败,最后找到原因就是这部分没有配置好造成的。
看一下FAQ文档
[Cortex-M users: Information on installing interrupt handers is provided in the “The application I created compiles, but does not run” FAQ]
ARMCortex-M用户需要特别注意:ARM Cortex-M3,ARM Cortex-M4,ARM Cortex-M4F ports需要在SysTick,PenSV和SVCCall中断向量上安装FreeRTOS handlers。向量表可以直接使用FreeRTOS定义的xPortSysTickHandler()、xPortPendSVHandler()和vPortSVCHandler()函数来填充,或者,如果中断向量表是符合CMSIS要求,那么可以将下面的三行添加到FreeRTOSConfig.h将FreeRTOS的函数名映射到它们的CMSIS当量:
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
稍后将在启动文件startup_stm32f10x_hd.s做修改
3.STM32需要哪些文件
STM32需要的文件和原来裸机上需要的文件相同。如果做过STM32裸机项目的可以基本照搬过来。
- 库文件: STM32F10x_FWLib
- 启动文件: startup_stm32f10x_hd.s
- CMSIS核心文件: core_cm3.c、core_cm3.h
- system文件: system_stm32f10x.c、system_stm32f10x.h、stm32f10x.h
- 中断相关: stm32f10x_it.c、stm32f10x_it.h
4.Keil工程Blinky
-
项目结构
├─CORE (CM3核心文件)
├─FreeRTOS (FreeRTOSv9.0.0\FreeRTOS\Source下所有文件拷贝过来就行了)
│ ├─include
│ └─portable (保留Keil、MemMang、RVDS,其他文件夹删除)
│ ├─Keil
│ ├─MemMang
│ └─RVDS
│ ├─ARM7_LPC21xx
│ ├─ARM_CA9
│ ├─ARM_CM0
│ ├─ARM_CM3
│ ├─ARM_CM4F
│ ├─ARM_CM4_MPU
│ └─ARM_CM7
│ └─r0p1
├─OBJ (目标生成目录)
├─PRO (工程目录)
├─STM32F10x_FWLib (STM32库函数)
│ ├─inc
│ └─src
└─USER (用户目录)-
Keil工程结构
STM32库函数文件只用到了gpio、rcc只包含这两个就好了,加快编译 Keil包含头文件路径
添加编译宏
STM32F10X_HD,USE_STDPERIPH_DRIVER
记得添加宏不然一堆错误。
-
Keil工程结构
5.修改启动文件 startup_stm32f10x_hd.s
根据Cortex-M3权威指南(中文).pdf中断和异常介绍
Cortex-M3提供了16个内部异常中断源,前文讲了“ARMCortex-M用户需要特别注意:ARM Cortex-M3,ARM Cortex-M4,ARM Cortex-M4F ports需要在SysTick,PenSV和SVCCall中断向量上安装FreeRTOS handlers”。将启动文件中SysTick,PenSV和SVCCall对应的三个回调函数替换成FreeRTOS提供回调函数。
替换SVC_Handler 为vPortSVCHandler
替换PendSV_Handler为xPortPendSVHandler
替换SysTick_Handler为xPortSysTickHandler
这三个中断处理函数包含在port.c里。
因为这三个函数是引用外部函数所以要先包含进去:
6.代码实现
程序说明:创建一个任务用来闪烁LED灯。
#include "FreeRTOS.h"
#include "task.h"
/* Library includes. */
#include "stm32f10x.h"
void vLED_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 输出高
}
void vLed0_task(void *pvParameters)
{
while(1) {
GPIO_SetBits(GPIOB,GPIO_Pin_5);
vTaskDelay(500 / portTICK_PERIOD_MS);
GPIO_ResetBits(GPIOB,GPIO_Pin_5);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
int main(void)
{
vLED_Init();
//创建开始任务
xTaskCreate(vLed0_task, "led0_task", configMINIMAL_STACK_SIZE, NULL, 3, NULL);
vTaskStartScheduler(); //开启任务调度
return 0;
}
编译、下载即可看到LED灯闪烁,最简单的FreeRTOS就移植成功了。
7.总结
摸索了几个小时终于在STM32上运行起来FreeRTOS了,开始移植老是失败,对比Demo程序也没有发现错误所在,后来研究了下Cortex-M3权威指南(中文).pdf中断向量表介绍再对比了一下移植程序终于知道问题所在,原来是中断向量表没有配置对,配置过后问题迎刃而解。
FreeRTOS在STM32移植还是比较容易的,如果做过裸机程序直接把工程照搬过来,把FreeRTOS内核拷贝过来,将FreeRTOS源文件和头文件添加到工程中,修改STM32启动文件,工程就顺利跑起来了。
移植成功了,接下来可以探索它背后的原理了。特意移植了一个最精简的工程,方便后面分析启动原理和代码分析。
【代码链接】
8.参考资料
【FreeRTOS官网】
【Cortex-M3权威指南(中文).pdf】
上一篇: 【STM32】PWM程序
下一篇: FreeRTOS MPU模块学习笔记
推荐阅读
-
FreeRTOS+STM32F103系列--1.移植
-
微服务系统架构设计系列 - RateLimiter - 1. 限流器简介与一般算法
-
1.翻译:EF基础系列--什么是Entity Framework?
-
NET Framework项目移植到NET Core上遇到的一系列坑(2)
-
1.翻译:EF基础系列--什么是Entity Framework?
-
C# 数据操作系列 - 1. SQL基础操作
-
1.安装VS2015 --- OpenCV从零开始到图像(人脸 + 物体)识别系列
-
MyBatis系列目录--1. MyBatis快速接入
-
NET Framework项目移植到NET Core上遇到的一系列坑(2)
-
DBA基础系列SQL Server 2014:1. SQL Server 安装部署(独立部署、非域环境)