如果你使用的是已存在的平台与范例程序,你不需要阅读与理解此页内容!
移植FreeRTOS到一个完全不同并且现在还没有支持的微控制器并不是一个微不足道的任务。这个文档的目的就是描述移植一个新平台需要的初步技能。
每种平台在一定程度上是独特的,并且非常依赖于所用的处理器与工具,所以此文档无法提供一个特定的移植细节。幸好FreeRTOS已移植到很多其他的平台上,建议你使用这些平台作为参考。
在同一系列的处理器间移植通常会更加简单与直接——例如从一个基于ARM7的平台移植到另外一个。如果这是你的目标,则阅读《如何修改现有的范例程序》文档将是一个很好的出发点。
建立目录结构
译者:下面的stub一词由于本人水平所限,只有直译为桩,个人理解为只给出定义而没有详细实现的函数,如有错误请给与矫正
FreeRTOS平台共有的内核源码通常包含于3个源文件中(如果使用联合程序,则有4个) ,还有1到2个平台(‘port’)文件用于剪裁内核到一个特定的体系结构。
建议步骤:
1. 下载最新的FreeRTOS源码
2. 解压文件到一个便利的路径,小心组织目录结构
3. 熟悉源代码组织与目录结构。
4. 创建一个文件夹用来包含[architecture]‘平台’需要的文件。遵循上面标题的链接中的协定,文件夹应该是下面的构成方 式:FreeRTOS/Source/portable/[compiler name]/[processor name]。例如,如果你使用GCC编译器,你可以在FreeRTOS/Source/portable/GCC下创建一个[architecture] 文件夹。
5. 把空白的port.c与portmacro.h文件放进刚刚创建的文件夹中,这些桩文件(stub files)应该包含所需函数与宏的实现, 参考已有的port.c与portmacro.h文件获取这些函数与宏的列表。你也可以直接复制已有的文件然后简单的把函数体与宏定义内容删除。
6. [architecture]的堆栈指针是递减的吗? 如果不是,则应该把portmacro.h文件中的 portSTACK_GROWTH 宏由-1改为1。
7. 为[architecture]平台创建一个用于包含范例应用程序文件的文件夹,这一次也要遵循 FreeRTOS/Demo/[architecture]的格式,或者是相似的格式。
8. 复制已有的 FreeRTOSConfig.h 与 main.c 文件到刚刚创建的文件夹中。这些文件也要编辑为桩文件(stub files)。
9. 查看FreeRTOSConfig.h文件,里面包含为你所选硬件进行配置的一些宏。
10. 在刚才的文件夹中再建一个叫做ParTest的文件夹 (类似于 FreeRTOS/Demo/[architecture] /ParTest) ,把一个ParTest.c桩文件 (stub file)复制到此文件夹。
11. ParTest.c包含三个简单函数用于:
- 1. 设置GPIO用于闪亮一些LED,
- 2. 置位或清零特定的LED,并且
- 3. 切换一个LED的状态。
- 你需要为你的开发板实现这三个函数。如果LED可以正常工作的话其他的工作就会简单很多。参考其他包含ParTest.c文件的范例工程 作为例子(ParTest是历史上对PARallel port TEST并口测试的不规则简称),《如何修改一个已有的范例》文档中也有编写与测试ParTest.c函数的信息。
创建一个工程
并不是你创建了工程(或makefile)所需的所有文件后就可以成功编译它。很明显仅仅包含这些文件并不会做任何事情 ,除非你把这些桩以可以工作的函数代替再编译。
工程需要包含如下的文件:
- Source/Task.c
- Source/Queue.c
- Source/List.c
- Source/portable/[compiler name]/[processor name]/port.c
- Source/portable/MemMang/heap_1.c
- Demo/[processor name]/main.c
- Demo/[Processor name]/ParTest/ParTest.c
下面的文件夹要加入到包含路径中(include path)——请使用Demo/[Process name]目录的相对路径,而不是绝对路径:
- Demo/Common (i.e. ../Common)
- Demo/[Processor Name]
- Source/include
- Source/portable/[Compiler name]/[Processor name]
必须编辑portable.h包含你新的portmacro.h文件。一个预处理定义可以达到这个目的。查看已有的portable.h文件可以得到很多范例。
桩的实现
这里是难点。当工程编译时平台相关层的桩就需要实现。建议首先实现 pxPortInitialiseStack() 函数。为了实现pxPortInitialiseStack() 函数你必须先决定你的任务上下文堆栈框架结构,这是与硬件平台非常相关的。