最近按照正点原子教程开始学习FreeRTOS,发现其手册的移植教程中有些地方可能不是那么详细,在此基于正点原子做一期最完整的FreeRTOS移植教程给大家。


小b将本次教程整理的资料放在网盘,以下链接供各位小伙伴下载和学习:
链接:https://pan.baidu.com/s/1z74dzFtQ198XLJwYhOVWlw
提取码:rson


  1. 打开FreeRTOS.exe文件,等待些许时间获取FreeRTOS源码

  2. 拷贝库函数一个最简单的跑马灯实验工程作为待移植工程文件,并在基础工程中新建一个名为 FreeRTOS 的文件夹

  3. 创建FreeRTOS文件夹之后将步骤1获取到的FreeRTOS文件下的FreeRTOSv9.0.0->FreeRTOS->Source中的全部文件全部拷贝到创建文件夹下

  4. 其中为了工程轻简,protable文件夹下只留下以下三个文件夹:

  5. 用keil打开工程文件,点击所示图标新建两个分组FreeRTOS_CORE 和 FreeRTOS_PORTABLE

  6. 创建成功后左边工程栏出现对应两个分组,双击添加对应的文件如下图所示,其中FreeRTOS_CORE中的文件为源码直接打开可看到的.c文件,FreeRTOS_PORTABLE中的文件为port.c 是 RVDS 文件 夹下的 ARM_CM3 中的文件,因为 STM32F103 是 Cortex-M3 内核的,因此要选择 ARM_CM3 中的 port.c 文件,heap_4.c 是 MemMang 文件夹中的,因为heap_4 提供了一个最优的匹配算法,选择heap_4相关API进行内存管理。

  7. 添加完FreeRTOS源码中的.c文件,接下来添加相应头文件的路径。点击如下图标进行设置:

  8. 编译,发现缺少FreeRTOSConfig.h,他是FreeRTOS 的配置文件,一般的操作系统都有裁剪、配置功能,而这些裁剪及配置都是通过一个文件来完成的,基本都是通过宏定 义来完成对系统的配置和裁剪的。可以到FreeRTOS的demo里面相关的,但是不同硬件和环境配置不同,本操作采用正点原子的板子,直接拷贝一份正点原子STM32的FreeRTOSConfig.h到FreeRTOS的include目录下,再次进行编译

  9. 编译结果有错误,打开USER的system_stm32f0x_it.c,将以下报错两个函数屏蔽掉,编译成功

  10. 修改sys.h文件
    在 sys.h 文件里面用宏 SYSTEM_SUPPORT_OS 来定义是否使用 OS, 我们使用了 FreeRTOS,所以应该将宏 SYSTEM_SUPPORT_OS 改为 1。

  11. 更改delay.c
    delay.c需要修改比较多地方
    函数 SysTick_Handler():

extern void xPortSysTickHandler(void);//systick中断服务函数,使用ucos时用到
void SysTick_Handler(void)
{   if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行{xPortSysTickHandler(); }
}

delay_init()函数:

//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟,基础例程里面SYSTICK时钟频率为AHB/8
//这里为了兼容FreeRTOS,所以将SYSTICK的时钟频率改为AHB的频率!
//SYSCLK:系统时钟频率
void delay_init()
{u32 reload;SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择外部时钟  HCLKfac_us=SystemCoreClock/1000000;              //不论是否使用OS,fac_us都需要使用reload=SystemCoreClock/1000000;              //每秒钟的计数次数 单位为M  reload*=1000000/configTICK_RATE_HZ;           //根据configTICK_RATE_HZ设定溢出时间//reload为24位寄存器,最大值:16777216,在72M下,约合0.233s左右   fac_ms=1000/configTICK_RATE_HZ;                //代表OS可以延时的最少单位    SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;     //开启SYSTICK中断SysTick->LOAD=reload;                      //每1/configTICK_RATE_HZ秒中断一次    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;     //开启SYSTICK
}

剩下三个函数都是延时函数:

//延时nus
//nus:要延时的us数.
//nus:0~204522252(最大值即2^32/fac_us@fac_us=168)
void delay_us(u32 nus)
{       u32 ticks;u32 told,tnow,tcnt=0;u32 reload=SysTick->LOAD;               //LOAD的值             ticks=nus*fac_us;                         //需要的节拍数 told=SysTick->VAL;                     //刚进入时的计数器值while(1){tnow=SysTick->VAL;  if(tnow!=told){        if(tnow<told)tcnt+=told-tnow;  //这里注意一下SYSTICK是一个递减的计数器就可以了.else tcnt+=reload-tnow+told;        told=tnow;if(tcnt>=ticks)break;            //时间超过/等于要延迟的时间,则退出.}  };
}
//延时nms
//nms:要延时的ms数
//nms:0~65535
void delay_ms(u32 nms)
{   if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行{       if(nms>=fac_ms)                     //延时的时间大于OS的最少时间周期 { vTaskDelay(nms/fac_ms);            //FreeRTOS延时}nms%=fac_ms;                      //OS已经无法提供这么小的延时了,采用普通方式延时    }delay_us((u32)(nms*1000));               //普通方式延时
}//延时nms,不会引起任务调度
//nms:要延时的ms数
void delay_xms(u32 nms)
{u32 i;for(i=0;i<nms;i++) delay_us(1000);
}

注意:delay_ms函数改完之后和头文件声明的不对应,需要到头文件delay.h更改下u16改成u32

最后,不要忘记将”includes.h”换成头文件”FreeRTOS.h”,并添加其他头文件如下图所示

其他无关的程序如:

#if SYSTEM_SUPPORT_OS                            //如果SYSTEM_SUPPORT_OS定义了,说明要支持OS了(不限于UCOS).
#ifdef  OS_CRITICAL_METHOD                      //OS_CRITICAL_METHOD定义了,说明要支持UCOSII ...
...OSTimeDly(ticks);                            //UCOSII延时
#endif
}

都可以删掉了。

  1. 更改usart.c
    usart.c 文件有两部分要修改,一个是添加 FreeRTOS.h 头文件, 默认是添加的 UCOS 中的 includes.h 头文件,修改以后如下:

    另外一个就是 USART1 的中断服务函数,在使用 UCOS 的时候进出中断的时候需要添加 OSIntEnter()和 OSIntExit(),使用 FreeRTOS 的话就不需要了,所以将这两行代码删除掉,修改 以后如下:
void USART1_IRQHandler(void)                 //串口1中断服务程序
{u8 Res;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾){Res =USART_ReceiveData(USART1);   //读取接收到的数据if((USART_RX_STA&0x8000)==0)//接收未完成{if(USART_RX_STA&0x4000)//接收到了0x0d{if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始else USART_RX_STA|=0x8000;  //接收完成了 }else //还没收到0X0D{   if(Res==0x0d)USART_RX_STA|=0x4000;else{USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;USART_RX_STA++;if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收   }      }}          }
}
  1. 直接将以下代码替换到main.c中的全部程序,编译烧录到板子中,有跑马灯现象证明成功。(本次实验使用的是战舰版,如果使用其他板可能需要稍作调整)
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
/************************************************ALIENTEK 战舰STM32F103开发板 FreeRTOS实验2-1FreeRTOS移植实验-库函数版本技术支持:www.openedv.com淘宝店铺:http://eboard.taobao.com 关注微信公众平台微信号:"正点原子",免费获取STM32资料。广州市星翼电子科技有限公司  作者:正点原子 @ALIENTEK
************************************************///任务优先级
#define START_TASK_PRIO     1
//任务堆栈大小
#define START_STK_SIZE      128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);//任务优先级
#define LED0_TASK_PRIO      2
//任务堆栈大小
#define LED0_STK_SIZE       50
//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数
void led0_task(void *pvParameters);//任务优先级
#define LED1_TASK_PRIO      3
//任务堆栈大小
#define LED1_STK_SIZE       50
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);int main(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4   delay_init();                      //延时函数初始化     uart_init(115200);                    //初始化串口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=~LED0;vTaskDelay(500);}
}   //LED1任务函数
void led1_task(void *pvParameters)
{while(1){LED1=0;vTaskDelay(200);LED1=1;vTaskDelay(800);}
}

学完有收获的小伙伴不妨点个赞支持一下小b呀~

STM32F103--移植FreeRTOS完整教程相关推荐

  1. STM32F103移植FreeRTOS必须搞明白的系列知识---1(Cortex-CM3中断优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识---1(Cortex-CM3中断优先级) STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级) ...

  2. STM32F103移植FreeRTOS

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.freeROTS是什么? 二.移植FreeRTOS步骤 1.移植工具 2.第一步建立一个工程 3.第二步下载Fre ...

  3. 基于STM32F103移植FreeRTOS教程

    前言 本教程只针对移植实操,关于理论部分请另行百度学习. 本教程移植实操基于正点原子源码.教程手册进程移植. 移植实操 1.将正点原子跑马灯程序源码复制一份,添加一个文件夹对FreeRTOS源码进行管 ...

  4. 【FreeRTOS】在Cortex-M4开发板上移植FreeRTOS并且实现LED灯闪烁(保姆级教程)

    相信有不少小伙伴手上只有M4的开发板,想要移植FreeRTOS:但是,网上大部分都是M3移植教程.因此,陷入深深的迷茫中,难不成只能使用仿真了???

  5. STM32F103移植LiteOS保姆级教程(基于Huawei-LiteOS-studio)

    前言 开始按照官方教程进行安装和配置发现会有一些问题,经过不断尝试终于可以在huawei-liteos-studio下编译移植成功.以下为STM32F103ZE移植LiteOS详细的完整教程. 步骤 ...

  6. 转发:stm32 移植 freertos

    原链接:http://www.51hei.com/bbs/dpj-106526-1.html 看到一篇stm32移植freertos的文章,讲述的最完整. 前言: 由于之前听过太多人抱怨移植FreeR ...

  7. STM32系列单片机标准库移植FreeRTOS V10.4.6详解

      文中所用到的资料下载地址 https://download.csdn.net/download/qq_20222919/87370679   最近看正点原子新录制了手把手教你学FreeRTOS的视 ...

  8. GD32F407 移植FreeRTOS+Lwip

    文章目录 移植过程 移植FreeRTOS 源码拷贝 FreeRTOSConfig.h 注意事项 移植LWIP 源码拷贝与编译 初始化 移植过程 freeRTOS V10.4.5 下载 https:// ...

  9. STM32F103移植mpu9250

    STM32F103移植mpu9250 1. 需求和来源 1.1. 基本配置 1.2. 遗留问题 2. 解决办法 2.1. libmpllib.lib 2.2. 空间不够 1. 需求和来源 回归技术的第 ...

  10. 2.STM32F407ZGT6 学习笔记-移植 FreeRTOS

    程序移植的代码: https://gitee.com/chejia12/free-rtos_-f407.git 1. 在工程下建议FreeRTOS文件夹 2. 在FreeRTOS文件夹下建立 src ...

最新文章

  1. 定制开发软件所有权_职业所有权软件开发人员指南
  2. 十六、python开发之进程与线程
  3. 前驱和后驱什么意思_14.98万!造型酷似“保时捷”,后置后驱续航510,这款SUV要火...
  4. qq互联android sdk,qq互联.Android
  5. 个人信息管理系统代码_Thymeleaf+SpringBoot+Mybatis实现的易游网旅游信息管理系统...
  6. unity3d 任务头上的血条
  7. mysql中定时任务_mysql中定时任务的用法
  8. 价值800的swapidc鸟云模板
  9. T4生成实体,单张表和多张表
  10. 在SQL Server中比较VARCHAR(max)与VARCHAR(n)数据类型
  11. k8s升级,HA集群1.12.0~HA集群1.13.2
  12. 23种设计模式(四)组件协作之观察者模式
  13. pytorch数据集
  14. 2020中国区块链产业政策年度报告|链塔智库
  15. 操作系统教程(第6版) 预习笔记
  16. Python写反斜杠\a
  17. 关于一个CUE文件及多个分轨APE合并成CUE及APE文件的办法
  18. ios移动端input以及中文键盘和阴影效果问题
  19. must be of typexxx解决方法
  20. 如何读取md文件(MarkdownPad2专业版已激活)

热门文章

  1. Jquery 使用niceScroll.js 插件
  2. iphone刷android怎么刷机,不用刷机 让iPhone运行Android 6.0
  3. 什么是jsp,什么是Servlet?jsp 和Servlet 有什么区别
  4. EXCEL制作行政区地图,小O地图EXCEL版发布新版本
  5. chrome-推荐13个插件
  6. 中国电信天翼网关路由器后台登录useradmin用户忘记密码的解决方法默认密码管理员密码工作人员密码
  7. python基础案例教程课后答案_Python基础案例教程
  8. html中在线取色器,在线取色器(ColorPicker)的制造方式
  9. CISCO常用配置命令
  10. 算法笔记(胡凡)刷题笔记目录