说明:其实要是从零移植freertos还是不简单的,比如那个port.c文件里面,有上下文切换的地方需要用到汇编,这个是和目标机器强相关的,不过还好官方有提供各个内核的port.c文件;还有比如FreeRTOSConfig.h文件,里面包含大量的配置,自己从零写也不现实,也还好在官方DEMO里面对各个平台的MCU有样例,给了参考用的FreeRTOSConfig.h文件。
一、需要的文件简单说明:
1.如图1,需要的文件主要分为三部分,当然还有和.c文件的相关头文件在这里没有列出:
图1
(1)核心组件:croutine.c、event_groups.c、list.c、queue.c、stream_buffer.c、tasks.c、timers.c
(2)其他组件:
heap_4.c,这是freertos提供的堆内存管理方法,其实有好几个,一般就用这第4个;
port.c,这是freertos针对目标内核平台做的处理,比如实现任务调度需要用到的3个中断函数:
void xPortPendSVHandler( void ); void xPortSysTickHandler( void ); void vPortSVCHandler( void );
这3个中断函数需要使用宏定义映射到目标平台定义的中断函数名称上,这个步骤可以放在FreeRTOSConfig.h文件
二、freertos源码下载:
1.我们需要的文件是从freertos源码里面抠出来的,因此我们需要去官网下载它:https://www.freertos.org
2.如图2,下载页面提供了两个下载路径:github和下载按钮,其中下载按钮是提供的完整源码,而github跳转过去的页面不是完整的源码
图2
3.其实从下载按钮下载就可以了。当然如果去github下载,则除了跳转过去的链接需要下载以外,需要去所在页面下面找到如图3所在位置,去跳转另一个页面下载内核子模块(不用管当前页面前面那些让用命令下载子模块的方法,我试了,按那些方法下载失败):
图3
4.源码目录,如图4,在Demo目录里面可以找到供参考用的FreeRTOSConfig.h文件,source文件夹下的所有文件整体拷贝到目标工程,然后把不需要的文件删了即可:
图4
三、开始移植
1.准备一个标准库工程,我是直接复制野火的样例改的,至少弄两个功能,这样好看出任务切换有没有效果,我是弄了一个LED闪烁和一个定时打印字符串。另外工程里面不要使用systick中断,这个中断保留给freertos做任务调度使用,在port.c里面由freertos针对对应的内核平台已经对此做了实现
2.如图5,在工程根目录下新建一个文件夹并命名为FreeRTOS
图5
3.将FreeRTOS源码中Source文件夹下的所有内容拷贝进上面新建的FreeRTOS文件夹,拷贝后如下图6:
图6
4.图7中选中的文件是不需要的,可以删除:
图7
5.进portable文件夹,如图8中选中的部分都是不需要的,可以删除
图8
6.进RVDS文件夹,如图9中选中的部分都是不需要的,可以删除
图9
7.去FreeRTOS源码中Demo文件夹下对应找到对应内核型号的FreeRTOSConfig.h文件复制到FreeRTOS文件夹下备用
图10
8.在工程中新建两个文件组:FreeRTOS/Core、FreeRTOS/Interface,并加入相关文件:
(1)在FreeRTOS/Core组里面添加核心组件c文件如图11,这些核心组件c文件在FreeRTOS文件夹下:
图11
(2)在FreeRTOS/Interface里面添加堆内存管理文件heap_4.c和目标内核平台接口实现文件port.c,如图12,其中heap_4.c文件位于MemMang文件夹下,port.c文件位于ARM_CM3文件夹下
图12
(3)如图13,在用户组加入FreeRTOSConfig.h,方便对其修改
图13
9.在工程选项中添加头文件目录:
(1)..\..\FreeRTOS\include
(2)..\..\FreeRTOS\portable\RVDS\ARM_CM3
(3)..\..\FreeRTOS
如图14:
图14
10.在FreeRTOSConfig.h文件中宏定义3个任务调度所使用的中断函数,将freertos在port.c里面实现的函数和stm32启动文件里定义的中断函数名字对应起来,同时要删除工程中的定义,否则会出重复定义的错误
四、编写测试程序
1.在main.c中引入头文件:
2.定义两个任务:
void vTask1( void *pvParameters ){ for( ;; ) { DelayTime(); LED1_TOGGLE; }}void vTask2( void *pvParameters ){ for( ;; ) { DelayTime(); printf("hello world.\r\n"); }}
3.创建并启动以上两个任务:
xTaskCreate(vTask1,"LED",128,NULL,1,NULL);xTaskCreate(vTask2,"printf",128,NULL,1,NULL);vTaskStartScheduler();
4.完成测试,可看到LED闪灯和定时打印两个任务同时进行
五、总结大概的移植步骤:
1.准备好一个单片机裸机工程,systick中断不要使用,当然了另外两个SVC和PendSV中断也不能使用
2.将需要的FreeRTOS文件复制过来,将不需要的文件删除,主要需要核心组件c文件以及相关头文件,堆内存管理c文件,内核平台接口实现port.c文件以及头文件,参考用的FreeRTOSConfig.h头文件
3.新建组,将删减后保留下来的c文件放入新建的组,将FreeRTOSConfig.h头文件加入用户组以方便修改
4.将以上各头文件所在目录加进工程的头文件引用配置
5.在FreeRTOSConfig.h中做宏定义以将FreeRTOS在port.c中定义的三个中断函数映射到目标MCU,并删除工程中已有的对应中断函数定义
6.以上5步已经完成了系统移植,后面就可以根据自己的需要引入对应的头文件,编写代码进行测试。只要按这五个步骤来,不管是用标准库工程还是stm32cubemx生成的工程来做移植其实都是差不多的,不过cubemx好像还有个快速配置freertos的功能,那个我暂时还没试过