3 软件设计
3.1 操作系统
μC/OS-II是JeanJ-Labrosse开发的免费的、开源的嵌入式实时操作系统。μC/OS-II是一个基于优先级的可剥夺型内核,系统所有任务都有一个唯一的优先级别,适用于实时性要求较强的场合。μC/OS-II提供多种系统服务,如消息邮箱、消息队列、信号量管理以及时间延时等,实时内核使得CPU的利用更有效。
3.2 μC/OS-II在ARM上的移植及配置
μC/OS-II的源代码除了那些与硬件关系紧密的软件模块需用汇编语言编写外,绝大部分代码都采用C语言编写,所以μC/OS-II的可移植性强。在ARM上移植μC/OS-II主要编写3个源文件,即OS_CPU.H、OS_CPU.C、OS_CPU_A.S。在OS_CPU.H
中完成所需的基本配置和定义(定义数据类型、定义使能和禁止中断宏等);OS_CPU.C主要移植OS-TaskStkInit()、OSTaskCreateHook()、OSTaskDelHook()、OSTaskSwHook()、OSTaskStatHook()、OSTimeTickHo-ok()等6个函数;OS_CPU_A.S主要完成OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()、OSTickISR()等4个汇编函数的移植。
3.3 系统任务及分析
对一个具体的嵌入式应用系统“任务划分”是实时操作系统应用软件的关键,任务划分是否合理将直接影响软件设计质量。本系统主要有8个任务,即车速脉冲测量任务、CAN总线任务、水温采样任务、油量采样任务、开关量处理任务、里程记录及
LCD显示任务、步进电机驱动任务、WDT任务。任务间通过消息队列和信号量进行通信和共享数据。系统主控程序如下:
主程序在完成初始化(硬件初始化ARMtarge-tInit()、μC/OS-II初始化OSInit()、建立消息队列等)工作后依次创建各任务,然后调用OSStart()启动操作系统,启动时钟ARMTargetStart()。在μC/OS-II中,各任务都是并发的,但优先级不同,拥有各自的任务堆栈,不同任务间通过消息队列和信号量进行通信和共享数据。任务采用无限循环结构,各任务通过延时或者等待信号量和消息队列来放弃CPU的使用权,这样在时钟脉冲到来时产生中断切换任务,系统转而运行准备就绪的高优先级任务,当延时或信号量和消息队列到来时,任务再次运行。系统采用TimerO定时中断作为系统时钟脉冲控制器,并在需要的任务中建立信号量。系统任务如下:
1)车速脉冲测量任务:脉冲信号接EINTO,使用定时器1定时,测量t时间内脉冲数,并将数据发送到消息队列。
2)CAN总线任务:CAN总线任务等待中断服务程序发送,接收CAN总线数据的信号量,获得CPU使用权后,CAN总线任务处理CAN总线数据并将其发送到消息队列,并再次等待接收信号量。
3)水温和油量采样任务:定时采样模拟量,并将采样到的模拟量数值发送到消息队列。
4)开关量处理任务:根据开关量的状态控制LED点亮或熄灭,延时。
5)里程记录及LCD显示任务:当车速脉冲值累加至0.1 km计数值,向本任务发出信号量,任务获得信号量后进入准备就绪状态,在任务调度时获得CPU的使用权,显示并记录里程信息,运行后继续等待接收信号量。
6)步进电机驱动任务:首先等待消息队列,再根据送出消息的任务识别出信息内容,根据队列中的数据驱动步进电机旋转相应的步数,运行后再次等待队列中的消息。本任务赋予第2高优先级。
7)WDT任务:用于监控,提高系统的可靠性,任务优先级最高,延时。
3.4 CAN总线任务及步进电机驱动任务流程
由于S3C44BOX的SIO接口的引脚与标准I/O端口复用,因此首先必须设置S3C44BOX的引脚57~引脚59为SIO接口,然后再通过配置SIO模块对应的寄存器,使得SIO时序与MCP2510的SPI接口协议一致,可通过以下初始化SIO函数实现。
如图5所示,初始化完成后,主程序发起CAN总线任务及步进电机驱动任务,两个任务先后进入等待信号量和等待消息队列,CAN总线发生中断后,中断服务程序释放信号量,使得CAN总线任务进入就绪状态,在其获得CPU控制权后,处理数据,然后将数据发送至消息队列,从而使得步进电机驱动任务进入就绪状态,电机任务通过任务调用获得CPU使用权,再根据消息队列中的数据计算出所需的驱动步数,驱动电机旋转。
4 结束语
采用S3C44BOX与嵌入式实时操作系统μC/OS_II设计了一款高精度高、高灵敏度、工作稳定的嵌入式总线汽车数字仪表。S3C44BOX资源丰富、执行速度快,能扩展很多种功能,如IC卡、GPS、黑匣子等;加之嵌入式实时操作系统简化了应用程序,可高效实时地调用系统任务,因此本汽车数字仪表系统能够很好地解决汽车仪表迈向综合信息化的问题。