提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
最近发现一个很好的嵌入式仿真平台(https://app.puliedu.com/#/),又恰巧在学习freertos。但这个平台上没有在stm32 上移植freertos,遂动手移植了一下。
一、嵌入式仿真平台
平台的详细介绍请参考网址:https://puliedu.com/#/。这个平台支持Arm、RISC V等多种体系结构处理器和100+常用电子模块的组件和手册。开发者可以根据需求搭建电路和编写代码,还可以本地上传代码,很友好。且只要能登陆网页就可使用,非常方便。
二、Freertos源码获取
https://github.com/FreeRTOS/FreeRTOS-Kernel
三、 Freertos移植
由于这个平台编译是使用makefile工程做的,所以先在平台上创建一个rtthread工程,然后将代码下载下来进行修改。如下图:
图1
在图1界面的rtthread项目中任意创建一个示例工程。然后根据图2,所示完成代码下载。
图2
下载后代码目录如下:
图3
接下来,将freertos源码导入进来,具体可参考: https://blog.csdn.net/yufm/article/details/103683863,这篇帖子讲的很详细。
然后就是makefile的修改,图4是我们要修改的部分,图5是修改后的
图4
图5
注:若RTT_SOURCE 改了其他名字,makefile后续引用处同样要做出修改。如图6。
图6
上述为源码路径配置,还要配置下头文件路径。只要将C_INCLUDES下rtthread的路径替换为freertos .h 的路径即可。
图7
图8
最后,要修改下startup_stm32f103xe.s 这个文件,rtthread的主入口为entry,而freertos的入口为main 将该文件102行注释打开,103行屏蔽或删除,如图9
图9
至此,需要修改已全部完成,接下来为测试代码
#include "sys.h"
#include "stm32f10x_conf.h"
#include "delay.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_STK_SIZE 512
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define LED0_TASK_PRIO 2
//任务堆栈大小
#define LED0_STK_SIZE 128
//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数
void led0_task(void *pvParameters);
//任务优先级
#define LED1_TASK_PRIO 3
//任务堆栈大小
#define LED1_STK_SIZE 128
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
int main(void)
{
LED_Init(); //初始化LED
//创建开始任务
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(); //进入临界区
//创建LED0任务
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);
//创建LED1任务
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);
vTaskDelete(StartTask_Handler); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//LED0任务函数
void led0_task(void *pvParameters)
{
while(1)
{
LED0=0;
vTaskDelay(500);
}
}
//LED1任务函数
void led1_task(void *pvParameters)
{
while(1)
{
LED1=0;
vTaskDelay(200);
LED1=1;
vTaskDelay(800);
}
}
led 0和led1 根据需求配置即可。
题外话,https://blog.csdn.net/yufm/article/details/103683863 这个帖子中将几个中断函数直接进行替换,我这里的做法是在FreeRTOSConfig.h中进行了宏替换。