目录
1、准备工作
1.1、准备基础工程
要移植 FreeRTOS,肯定需要一个基础工程,基础工程越简单越好,这里我们就用基础例程
中的跑马灯实验来作为基础工程。
1.2、FreeRTOS系统源码
要找资料,官网是最好的地方,FreeRTOS的官网是www.freertos.org。
进入 FreeRTOS 首页,就会看到download下载链接,进入后下载“FreeRTOSv9.0.0.exe”文件,下载完成后双击运行,下载源码到指定目录。
1.3、开发板准备
野火指南者,芯片为STM32F103ZET6。
2、移植工作
2.1、向工程中添加相应文件
1、添加FreeRTOS源码
在基础工程中新建一个名为 FreeRTOS 的文件夹,如下图所示:
创建 FreeRTOS 文件夹以后就可以将 FreeRTOS 的源码添加到这个文件夹中,添加完以后
如下图所示:
portable 文件夹,我们只需要留下 keil、MemMang 和 RVDS 这三个文件夹,其他的都可以删除掉,完成以后如下图所示:
2、 向工程分组中添加文件
打开基础工程,新建分组 FreeRTOS_CORE 和 FreeRTOS_PORTABLE,然后向这两个分组
中添加文件,如下图所示:
分组 FreeRTOS_CORE 中的文件在什么地方就不说了,打开 FreeRTOS 源码一目了然。重
点来说说 FreeRTOS_PORTABLE 分组中的 port.c 和 heap_4.c 是怎么来的,port.c 是 RVDS 文件
夹下的 ARM_CM3 中的文件,因为 STM32F103 是 Cortex-M3 内核的,因此要选择 ARM_CM3
中的 port.c 文件。heap_4.c 是 MemMang 文件夹中的,前面说了 MemMang 是跟内存管理相关
的,里面有 5 个 c 文件:heap_1.c、heap_2.c、heap_3.c、heap_4.c 和 heap_5.c。这 5 个 c 文件是五种不同的内存管理方法,就像从北京到上海你可以坐火车、坐飞机,如果心情好的话也可以
走路,反正有很多种方法,只要能到上海就行。这里也一样的,这 5 个文件都可以用来作为
FreeRTOS 的内存管理文件,只是它们的实现原理不同,各有利弊。这里我们选择 heap_4.c,至
于原因,后面会有一章节专门来讲解 FreeRTOS 的内存管理,到时候大家就知道原因了。这里
就先选择 heap_4.c,毕竟本章的重点是 FreeRTOS 的移植。
3、添加相应的头文件路径
添加完 FreeRTOS 源码中的 C 文件以后还要添加 FreeRTOS 源码的头文件路径,头文件路
径如下图所示:
头文件路径添加完成以后编译一下,看看有没有什么错误,结果会发现提示打不开
“FreeRTOSConfig.h”这个文件,如下图所示:
这是因为缺少 FreeRTOSConfig.h 文件,这个文件在哪里找呢?你可以自己创建,显然这不
是一个明智的做法。我们可以找找 FreeRTOS 的官方移植工程中会不会有这个文件,打开
FreeRTOS 针对 STM32F103 的移植工程文件,文件夹是 CORTEX_STM32F103_Keil,打开以后
如下图所示:
果然!官方的移植工程中有这个文件,我们可以使用这个文件,但是建议大家使用我们例
程中的 FreeRTOSConf.h 文件,这个文件是 FreeRTOS 的系统配置文件,不同的平台其配置不同。这个文件复制到什么地方大家可以自行决定,这里我为了方便放到了 FreeRTOS 源码中的 include 文件夹下。
FreeRTOSConfig.h 是何方神圣?看名字就知道,他是 FreeRTOS 的配置文件,一般的操作系统都有裁剪、配置功能,而这些裁剪及配置都是通过一个文件来完成的,基本都是通过宏定
义来完成对系统的配置和裁剪的,关于 FreeRTOS 的配置文件 FreeRTOSConfig.h 后面也会有一
章节来详细的讲解。
到这里我们再编译一次,没有错误!如下图所示:
2.2、修改配置
在FreeRTOSConfig.h中添加
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
在stm32f10x_it.c中屏蔽PendSV_Handler和SVC_Handler中断
最关键的一部,修改stm32f10x_it.c中的systick中断服务函数。
/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
extern void xPortSysTickHandler(void);
void SysTick_Handler(void)
{
#if (INCLUDE_xTaskGetSchedulerState == 1 )
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
#endif /* INCLUDE_xTaskGetSchedulerState */
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
}
#endif /* INCLUDE_xTaskGetSchedulerState */
}
3、验证DEMO
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
//ALIENTEK Mini STM32开发板范例代码3
//串口实验
//技术支持:www.openedv.com
//广州市星翼电子科技有限公司
void task1_fun(void *pvParameters);
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
uart_init(9600); //串口初始化为9600
LED_Init(); //初始化与LED连接的硬件接口
xTaskCreate( task1_fun,
"TASK1",
1000,
NULL,
0,
NULL);
/* Start the scheduler. */
vTaskStartScheduler();
for(;;){}
}
void task1_fun(void *pvParameters)
{
for(;;)
{
led1_ctrl(0);
vTaskDelay(500/portTICK_PERIOD_MS);
led1_ctrl(1);
vTaskDelay(500/portTICK_PERIOD_MS);
}
}
如果还有错误的话大家自行根据错误类型查找和修改错误!