zoukankan      html  css  js  c++  java
  • uCOS的软件定时器、uCOS时钟节拍和滴答定时器的关系

    uCOS2.81后的版本中有软件定时器的概念,如果要开启定时器任务,需要在OS_CFG.H文件中 #define  OS_TMR_EN                 1

    软件定时器其实跟硬件中断是相似的,定时时间到了,就执行一次回调函数,虽然好用,但是也会降低系统的实时性。
    软件定时器也需要一个时钟节拍驱动,这个驱动也是由硬件实现的,一般使用uCOS中的任务延时节拍驱动来驱动软件定时器,每个时钟节拍OSTmrCtr(全局变量,初始值为0)加1,当OSTmrCtr的值等于OS_TICKS_PER_SEC /OS_TMR_CFG_TICKS_PER_SEC(前者是ucos节拍频率,后者是软件定时器的节拍频率,相当于分频)时,调用函数OSTmrSignl()函数,发送信号量OSTmrSemSignal(初始值0,决定软件定时器扫描任务OSTmr_Task的运行),也就是说,对软件定制器的处理不在时钟节拍中断函数中执行,而是以发生信号量的方式激活任务OSTmr_Task,任务OSTmr_Task对定时器进行检测,包括定时器定时完成的判断,回调函数的执行。

     举例来讲,ucos中的OS_TICKS_PER_SEC设定值为1000(最大),OS_TMR_CFG_TICKS_PER_SEC为100,则可知uCOS的节拍时间为1ms,软件定时器的节拍时间为1000/100*1=10ms

     在软件定时器的生成函数中:


    OS_TMR  *OSTmrCreate (INT32U           dly,
                          INT32U           period,
                          INT8U            opt,
                          OS_TMR_CALLBACK  callback,
                          void            *callback_arg,
                          INT8U           *pname,
                          INT8U           *perr)
    其中dly表示第一次延时时间节拍数(软件定时器节拍,不是ucos的节拍)
    period表示重复节拍数,如果设定dly为10,period为20,opt设定OS_TMR_OPT_PERIODIC,则表示这是1个重复执行软件定时器,第一次执行定时时间为10x10=100ms,以后每隔20x10=200ms的间隔时间执行回调函数。

    uCOS2.81后的版本中有软件定时器的概念,软件定时器其实跟硬件中断是相似的,定时时间到了,就执行一次回调函数,虽然好用,但是也会降低系统的实时性。
    软件定时器也需要一个时钟节拍驱动,这个驱动也是由硬件实现的,一般使用uCOS中的任务延时节拍驱动来驱动软件定时器,每个时钟节拍OSTmrCtr(全局变量,初始值为0)加1,当OSTmrCtr的值等于OS_TICKS_PER_SEC /OS_TMR_CFG_TICKS_PER_SEC(前者是ucos节拍频率,后者是软件定时器的节拍频率,相当于分频)时,调用函数OSTmrSignl()函数,发送信号量OSTmrSemSignal(初始值0,决定软件定时器扫描任务OSTmr_Task的运行),也就是说,对软件定制器的处理不在时钟节拍中断函数中执行,而是以发生信号量的方式激活任务OSTmr_Task,任务OSTmr_Task对定时器进行检测,包括定时器定时完成的判断,回调函数的执行。

     举例来讲,ucos中的OS_TICKS_PER_SEC设定值为1000(最大),OS_TMR_CFG_TICKS_PER_SEC为100,则可知uCOS的节拍时间为1ms,软件定时器的节拍时间为1000/100*1=10ms

     在软件定时器的生成函数中:


    OS_TMR  *OSTmrCreate (INT32U           dly,
                          INT32U           period,
                          INT8U            opt,
                          OS_TMR_CALLBACK  callback,
                          void            *callback_arg,
                          INT8U           *pname,
                          INT8U           *perr)
    其中dly表示第一次延时时间节拍数(软件定时器节拍,不是ucos的节拍)
    period表示重复节拍数,如果设定dly为10,period为20,opt设定OS_TMR_OPT_PERIODIC,则表示这是1个重复执行软件定时器,第一次执行定时时间为10x10=100ms,以后每隔20x10=200ms的间隔时间执行回调函数。

    ===========================================
    uCOS时钟节拍和滴答定时器的关系

    在使用uCOS时,有一个非常重要,非常关键的概念就是操作系统的时钟节拍,uCOS的时钟节拍来源于滴答定时器,滴答定时器按照设定的时间不停的计时和产生中断,在uCOS-III中滴答定时器的中断服务函数如下:


    void  OS_CPU_SysTickHandler (void)
    {
        CPU_SR_ALLOC();
     
        CPU_CRITICAL_ENTER();
        OSIntNestingCtr++;                           /* Tell uC/OS-III that we are starting an ISR */
        CPU_CRITICAL_EXIT();
     
        OSTimeTick();                                /* Call uC/OS-III's OSTimeTick() */
     
        OSIntExit();                                /* Tell uC/OS-III that we are leaving the ISR */
    }

    其中OSTimeTick();的作用是检查每个任务的任务控制块中OSTCBDly减1后是否为0(翻译过来就是检查任务延时函数OSTimeDly中的节拍数是否减为0了),如果是,则表明这个任务刚才是挂起状态,此时应变为就绪态,接着在任务中OSTimeDly函数进行一次任务调度。
    所以可以得出一个重要关系:

    滴答定时器的中断时间  =  uCOS的1个节拍时间

    这个节拍就是OSTimeDly (OS_TICK dly, OS_OPT opt,OS_ERR *p_err)函数中的dly。

    在uCOS-III中针对节拍的时间有如下定义:

    /* ------------------------ TICKS ----------------------- */
     #define  OS_CFG_TICK_RATE_HZ            1000u        /* Tick rate in Hertz (10 to 1000 Hz)                     */
     
    这个OS_CFG_TICK_RATE_HZ表示节拍的频率,如果设定为1000,则表示频率为1000Hz,则1个节拍为1ms。
    那么问题来了,如果想要uCOS-III的节拍时间为1ms,如何设定滴答定时器的reload数值呢?

    通过上面的分析可知,我们只需要设定滴答定时器的中断时间为1ms即可,以STM32为例,典型的系统时钟频率为72MHz(外部晶振选择为8MHz),滴答定时器时钟源也选择为HCLK(不是除以8),

    则滴答定时器计数1次的时间为:1/72000000 s

    要想中断时间为1ms = 1/1000 s,则reload = (1/10000)/(1/72000000) = 72000

    而72000 = 72000000(系统时钟)/1000(OS_CFG_TICK_RATE_HZ)

    所以在设定滴答定时器初始化函数时,只需设定:

    SysTick_Config(SystemCoreClock/OS_CFG_TICK_RATE_HZ);  

    就能满足uCOS-III想要的节拍时间了。

    摘自:https://blog.csdn.net/u012351051/article/details/51262503

  • 相关阅读:
    基于 RocketMQ Prometheus Exporter 打造定制化 DevOps 平台
    RocketMQ-Console安装及RocketMQ命令行管理工具介绍
    RocketMQ之一:RocketMQ整体介绍
    Prometheus 监控之 zookeeper
    详解MySQL数据类型
    Linux2:Linux目录结构
    再谈AbstractQueuedSynchronizer3:基于AbstractQueuedSynchronizer的并发类实现
    再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现
    Java虚拟机15:再谈四种引用状态
    再谈AbstractQueuedSynchronizer1:独占模式
  • 原文地址:https://www.cnblogs.com/CodeWorkerLiMing/p/12007426.html
Copyright © 2011-2022 走看看