zoukankan      html  css  js  c++  java
  • μC/OS-II 的系统时钟

    简介

    μC/OS-II 与大多数计算机系统一样,用硬件定时器产生一个周期为 ms 级的周期性中断来实现系统时钟,最小的时钟单位就是两次中断之间相间隔的时间,这个最小时钟单位叫做时钟节拍(Time Tick)。
    硬件定时器以时钟节拍为周期定时地产生中断,该中断的中断服务程序叫做 OSTickISR( )。中断服务程序通过调用函数 OSTimeTick( ) 来完成系统在每个时钟节拍时需要做的工作。

    系统时钟中断服务程序

    void OSTickISR(void)
    {
    	保存CPU寄存器;
    	调用OSIntEnter( );			       
    	if (OSIntNesting == 1;				
    	{
    		OSTCBCur->OSTCBStkPtr = SP; //保存堆栈指针
    	}
    	调用OSTimeTick( );			       
    	清除中断;
    	开中断;
    	调用OSIntExit( );			       
    	恢复CPU寄存器;
    	中断返回;
    }
    

    时钟节拍服务函数

    void  OSTimeTick (void)
    {
    	……
        OSTimeTickHook( );
    	……
        OSTime++;		//记录节拍数
        ……
        if (OSRunning == TRUE) {    
                ptcb = OSTCBList;
                while (ptcb->OSTCBPrio != OS_IDLE_PRIO) 
                {
                    OS_ENTER_CRITICAL( );
                    if (ptcb->OSTCBDly != 0) 
        	        {
                        if (--ptcb->OSTCBDly == 0) //任务的延时时间减一
        	            {
                            if ((ptcb->OSTCBStat & OS_STAT_SUSPEND)
                                            == OS_STAT_RDY) 
        	                { 
                                OSRdyGrp |= ptcb->OSTCBBitY;
                                OSRdyTbl[ptcb->OSTCBY]
                                                               |= ptcb->OSTCBBitX;
                            } else {
                                ptcb->OSTCBDly = 1;
                            }
                        }
                    }
                    ptcb = ptcb->OSTCBNext;
                    OS_EXIT_CRITICAL( );
                }
        } 
    }
    

    函数 OSTimeTick( ) 的任务,就是在每个时钟节拍了解每个任务的延时状态,使其中已经到了延时时限的非挂起任务进入就绪状态。

    任务的延时

    由于嵌入式系统的任务是一个无限循环,并且 μC/OS-II 还是一个抢占式内核,所以为了使高优先级别的任务不至于独占 CPU,可以给其他任务优先级别较低的任务获得 CPU 使用权的机会,μC/OS-II 规定:除了空闲任务之外的所有任务必须在任务中合适的位置调用系统提供的函数 OSTimeDly( ),使当前任务的运行延时(暂停)一段时间并进行一次任务调度,以让出 CPU 的使用权。

    系统提供的延时函数

    void  OSTimeDly (INT16U ticks)
    {
        INT8U      y;
    #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register */
        OS_CPU_SR  cpu_sr = 0;
    #endif
    
        if (ticks > 0) {                             /* 0 means no delay! */
            OS_ENTER_CRITICAL();
            y            =  OSTCBCur->OSTCBY;        /* Delay current task */
            OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
            if (OSRdyTbl[y] == 0) {
                OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
            }
            OSTCBCur->OSTCBDly = ticks;              /* Load ticks in TCB */
            OS_EXIT_CRITICAL();
            OS_Sched();                              /* Find next task to run! */
        }
    }
    

    取消任务延时函数

    INT8U  OSTimeDlyResume (INT8U prio)
    

    获得系统时间函数

    INT32U  OSTimeGet (void)
    

    设置系统时间函数

    void  OSTimeSet (INT32U ticks)
    

    参考自:《μC/OS-II 入门教程》

  • 相关阅读:
    Linux下通过.desktop 文件创建桌面程序图标及文件编写方式(Desktop Entry文件概述)
    Ubuntu16.04进入挂起或休眠状态时按任何键都无法唤醒问题解决办法
    Ubuntu16.04+Gnome3 锁定屏幕快捷键无效解决办法
    A start job is running for Raise network interface(5min 13s )问题解决方法
    Ubuntu16.04 “有线未托管”有线网络不可用问题解决
    A start job is running for Network Manager wait online (29s / no limit) 等待30s解决办法
    Linux 串口终端调试工具minicom
    Linux 终端仿真程序Putty
    Oracle:在 debian9 上完美安装 oracle 10.2.0.5 x64
    从debian9、ubuntu18.04的deb包依赖来看,似乎不是那么好!!
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/8711780.html
Copyright © 2011-2022 走看看