FreeRTOS+STM32F103系列--1.移植

本文介绍了如何将FreeRTOS操作系统移植到STM32F103开发板上,从创建工程、配置文件到修改启动文件的详细步骤。通过移植一个简单的LED闪烁程序,展示了FreeRTOS在STM32上的应用,强调了中断向量配置的重要性。

—-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
     图1 FreeRTOS源文件

  最小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
      记得添加宏不然一堆错误。

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_HandlervPortSVCHandler
替换PendSV_HandlerxPortPendSVHandler
替换SysTick_HandlerxPortSysTickHandler
这三个中断处理函数包含在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

STM32F103微控制器上使用FreeRTOS实时操作系统,是一个非常常见的嵌入式开发需求,尤其适合需要实时任务调度和多任务管理的项目。以下是关于如何进行这一移植和开发的详细指导和资源推荐。 ### FreeRTOSSTM32F103上的移植步骤 1. **准备开发环境** - 确保安装了适用于STM32F103的开发工具链,例如Keil MDK、IAR Embedded Workbench或STM32CubeIDE。 - 下载FreeRTOS官方源码,并根据STM32F103的硬件特性选择合适的内核文件。 2. **构建项目结构** - 创建项目文件夹结构,通常包括`start`(用于启动文件)、`User`(用户代码)、`freertos`(FreeRTOS核心代码)等目录。 -STM32F103的启动文件复制到`start`目录中。 - 创建`main.c`文件,并编写基本的初始化代码,例如系统时钟配置和串口驱动。 3. **集成FreeRTOS源码** - 解压FreeRTOS源码,并将其分为`Core`、`Include`和`Port`三个子目录,分别存放内核文件、头文件和芯片相关移植代码。 - 拷贝`FreeRTOSConfig.h`配置文件到`User`目录,并根据项目需求进行适当配置,例如设置系统时钟频率、任务栈大小等[^5]。 4. **配置Keil项目** - 在Keil中添加`freertos`目录下的源文件,并配置头文件路径,确保编译器能够找到FreeRTOS头文件- 添加STM32F103的HAL库文件,以简化硬件编程[^2]。 5. **创建和管理任务** - 在`main.c`中定义任务函数,并使用`xTaskCreate()`函数创建任务。 - 使用`vTaskStartScheduler()`启动任务调度器,开始执行多任务操作[^5]。 6. **测试与调试** - 编译并下载程序到STM32F103开发板。 - 通过串口调试工具观察任务运行情况,并进行必要的调试和优化。 ### 示例项目与模板 - **示例项目**:提供了一个基本的FreeRTOS功能实现,包括任务创建、同步机制和时间片轮转等,适合开发者快速上手。 - **快速集成模板工程**:提供了一个基于STM32F103FreeRTOS模板,帮助开发者快速学习并应用实时操作系统的概念[^4]。 ### 注意事项 - 在开发过程中,请确保遵循良好的编程习惯,确保代码的稳定性和可维护性。 - 如遇到问题,请参考FreeRTOS官方文档和STM32官方开发手册[^2]。 ### 代码示例 以下是一个简单的FreeRTOS任务创建示例: ```c #include "FreeRTOS.h" #include "task.h" void vTaskFunction(void *pvParameters) { for (;;) { // 任务代码 vTaskDelay(pdMS_TO_TICKS(1000)); // 延迟1秒 } } int main(void) { xTaskCreate(vTaskFunction, "Task1", configMINIMAL_STACK_SIZE, NULL, 1, NULL); vTaskStartScheduler(); for (;;); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值