FREERTOS移植STM32F407

FREERTOS移植STM32F407

获取FREERTOS源码

从github上下载:FREERTOS源码

在这里插入图片描述

创建基础工程

1.利用Keil 5 创建一个STM32基础工程,建议直接使用任何一个STM32库模板。

在这里插入图片描述

  1. 在基础工程中创建一个文件夹FREERTOS,用来存放FreeRTOS源码,该源码存放在下载的source文件夹下,然后删除不需要的文件。我们用到的文件如下:

在这里插入图片描述
其中port.c文件来自portable\RVDS\ARM_CM4F目录,heap_4.c来自portable\MemMang目录,删除portable下的其他文件夹。

最后加入头文件路径:

在这里插入图片描述

3.编译报错(一): 找不到FreeRTOS.h

在源码FreeRTOSv202104.00\FreeRTOSv202104.00\FreeRTOS\Demo文件夹中找到对应芯片工程的FreeRTOSConfig.h,比如STM32F407就需要找到并添加到工程的FREERTOS/include目录下。

在这里插入图片描述

编译报错(2):SystemCoreClock未定义

FreeRTOSConfig.h中的条件编译

#ifdef __ICCARM__

改为

#if defined(__ICCARM__)||defined(__CC_ARM)||defined(__GNU__)

编译报错(3): 提示port.ostm32f4xx_it.o有重复定义

注释掉stm32f4xx_it.c中的SVC_Handler(),PendSV_Handler(),SysTick_Handler()即可。

编译报错(4):提示4个hook函数未定义

修改FreeRTOSConfig.h中的HOOK宏的值为0

#define configUSE_IDLE_HOOK             0
#define configUSE_TICK_HOOK             0
#define configCHECK_FOR_STACK_OVERFLOW  0
#define configUSE_MALLOC_FAILED_HOOK    0

至此,编译成功~

接下来,可以创建我们的任务了。

任务创建函数

xTaskCreate函数原型在task.c文件中,是一种动态创建任务的方式,系统通过heap_4.c的配置为任务自动分配相关的内存。

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,              // 关联的任务函数名
                       const char * const pcName,               // 任务名
                       const uint16_t usStackDepth,             // 任务堆栈大小,是实际申请的4倍
                       void * const pvParameters,               // 任务函数的参数,没有设为NULL
                       UBaseType_t uxPriority,                  // 任务优先级 0 ~ configMAX_PRIORITIES - 1
                       TaskHandle_t * const pxCreatedTask )     // 任务句柄,是个指针
    
// 返回值: BaseType_t ,实际是long 类型,定义在 portmacro.h中
// 任务句柄的类型 TaskHandle_t 的实际类型是 void*,定义在task.h中

任务删除函数

vTaskDelete的函数原型也在task.c文件中。通过xTaskCreate()动态创建的任务,在使用vTaskDelete()删除后,该任务创建时申请的堆栈和内存会在系统的空闲任务中被释放掉。

void vTaskDelete(TaskHandle_t xTaskToDelete)   // xTaskToDelte : 要删除的任务句柄

任务调度函数

vTaskStartScheduler函数原型也在task.c文件中,不需要参数,开启后就由FreeRTOS开始任务调度工作。

void vTaskStartScheduler( void )

主函数

我们以前写的STM32库函数编程方式属于裸机编程,编程也称为前后台系统。它通过while(1)大循环,轮询循环体,使得各个任务耦合在一起,实时性不高。

// 裸机编程
int main(){
   ...  // 初始化操作
   
   while(1){  // 轮询方式
       task1();    // 任务1,
       ...
       ... 
       task2();   // 任务2
       ....
   }
}

比如上面两个任务必须交替执行,一个任务必须等待另外一个任务完成,而等待时间起决定具体程序。

为了提高实时性,我们便引进RTOS,即用操作系统来管理具体的任务调度,而不是采用轮询的方式,这样就大大提高了任务之间的独立性和实时性。在实时性编程中,我们只需要在main函数中创建任务并开启任务调度,即可使系统持续运行。

int main(void)
{ 
    //设置系统中断优先级分组4(FreeRTOS中的默认方式!)
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    
    //初始化LED端口
    LED_Init();                         

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

开始任务的函数是一个接口,负责创建其他子任务,创建完之后会把自己删掉。这样在我们的main函数中,只需要一个start_task函数就行了,具体的任务创建都打包在start_task函数中。

这里我们创建两个任务:tast1_tasktask2_task

首先定义创建任务需要的一些宏,并包含FreeRTOS.htask.h头文件。

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

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

#define TASK1_TASK_PRIO     2
#define TASK1_STK_SIZE      128  
TaskHandle_t Task1Task_Handler;
void task1_task(void *pvParameters);

#define TASK2_TASK_PRIO     3   
#define TASK2_STK_SIZE      128  
TaskHandle_t Task2Task_Handler;
void task2_task(void *pvParameters);

然后编写start_task函数。

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    
    //创建TASK1任务
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //创建TASK2任务
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
                
    vTaskDelete(StartTask_Handler); //删除开始任务
                
    taskEXIT_CRITICAL();            //退出临界区
}

最后创建两个任务函数:task1_tasktask2_task。每个任务函数都是一个死循环,注意循环中必须添加vTaskDelay()延时函数,用于任务的切换。

//task1任务函数
void task1_task(void *pvParameters)
{
    while(1)
    {
        LED0 = 1;
        vTaskDelay(500); //延时500ms
        LED0 = 0;
        vTaskDelay(200); //延时200ms
    }
}

//task2任务函数
void task2_task(void *pvParameters)
{
    while(1)
    {
        LED1 = 1;
        vTaskDelay(200); //延时200ms
        LED1 = 0;
        vTaskDelay(200); //延时200ms
    }
}

最后烧录到STM32F407开发板中,然后操作系统便开始调度任务。可以看到两个LED灯任务便开始根据系统的调度算法进行运行。

在这里插入图片描述

------------------------------------------------分割线~------------------------------------------------------

移植M3

题外话,这里顺带提一点M3内核移植FreeRTOS。

基本步骤同上,编译问题有所不同。

1.选择STM32F103的FreeRTOSConfig.h文件,并放置在FREERTOS\include文件夹下

在这里插入图片描述

2.选择内核文件,使用这里的port.c文件。

在这里插入图片描述

3.编译出现一个问题,在FreeRTOS.h中修改宏如下

#ifndef INCLUDE_xTaskGetCurrentTaskHandle
    #define INCLUDE_xTaskGetCurrentTaskHandle   1   // 将0改为1
#endif

4.在启动文件startup_stm32f10x_hds中添加
在这里插入图片描述

以及修改如下

在这里插入图片描述

差不多就是这样~

最后的最后,移植操作系统虽然没啥技术含量,但移植成功,系统跑起来了还是蛮开心的,各位加油,奥利给~

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
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 ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rob月初

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值