定时器函数优先级μC/OSII中软件定时器的优缺点与改进

μC/OSII中软件定时器的优缺点与改进

时间:2011年12月01日
μC/OSII具有小巧、性能稳定、开源等众多优点,并且μC/OSII大部分用ANSI C语言编写,系统的移植非常容易。在μC/OSII I2.81及以后的版本中[2],加入了对软件定时器的支持,使得μC/OSII操作系 预付款爱达荷公司Hoku美国爱达荷州多晶硅工厂破土动工电池发射器美国科学家研发新型热光伏电池 转换效率大幅提高批评新闻线索邮箱XILINX推出全新解决方案支持未来可编程无线基站用户微软好友Windows Live再添20多家合作伙伴连接器线缆三星2012第十四届上海国际工业展览会通信控制器标准GREENPEAK公司推出 RF 远程控制器 Emerald GP500C批评新闻线索邮箱Atmel宣布推出第一款ARM9处理器英特尔智能手机福特高通CEO:英特尔手机芯片暂不足惧航空障碍太阳能LED的另一个重要应用方向--航空障碍灯
μC/OSII具有小巧、性能稳定、开源等众多优点,并且μC/OSII大部分用ANSI C语言编写,系统的移植非常容易。在μC/OSII I2.81及以后的版本中[2],加入了对软件定时器的支持,使得μC/OSII操作系统更加完善。

  μC/OSII是一种基于优先级的抢占式操作系统,实时性很强。而系统中软件定时器没有优先级,回调函数顺序执行,这样就降低了系统的实时性。因此,本文对软件定时器进行改进,定时器中加入优先级,回调函数按优先级执行,从而提高系统的实时性。

  1 对软件定时器的介绍

  μC/OSII系统中的时间管理功能包括任务延时与软件定时器,而软件定时器的主要作用是,对函数周期性或者一次性执行的定时,利用软件定时器控制块与“定时器轮”管理软件定时器。定时器控制块的结构如同任务控制块,创建一个定时器时,从空闲定时器控制块链表中得到一个空闲控制块,并对其赋值。

  软件定时器也需要一个时钟节拍驱动,而这个驱动一般是硬件实现的,一般使用μC/OSII操作系统中任务延时的时钟节拍来驱动软件定时器。每个时钟节拍OSTmrCtr(全局变量,初始值为0)增1, 当OSTmrCtr的值等于为OS_TICKS_PER_SEC /OS_TMR_CFG_TICKS_PER_SEC(此两者的商决定软件定时器的频率)时,调用函数OSTmrSignal(),此函数发送信号量OSTmrSemSignal(初始值为0,决定软件定时器扫描任务OSTmr_Task的运行)。也就是说,对定时器的处理不在时钟节拍中断函数中进行,而是以发生信号量的方式激活任务OSTmr_Task(具有很高的优先级)。任务OSTmr_Task对定时器进行检测处理,包括定时器定时完成的判断、回调函数的执行。

  μC/OSII 2.86中与软件定时器相关的函数包括:

  ① 软件定时器内部静态函数。获取与释放定时器控制块函数OSTmr_Alloc()、OSTmr_Free();定时器插入相应“时间轮”组函数OSTmr_Link();从相应“时间轮”组中删除定时器函数OSTmr_Unlink();软件定时器任务初始化函数OSTmr_InitTask();定时器扫描任务OSTmr_Task;定时器上锁与解锁函数OSTmr_Lock()与OSTmr_Unlock()(在μC/OSII 2.91中,此两函数被任务调度锁定与解锁函数代替)。

  ② 定时器外部接口函数。定时器创建与删除函数OSTmrCreate()、OSTmrDel();定时器启动与停止函数OSTmrStart()、OSTmrStop();定时器剩余时间与当前状态查询函数OSTmrRemainGet()、OSTmrStateGet();软件定时器的初始化OSTmr_Init();发送信号量OSTmrSemSignal函数OSTmrSignal();定时器名称查询函数OSTmrNameGet()。

  由于软件定时器的回调函数的执行都是在任务OSTmr_Task中执行,如果多个定时器同时定时完成,则在定时器任务中执行多个定时器的回调函数,因此定时器任务的执行时间不确定。而且定时器回调函数是顺序执行的,如果某个定时器回调函数需要尽快执行以实现精确定时,就难以实现了。由于各个定时器没有优先级,因此了影响系统的实时性。

  2 对软件定时器的改进

  为提高软件定时器回调函数执行的实时性,给每个定时器赋予一个优先级。当定时完成时,并且定时器的回调函数不为空,则把定时器的优先级写于软件定时器就绪表中。任务OSTmr_Task对相应“时间轮”检查结束后,如果在扫描各个定时器前软件定时器就绪表为零而扫描之后不为零,则发送信号量激活回调函数任务OSTmr_TaskCallback。在此任务中,回调函数根据软件定时器就绪表中的优先级执行相应的回调函数,这样就提高了系统的实时性。

  2.1 对软件定时器相关数据结构改进

  ① 定义结构体OS_TMR_CALL,存储定时器的回调函数、函数的参数、定时器指针,形式如下:

  typedefstructos_tmr_call {

  OS_TMR_CALLBACKOSTmrCallback; /*回调函数*/

  void *OSTmrCallbackArg;/*回调函数指针*/

  OS_TMR *OSTmr; /*定时器指针*/

  } OS_TMR_CALL;

  在头文件ucos_ii.h中,定义OSTmrCallbackTbl[OS_TMR_CFG_MAX],OS_TMR_CFG_MAX表示系统中配置的软件定时器数量。

  ② 在软件定时器控制块中加入成员变量OSTmrPrio(定时器优先级),删去变量OSTmrCallback(回调函数)、OSTmrCallbackArg(回调函数参数),为了测试的方便,可暂不删除这两个变量。

  ③ 定义定时器就绪表:

  INT8UOSTmrRdyGrp;

  INT8UOSTmrRdyTbl[OS_TMR_CFG_MAX/8 + 1];

  当定时器定时完成时,把定时器优先级写入就绪表,回调函数任务根据优先级执行回调函数。

  ④ 定义信号量OSTmrSemCallback(初始值0 ),当定时完成后,发送此信号量,激活回调函数任务,以执行回调函数。

 2.2 与软件定时器相关的函数函数与任务的改进

  2.2.1 软件定时器创建函数OSTmrCreate

  在创建函数OSTmrCreate的参数中加入优先级参数prio。调用创建函数时,对定时器控制块中的成员变量赋值,并给回调函数数组的相应单元赋值,形式如下:

  OSTmrCallbackTbl [prio].OSTmrCallback = callback;

  OSTmrCallbackTbl [prio].OSTmrCallbackArg = callback_arg;

  OSTmrCallbackTbl [prio].OSTmr = ptmr;

  2.2.2 对定时器任务OSTmr_Task的改进

  当有定时器定时完成,把定时器优先级写入软件定时器就绪表中,并根据就绪表前后的值判断时候发送信号量OSTmrSemSignal,以激活回调函数任务。任务OSTmr_Task的流程如图1所示。

OSTmr_Task的流程



图1 OSTmr_Task的流程

  把定时器优先级写入定时器就绪表的代码如下所示:

  if (OSTmrTime == ptmr>OSTmrMatch) {

  prio = ptmr>OSTmrPrio;

  pfnct =OSTmrCall[prio].OSTmrCallback;

  if (pfnct != (OS_TMR_CALLBACK)0) { /*加入定时器回调函数就绪表*/

  OSTmrRdyGrp|= (INT8U)(1 《 (INT8U)(prio 》 0x03));

  OSTmrRdyTbl[prio >> 0x03]|= (INT8U)(1 《 (INT8U)(prio & 0x07));

  }

  }

  2.2.3 对定时器停止函数OSTmrStop()的修改

  函数OSTmrStop只需修改与回调函数执行相关的部分即可,例如,case OS_TMR_OPT_CALLBACK_ARG: 部分的代码如下:

  case OS_TMR_OPT_CALLBACK_ARG:

  prio = ptmr>OSTmrPrio;

  pfnct = OSTmrCall[prio].OSTmrCallback;

  if (pfnct != (OS_TMR_CALLBACK)0) {

  ……/*prio加入定时器就绪表*/

  OSTmrCall[prio].OSTmrCallbackArg =(void *)callback_arg;

  OSSemPost(OSTmrSemCallback); /*发送回调函数执行信号量*/

  }else {

  *perr = OS_ERR_TMR_NO_CALLBACK;

  }

  而case OS_TMR_OPT_CALLBACK:部分的代码同上,只是回调函数的参数不需要重新赋值。

 2.2.4 回调函数任务OSTmr_TaskCallback()

  在源文件tmr.c中加入回调函数任务OSTmr_TaskCallback(),根据定时器就绪表中的优先级执行相应回调函数,回调函数任务的结构如下所示:

  static voidOSTmr_TaskCallback(void *p_arg) {……/*变量定义*/

  for (;;){//请求信号量OSTmrSemCallback

  OSSemPend(OSTmrSemCallback, 0, &err);

  OSTmr_Lock();/*定时器上锁*/

  while (OSTmrRdyGrp) {

  ……/*从定时器就绪表中得到最高优先级的定时器回调函数*/

  ……/*删除就绪表中的占有位*/

  OSTmr_Unlock(); /*定时器上锁*/

  pfnct = OSTmrCall[prio].OSTmrCallback;

  (*pfnct)((void *)(OSTmrCall[prio].OSTmr),OSTmrCall[prio].OSTmrCallbackArg); /*执行回调函数*/

  OSTmr_Lock(); /*定时器上锁*/

  }

  OSTmr_Unlock();/*定时器解锁*/

  }

  }

  由以上代码可知,访问就绪表时定时器上锁,而执行回调函数时处于定时器解锁状态。如果回调函数执行时间较长,在下一个软件定时器节拍到来时,定时器扫描任务可以得到及时的执行,当前回调函数执行完成后,可以及时得执行就绪表中最高优先级定时器的回调函数。由此可以看出,高优先级定时器的回调函数得到及时执行,系统的实时性提高。

  实验测试发现,在回调函数任务OSTmr_TaskCallback中,使用任务调度上锁与解锁比使用定时器上锁与解锁(即信号量的请求)执行速度快一些。毕竟回调函数任务的优先级很高(一般仅次于定时器扫描任务OSTmr_Task的优先级),所以使用任务调度锁定比定时器锁定要好一些。当然,还可以使用开关中断的方式对就绪表进行访问,可以根据实际情况选择使用哪种方式。

  3 实验测试

  本次实验使用软件开发环境IAR 5.30,以基于CortexM3内核的路虎LPC1768开发板作为硬件实验平台[6],对实时操作系统μC/OSII 2.86进行改进。

  对改进后的操作系统进行测试,在主函数中创建一个启动任务,在启动任务中创建4个周期定时器(系统中“时间轮”数设为4),赋予不同优先级与定时值,每个定时器控制一个LED的闪烁,启动这4个定时器。在启动函数中创建4个任务,每个任务也是控制一个LED灯的闪烁(利用任务延时),之后启动任务挂起。利用μC/OSII CSPY插件观察各定时器的运行情况,如图2所示。

软件定时器运行界面



图2 软件定时器运行界面

  经实验测试,系统运行正常,定时器回调函数得到及时的执行,系统实时性得到很大的提高。

  4 结语

  软件定时器改进后,定时器任务的执行时间确定,仅与同时完成定时的定时器数目有关,对处于就绪表中的定时器回调函数按优先级执行,使高优先级定时器的回调函数得到及时的执行,提高了系统的实时性。

信息产业电子政策信产部:下半年电子信息产业增速将达20%进入太阳能时代 格尔木将变身“光伏城”标签功能芯片恩智浦UHF解决方案为RFID系统提供高性能与多功能QP242与松下MPAV、MPAV2的性价比洛阳太阳能光热太阳能光热产业未来将聚焦产业链竞争通信错误译码基于Atmega16的FEC设计与实现印度半导体市场英飞凌授权印度半导体制造公司130nm CMOS工艺双晶晶体振荡器振荡器Rakon推出可代替OCXO的CDXO我国最大铜箔生产项目在昆山开工
Panasonic KME 松下 CM212-M(NM-EJM6A) Modular Placement Machine 高速模块化贴装机 KXFA1MUBA00 SPACERFUJI 富士 CP7 CP-7 CP-732ME CP-742E CP-742ME CP-752 DCPA0710 SHAFTPanasonic KME 松下 CM212-M(NM-EJM6A) Modular Placement Machine 高速模块化贴装机 CM402(KXF-4Z4C) CM602(NM-EJM8A NM-EJM4A)Modular High Speed Placement Machine 模块化超高速贴片机 KXFB0APXA00 JOINTHitachi 日立 Sanyo 三洋 TCM-X100 6301121130 GUIDE.LINEAR 765KB-010-402FUJI 富士 IP3 IP-III IP-IIIE IP-III-4000 IP-III-5000 PPN1110 PINYamaha 雅马哈 Philips Assembleon 飞利浦 SMT FV GEM Type Feeder Parts 供料器配件 飞达配件 喂料器配件 送料器配件 K87-M22D0-10X REEL HOLDER ASSYPanasonic KME 松下 Next Production Modular NPM XSN2+6VW SCREW Cross recessed Pan head machine screw M2X6-A2-70SIEMENS SIPLACE 西门子 00360407-01 52 WAY VALVE MICRO 833-650101JUKI Zevatech 东京重机 FX-3 High Speed Modular Mounter 高速模块化贴片机 WP0330516SC WASHER 3.3X8X0.5JUKI Zevatech 东京重机 KE-2050 KE-2050R KE-2055R Chip Shooter 高速贴片机 KE-2060 KE-2060R Flexible Mounter 高速通用贴片机 40001070 CONVEYOR BELT C(L)Hitachi 日立 Sanyo 三洋 TIM-5000 6300752830 CORD 741BQ-11D-351SAMSUNG 三星 DP20 NEEDLE 指针 (2012) 3-DP-D20-85-034-4 J2000637JUKI Zevatech 东京重机 KE-2040 High Speed IC Mounter 高速IC贴片机 E1621729000 LOCK UP VALVE BRSONY 索尼 SI-E2000 SI-E1000 MK2 MK3 Compact-Sized Chip Mounter贴片机 PHOTO SENSOR 1-418-703-11Panasonic KME 松下 CM212-M(NM-EJM6A) Modular Placement Machine 高速模块化贴装机 KXFB043YA01 JIG-WORK
1.4688401222229 s