摘要:μC/OS—II是面向8/16位及低端32位单片机应用的RTOS,而新近推出的μC/OS—Ⅲ则面向高性能32位单片机,如ARM Cortex等。以Cortex—M4为内核的Kinetis系列单片机,不仅用于全国大学生飞思卡尔杯智能车竞赛,也用于诸多大学的嵌入式系统教学,官方提供的开发环境是CodeWarrior。本文介绍如何利用CodeWarrior开发环境,将μC/OS—III在Kinetis单片机上运行起来,以便将μC/OS—III引入教学、科研与应用。
关键词:μC/OS—III;Kinetis CodeWarrior
引言
Kinetis系列是飞思卡尔公司基于ARM Cortex—M4和Cortex—M0+内核的单片机,和Cortex—M3相比,M4内核主要增加了DSP运算指令和可选的浮点运算单元,同时保持了与Cortex—M3的兼容性,因此被寄予希望能逐步替代Cortex—M3。Kinetis也成为飞恿卡尔杯全国大学生智能车竞赛新的硬件平台之一。
μC/OS—Ⅲ是Micrium公司推出的全新RTOS,特别适用于那些有计算前导零(CLZ)硬件指令的高端32位CPU,可大大加速就绪表查找速度μC/OS—II的主要精华在于其巧妙的优先级软件查表算法,而对于有CLZ硬件算法指令的CPU,如MIPS、PowerPC、ARM11及以上系列,仍使用μC/OS一Ⅱ就不那么合理了。μC/OS—III源代码公开,官方已提供对目前主流单片机的移植支持,并且针对几大主流单片机都提供相应的教材,Kinetis就是其中之一。Micrium官方提供的基于Kinetis平台的范例都是使用IAR作为集成开发环境的,考虑到飞思卡尔官方的Code Warrior开发环境有着广泛的用户群,尤其是使用过S08/S12等单片机的用户,大多熟悉CodeWarrior。因此,本文将以Kinetis平台为例,讲述如何使用CodeWarrior集成开发环境将μOS—III运行起来,作为应用开发的基础,也便于那些教学中使用CodeWarrior编译器的师生,将μC/OS—Ⅲ引入嵌入式系统教学。
1 CodeWarrior集成开发环境
Kinetis包括K,X、L三大系列,K和X系列是基于Cortex—M4内核,而L系列是基于Cortex—M0+内核。K系列又包括K10~K70多个子系列,不同系列侧重点不同,如K10是基准系列,K20带USB,K60带以太网。因为内核一样,只是外设不同,因此μC/OS—III的移植都是通用的。本文以清华大学飞恩卡尔培训中心为全国大学生智能车竞赛提供的K10开发套件为例进行说明。
针对Kinetis的CodeWarrior软件版本为V10.x,可从官方网站下载免费教学版本。新版的CodeWarrior基予Eclipse开发环境,支持S08/S12/ColdFire/Kinetis等系列单片机。本文使用的CodeWarrior版本为V10.2Special Edition。
最新版本的μC/OS—III源代码可从Micrium公司官方网站下载,网站上的“Source code”栏目提供的只是内核的源代码,不包括移植部分,也没有相关的范例,而“μC/OS—III Books”栏目里可下载针对不同单片机的电子版教材及配套的范例工程。本文使用官方为Kinetis提供的IAR环境下的工程范例为参考。
2 μC/OS-Ⅲ的目录结构
μC/OS—III的代码组织中,除了内核相关的代码文件外,还有两个独立的组件——μC/CPU和μC/LIB。μC/CPU用来封装一个CPU的属性,定义了与编译器和CPU相关的数据类型、寄存器的位宽、大小端格式、堆栈的增长方式、开关中断的函数等等。换句话说,也就是把原来
μC/OS里的一些CPU硬件相关的定义和函数独立成为一个组件,这样,代码的结构就更加清晰。而μC/LIB是一个基础的函数库,不依赖于任何的处理器和编译器,主要包括一些字符串处理函数、数学相关函数,以及内存管理相关的函数。μC/OS—III依赖于μC/CPU和μC/LIB,
因此工程中必须包括μC/CPU和μC/LIB的相关文件才能完成编译。
图1展示了一个典型工程的文件结构。其中,μC/OS—III、μC/CPU、μC/LIB和配置文件部分都是必须的,加粗斜体的文件表示是需要移植的。lib_mem_a.asm文件是用汇编语言编写的优化的内存分配函数,可以不要(lib_cfg.h里的宏LIB_MEM_CFG_OPTIMIZE_ASM_EN要设置为0)。配置相关的头文件必需的有4个,其中,μC/OS—III、μC/CPU和μC/LIB三个组件各有一个对应的配置文件,还有一个是os_cfg_ app.h。os_cfg.h和os_cfg_app.h都是μC/OS—Ⅲ相关的配置文件,前者主要是功能的配置,如是否使用信号量、是否使用时间片轮转调度、是否进行参数检查等等;后者主要是内核资源的配置,如空闲任务、时钟节拍任务的堆栈大小、信号量、消息队列等内核资源的数量等。“板级支持包”和“用户程序”里列出的文件并不是必需的,只是一个范例。板级支持包用来定义与开发板硬件相关的功能函数,如硬件韧始化函数、I/O操作函数、串口服务函数等等。使用板级支持包可以使代码结构更清晰,方便代码共享。
从Micrium网站下载针对Kinetis的教材配套的范例工程压缩包,解压后目录结构如图2所示。Micrium公司的代码组织结构非常清晰,对于程序开发人员来说是一个很好的参考。其中,uCOS-III、uC—CPU、uC—LIB三个文件夹下分别包含了该模块对应的代码,底下各有一个Cfg文件夹,里面包括了该模块配置头文件的模板。而移植相关的部分代码文件都是按“CPU\编译器”的目录结构来组织,如uC—CPU下的ARM—Cortex—M4\IAR。EvalBoards文件夹是范例工程所在,按照“开发板\编译器”的结构组织。
3 Codewarrior环境下运行μC/OS-Ⅲ步骤
3.1 建立新工程
把图2中所述的解压后的Micrium文件夹放到不含中文的路径下(如E:\),在EvalBoards文件夹下新建K10DEVKIT文件夹,表示我们的K10核心开发板。在K10DEVKIT下再新建CodeWarrior文件夹,表示使用CodeWarrior开发环境,该文件夹将作为工程项目的工作空间(works pace)。在CodeWarrior下再建立BSP文件夹,作为K10DEVKIT的板级支持包。
启动CodeWarrior V10.2,将workspace切换到刚才建立的K10DEVKIT\CodeWarrior文件夹,软件会重启并弹出向导页面,选择新建工程,然后按照提示一步步直到完成,中途需要选择单片机的型号和调试工具。开发板使用的单片机是主频100 MHz的PK10N512,调试器使用USBDM。新建立的工程中,软件会自动生成所需的初始化文件和调试配置文件,用户可能用到的几个文件说明如下:
3.2 添加文件
如图2所示,μC/OS—III和μC/CPU中需要移植的代码文件都是放在“CPU\编译器”的目录结构下,从官网下载的只有针对IAR编译器的。首先,在需要移植的代码目录下各建立一个和IAR并列的CodeWarrior文件夹,表示针对CodeWarrior开发环境的移植,然后,把原来IAR开发环境下的移植文件全部拷贝到CodeWarrior文件夹下。在CodeWarrior开发环境下,部分移植文件需要修改,这将在后面讲述。接下来需要把所有相关的代码添加到CodeWarrior工程中。为了便于组织和管理文件,采用以下步骤:
①在CodeWarrior工程的Sources文件夹下建立以下子文件夹;uC—CPU、uC—LIB、uCOS—Ⅲ、Cfg、BSP、APP。uC—CPU、uC—LIB和uCOS—III用来存放该组件包含的文件,Cfg存放配置头文件,BSP存放板级支持包相关文件,APP存放用户代码文件。这里提一下,除了APP和Cfg文件夹外,其他文件夹可采用“虚拟文件夹”形式,这样,该文件夹并不实际存在于Sources目录下,只是用来对文件进行分类管理。
②按照图1所列的内容,把uC—CPU、uC—LIB和uCOS—III三个组件相关的.c和.asm文件添加到对应文件夹,包括移植部分的文件。当然,用户也可以再新建一层子目录区分移植部分和非移植部分。添加文件时有两种方式:拷贝和链接。这里采用链接方式,不生成额外的拷贝,便于代码的管理和更新。将图1中“配置文件”列的几个头文件添加到Cfg文件夹(拷贝图2中的模板文件),这时采用拷贝方式,因为这些文件是应用相关的,不同工程有不同的配置。而其他无需修改的头文件不添加到工程中,而是将其路径加入到工程搜索路径中,这在后面讲述。添加完所有文件后的工程目录如图3所示。
3.3 修改文件
前面提到,uC/OS—III和uC/CPU中需要移植的代码文件在不同的编译器下需要稍作修改。其中,C文件与编译器无关,而汇编文件从IAR转到CodeWarrior有几个地方需要修改,这涉及cpu_a.asm和os_cpu_a.asm两个文件,说明如下:
①在CodeWarrior的汇编文件中,默认标号都以“:”结尾,编译指令都以“.”开头。虽然也可以在工程设置里取消该限制,但还是建议按照该格式编写代码。因此,请检查汇编代码是否符合上述要求。
②在CodeWarrior的汇编文件中,声明全局函数用的是.global,而IAR中用的是PUBLIC,如IAR中的“PUB-LIC OSStartHighRdy”应改为“.global OSStartHighRdy”。
③在汇编文件中,代码前要进行代码段的声明,如IAR中的“RSEG CODE:CODE:NOROOT(2)”在CodeWarrior里应改为“.text,code”
3.4 添加头文件路径
右键点击工程名,选择“Properties”→“C/C++Build”→“Settings”,在“ARM Compile”→“Input”页面可以添加头文件搜索路径,把工程中用到的头文件所在的路径加上,添加时建议使用相对路径(相对工程目录),如图4所示。
3.5 修改中断向量衰
CodeWarrior自动生成的kinetis_sysinit.c文件包含了startup代码和中断向量表,把μC/OS—Ⅲ用到的两个中断向量加入中断向量表,代码如下:
PendSV中断和SysTick定时器集成于Cortex—M3/4内核中,专门用于OS的任务切换和时钟节拍。因此,只要是使用Cortex—M3/4内核的单片机,这部分的移植代码都是通用的。
3.6 代码调试
在进行μC/OS—III应用开发时,应先从最小系统开始调试。在配置文件里把不需要的功能先关掉,如消息队列、信号量、hook函数、统计任务等。在用户程序里执行完硬件相关的初始化后,先建立一个简单的任务(即起始任务),然后测试任务调度是否正常。注意,这时在运行的还有μC/OS—III内部的空闲任务。
如果任务调度正常,可在起始任务里初始化并打开时钟节拍中断,然后可通过断点调试等手段测试时钟中断服务程序是否得到正确执行。确认后可在起始任务里调用延时相关的函数,如以一定的频率闪灯,或者向串口输出信息。如果上述测试通过,那么意味着μC/OS—III已经运行起来了,接下来用户就可以一步步按照应用需求进行开发了。
结语
使用CodeWarrior集成开发环境的读者,只要按照以上步骤,即可在Kinetis系列单片机上完成μC/OS—III的编译和运行。本文所讲述的步骤也可用于其他开发环境,遵循Micrium官方的文件组织结构,可使得工程目录结构清晰规范,方便代码的升级和共享。