FreeRTOS移植及STM32下基于FreeRTOS的程序编写


前言

FreeRTOS可以拆分成两个部分来看。Free:就是免费的;RTOS的全称是Real Operating System,中文名就是实时操作系统,所以FreeRTOS其实就是一个免费的实时类的操作系统。FreeRTOS是RTOS系统的一种,FreeRTOS十分的小巧,可以在资源有限的微控制器中运行,当然了 FreeRTOS不仅局限于在微控制器中使用。
本篇博客是STM32下基于FreeRTOS的多任务程序,使用到的板子是正点原子的STM32f103精英版。


FreeRTOS移植

tips:其实很多商家已经完成了FreeRTOS的移植工作,比如正点原子家的板子就直接有已经完成移植的代码。
这里博主也自己完成了一次FreeRTOS的移植。如果你也想自己实操一次,就可以跟着博主继续本内容;如果你想直接进入多任务程序,请下滑到下一个大标题中。^ _ ^

准备工作

首先需要下载FreeRTOS的源码

FreeRTOS的源码可以在官网下载。如果你买的是正点原子的板子,问商家给的资料里面应该也有FreeRTOS的源码(软件资料 ->14FreeRTOS学习资料 ->FreeRTOS源码)。

然后还需要一个Keil5的基础工程(越简单越好)

可以准备一个跑马灯的工程(在Keil5环境下),在此就不再赘述跑马灯的工程了。跑马灯程序打开的初始工程界面如下图所示:
在这里插入图片描述

移植

新建FreeRTOS的文件夹

在基础工程中新建一个名为 FreeRTOS的文件夹,在文件夹中添加我们需要的FreeRTOS源码。需要的文件都可以在FreeRTOS源码中找到,需要的文件如下图所示(其中,portable文件夹中,我们只需要 留下keil、MemMang和RVDS这三个文件夹,其他的都可以删除掉):
在这里插入图片描述
将所需要的文件复制到新建的文件夹中即可。
同时,工程目录中也需要添加新的文件夹和文件,所需要添加的如下图所示:
在这里插入图片描述

添加路径

打开准备好的基础工程,点击目标工程,添加头文件的路径,如下图所示:
在这里插入图片描述
点击Include Paths后面的三个点,选择所需要添加的路径,所添加的路径如下图所示:
在这里插入图片描述
注意:这些文件都是在本工程下的哦~不要添加路径添加到了从官网上下载的FreeRTOS源码中。
出现问题:若此时对程序进行编译是可以通过的,但是构建时就会出现错误,出现的错误提示是找不到“FreeRTOSConfig.h”头文件。
在这里插入图片描述
分析原因:这是由于后面添加的文件中调用了“FreeRTOSConfig.h”这个头文件,但是在添加的路径中找不到这个头文件。
解决问题:找遍了添加的文件中,发现是没有“FreeRTOSConfig.h”的。再在官网上面下载的源码中找到了“FreeRTOSConfig.h”文件。

添加配置文件

在FreeRTOS的源码路径中有“FreeRTOSConfig.h”文件,路径如下图所示:
在这里插入图片描述
然后复制文件,粘贴到基础工程中的FreeRTOS文件中去,如下图所示:
在这里插入图片描述
添加完成之后,再次构建就不会报错了。
在这里插入图片描述
这个“FreeRTOSConfig.h”头文件是一个配置文件,是直接在官网中下载的,可以直接复制粘贴使用;也可以根据自己的需求来进行配置。

tips:由于正点原子SYSTEM文件夹里面的文件一开始是针对UCOS而编写的,所以如果使用FreeRTOS的话就需要做相应的修改 。
正点原子提供的资料中“STM32F1 FreeRTOS开发手册”中有详细修改步骤,在这里不再赘述。(提取码:hahy)

完成以上操作就完成了FreeRTOS的移植。完成了FreeRTOS的移植之后,我们就来进行下一项。

多任务程序

正点原子提供的资料中有模板,在其中修改成为自己想要完成的程序即可。

开始任务

模板中有一个开始任务,设开始任务的优先级为1,其他任务依次。

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

在主函数中

//创建开始任务
    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();          //开启任务调度

从这个代码中就可以看出来,直接在开始任务函数中调用其他函数即可,就不用再将其他函数编写到主函数中。

在开始任务的基础上,其他任务只需要在此基础上添加三个地方:
①声明;②函数编写;③开始任务函数调用
以下面三个任务为例:

task1:每间隔500ms闪烁(变化)一次LED

声明

//任务优先级
#define LED0_TASK_PRIO		2
//任务堆栈大小	
#define LED0_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数
void led0_task(void *pvParameters);

函数编写

//LED0任务函数 
void led0_task(void *pvParameters)
{
    while(1)
    {
        LED0=~LED0;
        printf("task1:LED\r\n");
        vTaskDelay(500);
    }
} 

开始任务函数调用

    //创建LED1任务
    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);   

task2:每间隔2000ms,向串口发送一次指令数据“HELLO WORLD!"

声明

//任务优先级
#define HELLO_TASK_PRIO		3
//任务堆栈大小	
#define HELLO_STK_SIZE 		50  
//任务句柄
TaskHandle_t HELLOTask_Handler;
//任务函数
void HELLO_WORLD_task(void *pvParameters);

函数编写

void HELLO_WORLD_task(void *pvParameters)
{
    while(1)
    {
		printf("task2:HELLO WORLD!\r\n");
        vTaskDelay(2000);
    }			
}

开始任务函数调用

    //创建HELLO_WORLD任务
    xTaskCreate((TaskFunction_t )HELLO_WORLD_task,     
                (const char*    )"HELLO_WORLD_task",   
                (uint16_t       )HELLO_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )HELLO_TASK_PRIO,
                (TaskHandle_t*  )&HELLOTask_Handler);	

task3:每间隔5000ms,从AHT20采集一次温湿度数据(不考虑硬件情况,仅写出整个多任务框架模拟代码)。

声明

//任务优先级
#define AHT20_TASK_PRIO		3
//任务堆栈大小	
#define AHT20_STK_SIZE 		50  
//任务句柄
TaskHandle_t AHT20Task_Handler;
//任务函数
void AHT20_task(void *pvParameters);

函数编写

void AHT20_task(void *pvParameters)
{
		printf("task3:AHT20\r\n");
        vTaskDelay(5000);
}

tips:由于无硬件支持,这里只是一个框架。

开始函数调用

    //创建AHT20任务
    xTaskCreate((TaskFunction_t )AHT20_task,     
                (const char*    )"AHT20_task",   
                (uint16_t       )AHT20_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )AHT20_TASK_PRIO,
                (TaskHandle_t*  )&AHT20Task_Handler);		

实验结果

LED灯闪烁,时间间隔500ms。
在这里插入图片描述

串口调试助手。博主使用的是正点原子官方提供的串口调试助手,在使用串口调试助手前,需要提前安装CH340驱动。在硬件上,需要用跳帽将PA9和PA10与RXD和TXD盖起来,才能在串口显示接收的数据,如下图所示:
在这里插入图片描述
在这里插入图片描述


总结

实操了一次移植,感觉棒棒哒~需要使用串口调试助手的话,需要提前安装驱动CH340,然后再使用串口调试助手。

  • 完成移植 √
  • 完成多任务程序 √
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeRTOS是一个开源的实时操作系统,可以用于嵌入式系统的开发。要将FreeRTOS移植STM32F407上,需要进行以下几个步骤。 首先,需要包含FreeRTOS的头文件移植文件。头文件包含了FreeRTOS的函数声明和宏定义,移植文件是连接FreeRTOS和具体硬件的桥梁。在移植文件,可以根据使用的开发环境选择需要的文件,其他文件可以删除。\[1\] 其次,需要修改delay_us()函数。这个函数用于实现微秒级的延时。在函数,需要根据系统的时钟频率和延时时间计算出需要的时钟周期数,并使用SysTick定时器进行延时。\[2\] 然后,需要屏蔽FreeRTOSSTM32F407提供的相同的断服务函数。在stm32f4xx_it.c文件,可以直接屏蔽对应的函数。另外,也可以在FreeRTOSConfig.h文件注释掉对应的宏定义。这样可以避免断冲突。\[3\] 最后,进行程序测试,确保FreeRTOSSTM32F407上正常运行。 总结起来,将FreeRTOS移植STM32F407上需要包含头文件移植文件,修改延时函数,屏蔽相同的断服务函数,并进行程序测试。 #### 引用[.reference_title] - *1* *2* [STM32F407移植FreeRTOS操作系统](https://blog.csdn.net/weixin_42960194/article/details/128965478)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [FreeRTOS移植STM32F407](https://blog.csdn.net/pwzpwz1/article/details/128544576)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值