博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
移植FreeRTOS到STM32F103全过程
阅读量:4284 次
发布时间:2019-05-27

本文共 4451 字,大约阅读时间需要 14 分钟。

转载出处:

 

目标:

    移植freeRTOS到stm32开发板。
 




1. 熟悉freeRTOS的firmware结构

解压源码到..\FreeRTOSv8.2.2,首先一定要浏览一下各个文件夹下的readme.txt文件。
进到这个目录:FreeRTOSv8.2.2\FreeRTOS\Source
看看这个readme文件:
Each real time kernel port consists of three files that contain the core kernel
components and are common to every port, and one or more files that are 
specific to a particular microcontroller and or compiler.
+ The FreeRTOS/Source directory contains the three files that are common to 
every port - list.c, queue.c and tasks.c.  The kernel is contained within these 
three files.  croutine.c implements the optional co-routine functionality - which
is normally only used on very memory limited systems.
+ The FreeRTOS/Source/Portable directory contains the files that are specific to 
a particular microcontroller and or compiler.
+ The FreeRTOS/Source/include directory contains the real time kernel header 
files.
See the readme file in the FreeRTOS/Source/Portable directory for more 
information.
看懂上面说的了吗?
说的是,源码包括:
1. 通用的内核文件:主要是三个:list.c, queue.c and tasks.c. 而croutine.c表示是写作式的任务,仅用在内存实在是有限的mcu上面。
2. 针对不同架构平台的接口。
3. 头文件
进入FreeRTOSv8.2.2\FreeRTOS\Source\portable,继续看该文件夹下的readme.txt
Each real time kernel port consists of three files that contain the core kernel
components and are common to every port, and one or more files that are 
specific to a particular microcontroller and/or compiler.
+ The FreeRTOS/Source/Portable/MemMang directory contains the three sample 
memory allocators as described on the http://www.FreeRTOS.org WEB site.
+ The other directories each contain files specific to a particular 
microcontroller or compiler.
For example, if you are interested in the GCC port for the ATMega323 
microcontroller then the port specific files are contained in
FreeRTOS/Source/Portable/GCC/ATMega323 directory.  If this is the only
port you are interested in then all the other directories can be
ignored.
看懂了吗?
总结:
1. 在该文件夹FreeRTOS/Source/Portable/MemMang 下面,包含内存分配的样例
2. 其他的文件夹包含具体的文件针对不同的平台和(或者)编译器
猜测:
移植的时候,必须包括如下:
(1)通用的内核文件:list.c, queue.c and tasks.c
(2)针对不同硬件平台的文件
(3)内存分配的文件
(4)头文件
......
 

2. 移植代码

(1)先建立一个工程文件不包括OS的,可以运行,比如最简单的跑马灯例程。
(2)在模板里面建立文件夹: FreeRTOS, 然后再FreeRTOS下建立新文件夹include,用来保存头文件
 
(3)从源文件 \FreeRTOSv8.2.2\FreeRTOS\Source 中找到 croutine.c, timers.c, list.c, queue.c, tasks.c 这5个文件,加入到FreeRTOS文件夹中;
(4)从源文件 \FreeRTOSv8.2.2\FreeRTOS\Source\portable\RVDS\ARM_CM3中找到port.c,加入到FreeRTOS文件夹中;
(5)从源文件 \FreeRTOSv8.2.2\FreeRTOS\Source\portable\MemMang找到heap_2.c,加入到FreeRTOS文件夹中;
这样*.c就添加完成了。
其中:port.c 是针对具体的硬件平台加进来的;
         heap_2.c 是其中一种内存分配管理机制,你可以换成其他形式。
        其他的.C文件是和内核相关的通用文件。
下面添加*.h头文件到include文件夹中
(6)将文件夹 \FreeRTOSv8.2.2\FreeRTOS\Source\include 中的所有.h文件添加到我们建立的include文件夹中;
(7)将文件夹 \FreeRTOSv8.2.2\FreeRTOS\Source\portable\RVDS\ARM_CM3下的portmacro.h文件添加到include文件夹中;
(8)我用的编译器是Keil,是stm32f103系列,在源码的Demo程序中,找到这个芯片的配置文件,加入到include文件夹中;
        将文件夹 \FreeRTOSv8.2.2\FreeRTOS\Demo\CORTEX_STM32F103_Keil 下FreeRTOSConfig.h,加入到include文件夹中;
这样就完成包含头文件的移植。
注意:红色标记的文件哪里来的呢??
(9)在工程中建立FreeRTOS和FreeRTOS\include文件夹,将我们在上面添加的代码添加到工程中,这个就不需要我说了吧。
(10)修改编译环境
    菜单栏找到 Project->options for target->C/C++->Include Paths 中加入上述的 include 文件夹,当然FreeRTOS文件夹最好也添上,防止遗漏。
(11)修改启动代码,重要啊。。。
在__heap_limit 下面添加:
__heap_limit
PRESERVE8
THUMB
;以下是添加的代码
IMPORT xPortPendSVHandler
IMPORT xPortSysTickHandler
IMPORT vPortSVCHandler
 
另外还有就是这三句代码也得修改
DCD SVC_Handler           ->            DCD vPortSVCHandler
DCD PendSV_Handler      ->            DCD xPortPendSVHandler
DCD SysTick_Handler      ->            DCD xPortSysTickHandler
 
 
为什么需要修改呢??想想。。。。。
(12)修改代码
     添加freeRTOS相关的头文件到函数中。
创建任务,并启动调度。
main.c函数;

点击(此处)折叠或打开

  1. #include "led.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4.  
  5. // FreeRTOS head file, add here.
  6. #include "FreeRTOS.h"
  7. #include "task.h"
  8. #include "queue.h"
  9. #include "list.h"
  10. #include "portable.h"
  11. #include "FreeRTOSConfig.h"
  12.  
  13.  
  14. void redLed_Task(void *pvParameters)
  15. {
  16.     static u8 state = 0;
  17.     pvParameters = pvParameters;
  18.     
  19.     while(1)
  20.     {
  21.         (state = !state) == 1 ? (LED0 = 0) : (LED0 = 1);
  22.         vTaskDelay(500/portTICK_RATE_MS); 
  23.     }
  24. }
  25.  
  26.  
  27. void greenLed_Task(void *pvParameters)
  28. {
  29.     static u8 state = 0;
  30.     pvParameters = pvParameters;
  31.     
  32.     while(1)
  33.     {
  34.         (state = !state) == 1 ? (LED1 = 0) : (LED1 = 1);
  35.         vTaskDelay(1000/portTICK_RATE_MS); 
  36.     }
  37. }
  38.  
  39.  
  40. int main(void)
  41. {
  42.     LED_Init();            
  43.  
  44.     xTaskCreate( redLed_Task, "LED1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL); 
  45.     xTaskCreate( greenLed_Task, "LED2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+2, NULL );
  46.  
  47.     vTaskStartScheduler();
  48.     return 0;
  49.  
  50. }
烧写进去就可以看到,两个灯在闪闪发亮了,一个时间间隔是1000ms,一个延时间隔为500ms。
是不是很easy啊。
 

小结:

想一想移植需要做什么?
通用接口,具体硬件接口,内存管理,头文件,任务创建,启动任务。
源代码:
你可能感兴趣的文章
C语言的常用库函数(dos)之四(dir.h文件下的一些函数)
查看>>
warning: jobserver unavailable: using -j1. Add `+' to parent make rule问题怎么解决
查看>>
防火墙报文转发流程
查看>>
以太坊创始人:17岁的亿万富翁养成记
查看>>
linux下IPTABLES配置详解
查看>>
关于iptables -m选项以及规则的理解
查看>>
linux系统中查看己设置iptables规则
查看>>
一些库函数的使用注意事项
查看>>
IPv6地址自动配置中的有状态(stateful)和无状态(stateless)的区别
查看>>
阿里云 ACP 云安全 题库 -- 数据库审计部分
查看>>
GC 回收机制
查看>>
探究 Android MVC、MVP、MVVM 的区别以及优缺点
查看>>
深入分析 Handler 内存泄露
查看>>
解决 windows 文件被占用的问题 -- The action can‘t be completed because the folder is open in another program
查看>>
Tencent/matrix错误:Cause: need sign apk but apksigner *\Sdk/build-tools/*/apksigner was not exist
查看>>
Android6.0运行时权限详解
查看>>
Android 开机启动过程
查看>>
View 的事件分发机制(一)
查看>>
Android 面试题整理(一)
查看>>
Android 项目中打印Log的优化
查看>>