Newtank

个人站

欢迎来到我的个人站~


定时器管理

目录

中断处理

响应中断条件

有中断源发出中断信号;中断信号未被屏蔽

ISR框架

  1. 保存所有寄存器的值
  2. 调用OSIntEnter(),或直接将全局变量OSIntNesting加1
  3. 执行用户代码进行中断服务
  4. 调用OSIntExit()
  5. 恢复所有寄存器的值
  6. 调用中断返回指令

时钟节拍

时钟ISR

  1. 保存处理器寄存器的值
  2. 调用OSIntEnter()或将OSIntNesting加1
  3. 调用OSTimeTick()
  4. 调用OSIntExit()
  5. 恢复处理器
  6. 执行中断返回

OSTimeTick()

void OSTimeTick (void)
{
	OS_TCB *ptcb;
	OSTimeTickHook(); (1)
	ptcb = OSTCBList; (2)
	while (ptcb->OSTCBPrio != OS_IDLE_PRIO) { (3)
		OS_ENTER_CRITICAL();
		if (ptcb->OSTCBDly != 0) {
			if (--ptcb->OSTCBDly == 0) {
				if (!(ptcb->OSTCBStat & OS_STAT_SUSPEND)) { (4)
					OSRdyGrp |= ptcb->OSTCBBitY; (5)
					OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
				} else {
					ptcb->OSTCBDly = 1;
				}
			}
		}
		ptcb = ptcb->OSTCBNext; OS_EXIT_CRITICAL();
	}
	OS_ENTER_CRITICAL(); (6)
	OSTime++; (7)
	OS_EXIT_CRITICAL();
}

OSTimeDLY()

任务延时函数,申请该服务的任务可以延时一段时间。调用后,任务进入等待状态

void OSTimeDly (INT16U ticks) {
	if (ticks > 0){
	OS_ENTER_CRITICAL();
	if ((OSRdyTbl[OSTCBCur->OSTCBY] &=
		~OSTCBCur->OSTCBBitX) == 0) {
		OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
	}
	OSTCBCur->OSTCBDly = ticks;
	OS_EXIT_CRITICAL();
	OSSched();
	}
}

该函数存在占用问题导致实际延迟时间抖动

该任务期望延时10ms(1tick),但最后只延时5ms

或是

高优先级任务的不确定性导致实际延时抖动

解决方案:尽可能优化软硬件性能

定时器的启动

系统定时器应该在多任务系统启动以后再启动,即调用OSStart()之后。

使用OSRunning变量控制运行