基于XE167的FreeRTOS移植

分享到

XE166系列微控制器广泛应用于汽车,电机控制等工业领域中,有着丰富的片上资源外设,并有很强的处理能力。采用RTOS进行应用设计能够更快的进行自己的应用设计,并且能够在系统实时性,代码可读性,复用性,移植性等方面有很大的提升。本文介绍了采用RTOS进行设计的优势,以及如何一步步将FreeRTOS应用到您的XE166系列的微控制器的系统之中。
1. 本文使用的平台和环境
工具软件:keil uVision4 for c166
硬件平台:XE167 实验板
2. FreeRTOS简介 
     FreeRTOS是一个小型嵌入式系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能等,可基本满足较小系统的需要。

  开源且完全免费            多平台支持                      资料详尽        多种组件拓展支持

 

  •   完全免费,包括商业应用。
  •  开放源码,包括内核代码及多平台移植的平台相关代码。
  •  多种平台支持。
  •  资料详尽,包括快速实用指南,用户配置手册,API说明等文档。

3. 采用RTOS进行设计的优势

图1 前后台程序设计与RTOS编程模型对比

采用RTOS进行程序设计特点:
(1)每个不同的功能模块可以设计成一个单独任务。
(2)任务在逻辑上并发运行,程序设计时认为不相关的程序是并行运行互不影响的。物理上靠OS内核调度分时运行。
(3)不同模块,异步事件和同步顺序运行的程序靠信号量,队列等机制进行通信,在逻辑上认为任务A发送了信号1,就触发了等待信号1而阻塞的的任务B的执行。                                                                                                  

                                                                   

 

                                                                              2 任务间通信机制

 

(4)更高的实时性。在高优先级的异步事件发生后,可以触发任务调度使得高优先级的事件立刻得到处理,而不是像前后台程序那样要在主程序依次轮到相应的功能函数处进行处理。
(5)更有效方便的时间管理。在程序延时中不会占用CPU资源,延时任务让出CPU让其他任务执行。
(6)诸如TCP/IP网络协议栈,文件系统,命令行程序等更易拓展,一些RTOS有方便移植的各类协议栈和应用。


4. FreeRTOS的移植
    使用RTOS编程自然首先就是如何把RTOS移植到自己的系统中。可能网上已经有了相似平台的移植代码,但是工程师把握使用平台的原理是必要的,这会在设计时帮助工程师来提高设计系统的可靠度有所帮助。下面本文将针对移植分析,所涉及到的关键问题,以及具体的移植过程进行介绍。


4.1 FreeRTOS移植分析
要移植FreeRTOS到XE166系列单片机中要考虑三个方面的问题:FreeRTOS原理,XE166系列的C166内核原理,编译器相关问题。具体列出内容如下:
    FreeRTOS方面

  •  源码结构。
  •  CPU相关的文件,文件中实现的所有函数,宏定义功能,使用环境及如何实现。
  •  FreeRTOS运行过程。

    XE167及C166内核

  •   C166必要汇编程序设计。
  •  C166的中断过程及CPU上下文概念。
  •  C166堆栈系统
  •  C166寄存器结构

    编译器相关问题

  •    编译器对特殊寄存器的使用。
  •   编译器对函数调用处理方式。
  •   针对特点编译器的汇编程序格式。

首先应了解FreeRTOS的大致原理,及文件结构,然后分析CPU相关部分代码的功能,以及它们的运行上下文环境,最好在已经移植的平台中用跟踪调试的方式来观察FreeRTOS的启动及任务切换过程,以及了解移植部分代码如何在RTOS中起作用的。
在了解了FreeRTOS原理后,就应该开始着手实现与C166内核相关部分的代码,这部分代码的实现又涉及到C166内核及编译器相关的问题。这时可以从英飞凌网站及IDE集成开发环境的目录中找到相关的数据手册,软件帮助文件,软件用户指南等资料进行参考。
实现了移植之后就可以对移植的内核进行测试,优化,并基于移植好的FreeRTOS系统进行应用程序设计。


4.2 FreeRTOS移植涉及关键问题分析


4.2.1 FreeRTOS文件结构


表1  FreeRTOS主要文件

文件名称

功能

list.c

任务各种状态列表的实现。

queue.c

队列,信号量等的实现。

tasks.c

任务调度的实现。

heap_2.c

内存管理的实现。

croutine.c

协程(co-routines)的支持,可选特性。

timers.c

软定时器的支持,可选特性。

port.c

平台相关的代码实现

portext.asm

平台相关的代码实现(适合用汇编实现部分)

portmacro.h

平台相关的宏定义

freertosconfig.h

具体应用相关的对FreeRTOS的功能裁剪配置文件

 

 

FreeRTOS主要由list.c,queue.c,tasks.c 三个文件构成,这三个文件是FreeRTOS能够运行的必要组成部分。除这些文件外还有一些相应的头文件和一些拓展功能实现的文件,如croutine.c,timers.c ,这些文件可以根据用户对FreeRTOS的高级功能的需求来决定是否包含进工程。其中 port.c ,portext.asm ,portmacro.h 是与平台相关的文件,通过修改这三个文件的内容来符合针对特定的平台。
    该三个文件主要实现了以下的功能函数:


表2  移植文件中主要的功能函数

函数

功能

portENABLE_INTERRUPTS()

允许全局中断

portDISABLE_INTERRUPTS()

禁止全局中断

portENTER_CRITICAL()

进入临界段

portEXIT_CRITICAL()

退出临界段

vPortEndScheduler()

结束调度

pxPortInitialiseStack()

初始化任务堆栈

portYIELD()

强制上下文切换

xPortStartScheduler()

启动调度器

滴答时钟定时器初始化函数

滴答时钟定时器中断服务函数

为系统提供滴答时钟

 

 

其中portENABLE_INTERRUPTS()与portDISABLE_INTERRUPTS()为开关中断功能函数,C166系统中通过调用汇编指令实现。
portENTER_CRITICAL(),portEXIT_CRITICAL()为进出临界段函数。进入临界段时要禁止中断和调度。实现时要考虑调用的嵌套,即在临界段中再调用临界段函数还是临界段中,只有最后一层跳出后才是真正的跳出临界段,才能使能中断和调度。
    vPortEndScheduler() 为结束调度函数,这个可以空实现,即不在函数中写任何代码。
    pxPortInitialiseStack() 为任务堆栈初始化功能函数。可以用C语言初始化相应的堆栈结构。
    portYIELD() 为强制上下文切换的功能函数。在系统调用此表达式后,会将当前任务的上下文保护到任务堆栈中,再进行任务的调度找到当前就绪的最高优先级的任务,接下来恢复新的任务的上下文到微控制器的CPU的各个寄存器及相应的任务变量中。由于这涉及到CPU的寄存器,和一般会涉及到系统堆栈的操作,所以这部分代码通常会通过汇编语言,或是C与汇编语言的混合编程来实现。C166系统中由软中断操作触发。
    xPortStartScheduler() 为开始调度器调度的实现的功能函数。主要实现了滴答时钟定时器的初始化,并恢复当前就绪优先级最高任务的上下文环境,通过中断返回进入到第一个执行的任务中,就开始了多任务的调度。因为涉及到CPU的寄存器,和一般会涉及到系统堆栈的操作,所以这部分代码通常会通过汇编语言,或是C与汇编语言的混合编程来实现。
    pxPortInitialiseStack(),portYIELD(),xPortStartScheduler() 的实现要考虑到任务堆栈的结构,以及与使用的微控制器体系结构,编译器规则等都有所关联。


提示:这部分内容的深入理解可以通过分析已经实现移植的多个平台的移植代码来分析,以及通过已实现移植的系统中通过单步调试跟踪代码的执行流程来深入理解。