关于ucos中os_tmr.c中的代码分析

发布者:HarmonyJoy最新更新时间:2015-12-24 来源: eefocus关键字:ucos  代码分析 手机看文章 扫描二维码
随时随地手机看文章
 我本身也是个初学者,喜欢嵌入式而自学ucos系统,ucos是个开源的代码,短小而又简单,这是我学习的笔记,希望能对喜欢ucos的人有一点帮助,因本人也是初学者,如有错误迎指点。一般的书多是2.5版本,没有os_tmr.c,所以我写了关于这部分代码的分析。
我读ucos.中的os_tmr.c:
         我想这个文件里就是为了写一个建立在操作系统的定时器,原来我们学的时钟节拍就像cpu总线时钟脉冲一样。我们建立的是定时器结构体,在os_tmr.c中有一个函数OSTmr_Task()这个函数对定时器结构体的信息进行处理,在定时时间到了时候,该定时器中的一个指向回调函数的指针就调用这个回调节器函数进行工作,当然,你要写回调函数,不然就什么也不做,以前做过ucos移植的人知道要写一个硬件定时器中断函数,这回要加个OSTmrSignal()这里有个发送信号。我们学硬件时知道,用到硬件定时器时要给它一个计算脉冲。这个软件定时器也要一个计算脉冲。我们建立的定时器结构体都会挂到OSTmrWheelTbl[OS_TMR_CFG_WHEEL_SIZE]上面,OS_TMR_CFG_WHEEL+SIZE是要自己定义的,至于挂到OSTmrWheelTbl[0] 到OSTmrWheelTbl[OS_TMR_CFG_WHEEL_SIZE-1]哪一个上,只要看一下OSTmr_Link (OS_TMR *ptmr, INT8U type)就明白了,而且一个OSTmrWheelTbl[n]上可以挂很多个定时器结构体。
一、定时器的建立:
         定时器是在我们的应用程序中建立的,
OS_TMR  *OSTmrCreate (INT32U           dly,
                      INT32U           period,
                      INT8U            opt,
                      OS_TMR_CALLBACK  callback,
                      void            *callback_arg,
                      INT8U           *pname,
                      INT8U           *perr)
想使用定时器那些函数要在os_cfg.h中定义 OS_TMR_EN。
返回值是os_tmr结构体(定义在ucos_ii.h中)。
typedef  struct  os_tmr {
INT8U            OSTmrType;                      
OS_TMR_CALLBACK  OSTmrCallback;                  
void            *OSTmrCallbackArg;               
void            *OSTmrNext;                     
    void            *OSTmrPrev;
INT32U           OSTmrMatch;                 当 OSTmrTime == OSTmrMatch 定时器到时间了。  
INT32U           OSTmrDly;                       
INT32U           OSTmrPeriod;                    
#if OS_TMR_CFG_NAME_EN > 0u
INT8U           *OSTmrName;                     
#endif
INT8U            OSTmrOpt;                      
INT8U            OSTmrState;                     
                                                         
                                   
} OS_TMR;
OSTmrType类型定义在ucos_ii.h中:OS_TMR_TYPE
OS_ARG_CHK_EN要在os_cfg.h中定义一下,来确定要不要一些功能。
OS_TMR_CFG_NAME_EN要你自己在os_cfg.h中定义,来控制要不要用OSTmrName
OSTmrState在ucos_ii.h中有以下几种类型:
       OS_TMR_STATE_UNUSED   不存在这个定时器                                    
       OS_TMR_STATE_RUNNING  这个定时器正在运行 
           OS_TMR_STATE_COMPLETED这个定时器已经跑完了                                 
       OS_TMR_STATE_STOPPED   这个定时器停止了  
参数:
  1. Dly            定时时间,如果是这个定时器只用一次,那么就用这个,如果定时器要反复用那么它是第一次时用,以后用period。
  2. Period       定时器从复用时会用到这个作定时时间。
  3. Opt           这里有两种选项,告诉我们是只用一次还是反复使用。只用一次OS_TMR_OPT_ONE_SHOT,反复使用OS_TMR_OPT_PERIODIC。这些定义在ucos_ii.h中。
定时器选项有五种
#define  OS_TMR_OPT_NONE                    0u    没有选择
#define  OS_TMR_OPT_ONE_SHOT                1u    定时器不会自动重复使用
#define  OS_TMR_OPT_PERIODIC                   2u    定时器会自动重装
#define  OS_TMR_OPT_CALLBACK                  3u    OSTmrStop()中使用,调用回调函数,但不带参数
#define  OS_TMR_OPT_CALLBACK_ARG            4u     也是OSTmrStop()中使用,调用回调函数,但有参数。
  1. Callback    指向回调函数的指针,这个函数这样声明,void mycallback(OS_TMR *ptmr,  void p_arg );
  2. Callback_arg      参数给callback的。
  3. Pname      定时器的名字
  4. Perr      错误指针*         OS_ERR_NONE                           没有错误
                               OS_ERR_TMR_INVALID_DLY                 无效的定时时间
                               OS_ERR_TMR_INVALID_PERIOD              无效的周期
                               OS_ERR_TMR_INVALID_OPT                                   无效的选项
                                OS_ERR_TMR_ISR                         在中断中调用
                               OS_ERR_TMR_NON_AVAIL                  空的定时器用光了,这个和task一样意思。
用到的函数OSTmr_Alloc()得到一个定时器结构体。
二、删除一个定时器,也是在我们的功能函数中使用,返回为是否成功删除。
BOOLEAN  OSTmrDel (OS_TMR  *ptmr,
                   INT8U   *perr)
  1. Ptmr  指向定时器结构体。
  2. Perr   指向错误的指针。
这里用到这两个函数OSTmr_Unlink(ptmr);  如果是定时器在工作时,要用它解除 OSTmrState= OS_TMR_STATE_STOPPED。                        
                   OSTmr_Free(ptmr);   释放这个定时器结构体。
三、得到定时器名字的函数,返回名字的长度。
INT8U  OSTmrNameGet (OS_TMR   *ptmr,
                     INT8U   **pdest,  指向了一个指向定时器名字地址指针的指针。
                     INT8U    *perr)
四、定时器还有多长时间溢出。返回还有多长时间溢出。
INT32U  OSTmrRemainGet (OS_TMR  *ptmr,
                        INT8U   *perr)
五、获得定时器状态的函数,返回状态。             
INT8U  OSTmrStateGet (OS_TMR  *ptmr,
                      INT8U   *perr)
六、启动你的定时器,返回是否成功启动。            你的应用程序使用它
BOOLEAN  OSTmrStart (OS_TMR   *ptmr,              要用到OSTmr_Unlink()和OSTmr_Link()先
                     INT8U    *perr)散             解除,再重新用这个定时器
七、停止定时器,返回是否成功停止。               你的应用程序使用它 
BOOLEAN  OSTmrStop (OS_TMR  *ptmr,
                    INT8U    opt,
                    void    *callback_arg,   这个也是个函数
                    INT8U   *perr)
回调函数在这里使用,callback()。
Opt 为OS_TMR_OPT_NONE不使用回调函数。
OS_TMR_OPT_CALLBACK使用回调函数不用参数。
OS_TMR_OPT_CALLBACK_ARG要使用参数。
八、发送信号,这个是在timer tick中使用要您写到ISR中
INT8U  OSTmrSignal (void)返回信号量。
九、从定时器池中得到一个结构体。在建构函数中用
static  OS_TMR  *OSTmr_Alloc (void);
十、释放定时器,中删除函数中用
static  void  OSTmr_Free (OS_TMR *ptmr)
十一、OSTmr_Init(void),在OSInit()中用。
十二、static  void  OSTmr_InitTask (void)在OSTmr_Init中使用。用来建立一个任务OSTmr_Task()
十三、OSTmr_Task()这个是调度你建立的定时器用的,一但定时时间到就调用回调函数。
我们建立的定时器都进入定时器轮盘里OSTmrWheelTbl[],
十四、static  void  OSTmr_Link (OS_TMR  *ptmr,         //OSTmrState = OS_TMR_STATE_RUNNING
                          INT8U    type)
Ptmr->OSTmrMatch的确定方法   
if (type == OS_TMR_LINK_PERIODIC) {                          
        ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime;
    } else {
        if (ptmr->OSTmrDly == 0) {
            ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime;
        } else {
            ptmr->OSTmrMatch = ptmr->OSTmrDly    + OSTmrTime;
        }
    }
挂载定时器时spoke  = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE);
pspoke = &OSTmrWheelTbl[spoke];这样确定的置位,当OSTmrTime加到和OSTmrMatch相等时一定会来以这个spoke为下标的数组里找该定时器。至于定义一个OSTmrWheelTbl[]而不是把你所有建立的定时器串成一串是怕一起处理浪费时间吧,这样可以一次少处理几个定时器。
我想看了OSTmr_Task (void *p_arg)这个函数的人可能会好奇为什么用那种方法挂载定时器,当定时时间到了时会找到OSTmrWheelTbl[]正确的下标,并在那个OSTmrWheelTbl[ok]里找到该定时器吧。其实你可以算一下,定义OS_TMR_CFG_WHEEL_SIZE=8,然后在OSTmrTime=6时建立一个定时器(假如定时器只工作一次),OSTmrDly=12,那个这个定时器会挂到OSTmrWheelTbl[2]中,当OSTmrTime加到18时它就会去
OSTmrWheelTbl[2]找该定时器。
十五、static  void  OSTmr_Unlink (OS_TMR *ptmr)释放定时器结构体用它把该定时器从定时器轮中卸下。 
关键字:ucos  代码分析 引用地址:关于ucos中os_tmr.c中的代码分析

上一篇:#ifdef DEBUG;debug();#endif
下一篇:IAR for MSP430 关于添加自定义头文件的两种方法

推荐阅读最新更新时间:2024-03-16 14:41

高速快充USB Type-C来袭 统一接口的江湖
  从1996年USB1.0出现至今,已经近20年的历程,而接口速率也从USB1.0发展至USB3.1。每一次版本的革新都带来了更高速的传输速率。USB传输速度从1.0(1.5Mbps)、2.0(480Mbps)、3.0(5Gbps),发展到今天最大传输速度10Gbps,在速度革新的同时,每一代USB接口类型也在随之进化发展,而USB3.1 Type-C接口的出现对于移动设备将会起到很重要的作用,从目前来看,USB3.1中的Type-C最有可能成为未来的连接标准,提供数据传输、外设连接、显示输出、快速充电等一体化的连接方案。   最直观的感受就是在世界瞩目的苹果新品发布会上,其最新发布的MacBook端口进行了改变,整个机子没有任
[嵌入式]
一种基于C8051单片机的SPWM波形实现方案
1 引言   正弦脉宽调制(SPWM)技术已在交流调速、直流输电、变频电源等领域得到广泛应用,为了提高整个系统的控制效果,高性能SPWM脉冲形成技术一直是人们不断探索的问题。采用模拟电路和数字电路等硬件电路来产生SPWM波形是一种切实可行的方法,但是这种实现方法控制电路复杂、抗干扰能力差、实时调节较困难。近年来,人们提出了由单片机、DSP等微控制器来实现SPWM波形的数字控制方法 ,由于微控制器内部集成了很多控制电路,比如定时器、PWM电路、可编程计数器阵列等,所以使得这种实现SPWM的方法具有控制电路简单、运行速度快、控制精度高、抗干扰能力强等优点。本文介绍了一种利用C8051单片机实现输出频率可变SPWM波形的方法,并将由C
[单片机]
一种基于<font color='red'>C</font>8051单片机的SPWM波形实现方案
基于AT89C2051单片机和GPS技术实现机器人定位模块的设计
1 引言 定位是根据先验的环境信息,结合当前的机器人位置信息以及传感器输入信息,准确地确定机器人位姿的过程。可靠定位是移动机器人研究中备受关注和富有挑战性的一个重要研究主题。 机器人定位技术可分为绝对定位和相对定位技术两类,绝对定位主要采用导航信标、主动或被动标识、地图匹配或卫星导航技术(GPS) 进行定位。相对定位是通过测量机器人相对于初始位置的距离和方向来确定机器人的当前位置,通常也称为测程法。绝对定位和相对定位各有优缺点,具有互补性,将两者结合能形成更加准确可靠的定位系统。本实验模块的设计就是先用测程法进行相对定位,然后利用电子罗盘进行纠正。 2 定位原理及硬件设计 2.1定位原理 本设计对应的机器人是前后轮独立驱动的,
[单片机]
基于AT89<font color='red'>C</font>2051单片机和GPS技术实现机器人定位模块的设计
89C52单片机串行通信编程两则
1.当89C52串行口按工作方式1进行串行数据通信时,假定波特率为1 200b/s,以中断方式传送数据,请编写全双工通信程序。 #include at89x52.h unsigned char data txbuf; unsigned char data rebuf; void main() { unsigned char temp; SCON=0x50; TMOD=0x20; TH1=0xE8; TL1=0xE8; TR1=1; ES=1; EA=1; } void comre() { rebuf=SBUF; } void comtx() { SBUF=txbuf;
[单片机]
c51中断优先级c语言,51单片机的中断优先级及中断嵌套
说最基本的,老的51单片机(80C51系列)有5个中断源,2个优先级,可以实现二级中断服务嵌套。现在很多扩展的51单片机已经有4个优先级(或更多)和更多的中断源了。 在说到中断之前,我先来定义一下优先级,明白了什么是优先级,后面的阐述就容易明白了。实际上很多人都是混淆了优先级的含义,所以才觉得糊里糊涂。 中断的优先级有两个:查询优先级和执行优先级。 什么是查询优级呢?我们从datasheet或书上看到的默认(IP寄存器不做设置,上电复位后为00H)的优先级: 外部中断0 定时/计数器0 外部中断1 定时/计数器1 串行中断 或 int0,timer0,int1,timer1,serial port 或 INT0、T
[单片机]
80C51单片机产生几种基本波形的方法
  简介:介绍了基于80C51单片机产生几种基本波形的方法。采用微处理器兼容的14位数模转换器MAX7534,高速,稳定,具有良好的线性。用户通过按键选择输出需要的波形,波形精度能够满足一般的使用条件。   本文利用80C51单片机外接数模转换器和I/V转换电路,由用户通过按键选择输出实验中经常使用到的几种基本波形:方波、锯齿波、正弦波。方波由80C51单片机内部自带的计数器/定时器产生,并由用户通过小键盘选择波形周期。与微处理器兼容的14位数模转换器MAX7534将数字量转换为模拟量电流信号,通过I/V转换电路得到双极性的锯齿波和正弦波信号,波形保证了他的精度和平滑、稳定。   1硬件电路设计   80C51单片机时钟电
[单片机]
80<font color='red'>C</font>51单片机产生几种基本波形的方法
双异步串口经AT89C2051与TMS320VC5402HPI口通信的解决方案
    摘要: 提出了两个微机串口与DSP处理器(TMS320VC5402)HPI(Host Port Interface)口通信问题的解决方案,该方案采用单片机(AT89C2051)实现数据的串/并、并/串转换,并控制DSP的HPI实现共享总线。给出了硬件连接电路和用FPGA作为总线仲裁器的设计思路,介绍HPI口的操作过程,单片机与微机串口之间通信的硬件设计方法。     关键词: DSP 单片机 HPI 串行通信 FPGA 本文所介绍的是我所正在研制的卫星CDMA接收机未端DSP与微机串口通信的接口电路。由于CDMA接收机支持两个独立CDMA信道的接收,并将两路解调后的数据分别经串口送至不同的计算机
[网络通信]
CY7C53120神经元芯片及其应用
    摘要: 由Cypress公司和Toshiba公司制造的神经元芯片CY7C53120是组成LonWorks控制网络的核心。其芯片内集成了介质访问控制、网络管理、控制应用等三个处理器,且内嵌LonTalk协议,并在ROM固件映像中包含先编好的I/O驱动程序和网络操作系统。文中介绍了CY7C53120的内部结构、特点及具体应用。     关键词: 神经元芯片 LonWorks控制网络 LonTalk协议 固件 CY7C53120 1 概述 CY7C53120神经元芯片内集成了三个处理器,这是LonWorks控制网络的核心单元,网络中所有节点的介质访问控制、网络管理、控制应用均由它完成。CY7C53120
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved