FreeRTOS 移栽要点怎么解决
2016-10-18 · 打造可传承的民族化工灌装机品牌
FreeRTOS 的移植主要需要改写如下三个文件。
1. portmacro.h
2. port.c
3. port.asm
如果采用的C编译器允许在C 代码中插入汇编,并且支持用C语言写中断处理函数。则port.asm 文件的内容是可以合并到port.c 中的。
下面以将 FreeRTOS 移植到FreeScale 68HCS12 内核的单片机为例,开发环境采用:CodeWarriorDevelopment Studio V5.9.0
之所以采用FreeScale 68HCS12 作为示例 CPU,是因为我以前写过一篇将uC/OS-II移植到FreeScale 68HCS12 核单片机的笔记。采用同样的CPU,同样的开发环境,可以方便我们比较两种不同实时操作系统的移植代码的异同。另外,FreeScale 68HCS12 相对ARM、MIPS 等构架要简单的多。移植代码量相对来说也要小一些,因此也更容易入门。
portmacro.h
portmacro.h 主要包括两部分内容,第一部分定义了一系列内核代码中用到的数据类型。FreeRTOS 与 uC/OS-II 一样,并不直接使用char、int 等这些原生类型,而是将其重新定义为一系列以port开头的新类型。在uC/OS-II的移植代码中,通常采用 typedef 来定义新的类型,而FreeRTOS的作者似乎更喜欢用宏定义。下面是相应的代码片段。
portTickType 既可以定义为16位的无符号整数,也可以定义为32位的无符号整数。具体用那种定义,要看 FreeRTOSConfig.h 文件中如何设置configUSE_16_BIT_TICKS。
然后是一些硬件相关的定义。包括数据对其方式,堆栈增长方向,Tick Rate,还有任务切换的宏。
portBYTE_ALIGNMENT 在uC/OS-II 是不需要的,FreeRTOS的代码中在分配任务堆栈空间时用到这个宏定义。
portSTACK_GROWTH 定义为1 表示堆栈是正向生长的,-1为逆向生长的。一般来说堆栈都是倒生的,68HCS12 也不例外,因此这里定义为 (-1)。
多说一句在 uC/OS-II 中,对应的宏是OS_STK_GROWTH, 1 表示逆向生长,0表示正向生长。
portTICK_RATE_MS 只在应用代码中可能会用到,表示的是Tick 间间隔多少 ms。
portYIELD() 实现的是任务切换,相当于 uC/OS-II中的 OS_TASK_SW()。
portNOP() 顾名思义就是对空操作定义了个宏。具体在FreeRTOS 代码中哪里用到了这个宏没注意过,但是想必是有地方用到了。
然后是有关临界区的处理代码:
这部分的代码挺长的,不过其实是对 Small Memery Model 和Banked Memery Model 分别提供了如下两个宏定义:
portRESTORE_CONTEXT()
portSAVE_CONTEXT()
使用哪一套宏定义是通过BANKED_MODEL 这个宏是否被定义来确定的。其实,CodeWarrior Development Studio V5.9.0 中提供的官方代码中给出了一种更正规的判断方法:
FreeRTOS中保存和恢复任务上下文环境的代码与uC/OS-II中的大同小异,唯一有点区别的就是要保存uxCriticalNesting 的值。原因上面已经介绍过了。
之所以要搞这两个宏,是为了利用某些C编译器的扩展功能对任务函数进行更好的优化。CodeWarrior 并不提供相关的功能,所以在这里任务就是普通的函数。