功率电感生产厂家
联系我们
热门搜索
点击排行
推荐阅读
猜猜你喜欢的
技术知识 您所在的位置: 首页 > 技术知识

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

来源:    作者:    发布时间:2015-01-05 10:48:28    浏览量:

  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 = cal共模电感器lback_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].OSTmrCa一体电感器llback;

  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的优先级),所以使用任务调度锁定比定时器锁定要好一些。当然,还可以使用开关中断的方式对就绪表进行访问,可以根据实际情况选择使用哪种方式。

  • 介质损耗/功率因数测试鲜为人知的事实Megger技术支持小组随着变电站电气设备故障率的不断上升,供电公司和重工业必须着手进行预防和预测性维护,确保电力系统的完整性和可靠性。电气绝缘问题是电气设备故障的一个常见原因,而介质损耗/功率损耗/

  • 两个BUCK电路制作的并联电路


    我为什么最后调试的结果是I1为正值,但是I2却为负值了? 是电流I1流向了I2吗? 该怎么解决呢?
    两个并联需要考虑均流的,你的电路里面貌似没有。。。。均流只是这个题目的一部

  • On Semi Q32M210 32位MCU血糖仪应用方案On Semi公司的Q32M210是精密的混合信号32位MCU, 集成了2个16位模数转换器、高精度电压参考、3个10位数模转换器和基于ARM Cortex-M3 32位内核以及高度可配置的模拟前端及

  •