基于LPC2119和μC/OSII 的CAN中继器设计
2.3 系统设计实现
嵌入式CAN中继器主要实现两路CAN总线数据之间相互转发,并且可以根据实际需要,改变某一路CAN控制器的波特率。采用μC/OSII实时操作系统,整个设计由操作系统和一系列用户应用程序构成。
主函数是程序首先执行的一个函数。该函数永远不会返回,主要实现系统的硬件和操作系统的初始化。硬件包括中断、键盘、显示等初始化;操作系统包括任务控制快和事件控制快的初始化,而且在启动多任务调度之前,必须至少创建一个任务。在此系统中创建了一个启动任务,主要负责时钟的初始化和启动,中断的启动,CAN控制器的初始化及启动及任务的划分等。在交出CPU的使用权之后,只做一些空闲处理。
(1) 任务的划分
要完成实时多任务的各种功能,必须对任务进行划分。本程序根据各个任务的重要性和实时性,把程序分成六个具有不同优先级的任务,包括系统监控、数据转发、键盘输入、LED显示、接收队列监视和波特率设置。表1为任务划分表。
除了6个主要应用任务之外,还有两个中断服务子程序:一个时钟节拍中断,用于提供周期性信号源;一个CAN接收中断,用于把接收数据写入环形缓冲区。

(2) 任务的同步与调度
通常多任务操作系统的任务不同于一般的函数,它是一个无限循环,而且没有返回值。如果没有更高优先级的任务进入就绪态,当前任务是不会放弃对CPU的使用权的。为了实现操作系统的正常运行和有关事件的同步,必须正确处理任务间的通信和事件标志的设置。整个系统的功能结构如图2所示。

图2系统功能结构
各个任务具有不同的优先级,通过调用系统挂起函数或延时函数,可以启动具有更高优先级的进入就绪态的任务。在嵌入式CAN中继器的设计中,通过对延时参数的设置,系统每隔一定的时钟节拍,就启动接收队列监视任务,定期扫描环形缓冲区。一旦发现读指针与写指针不相等时,就将环形缓冲区中新接收到的数据存入TEMPBUF中,同时发送信号量SendSem。数据转发任务接收到信号量,启动运行,完成数据转发功能。
数据转发任务如下:void CANDATA_ExchangeTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3/* 给CPU状态寄存器分配存储器*/
OS_CPU_SRcpu_sr;
#endif
INT8U err;
pdata=pdata;/*避免编译器警告*/
for(;;) {
OSSemPend (SendSem,0,err);/*等待发送信号量,若无信号则将本函数挂起,并启动其他任务,如系统监控或键盘输入或LED显示等*/
if (CANNUM == CAN1) {/*判断是哪一路总线接收到数据,如是CAN1,则向CAN2发送数据*/
ToSendData (TEMPBUF,FORTXBUF );/*将存放在TEMPBUF中的数据转换成可用于发送的数据格式,存放在FORTXBUF中*/
CanSendData (CAN2,0x00,FORTXBUF);/*向另一路总线发送数据*/
}
else {
ToSendData (TEMPBUF,FORTXBUF );
CanSendData (CAN1,0x00,TXBUF);
}
}
}同样,其他模块功能——波特率的设置、系统的监控、信息的显示等,也是通过任务间的通信—信号量的传递来实现的,以此来保证时间与任务的同步。
结语
μC/OSII实时操作系统在嵌入式硬件平台的基础上,用μC/OSII实时操作系统开发应用程序有其独到之处,用户可以直接利用系统的接口函数编写自己的应用程序,不需另行开发,大大方便了用户编程,缩短了软件的开发周期,提高了开发效率。基于μC/OSII和LPC2119的CAN中继器,在实验调试过程中,运行状况良好,工作稳定。
评论