关于ucos中os_tmr.c中的代码分析
我本身也是个初学者,喜欢嵌入式而自学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()中使用,调用回调函数,但有参数。
4、 Callback 指向回调函数的指针,这个函数这样声明,void mycallback(OS_TMR *ptmr, void p_arg );
5、 Callback_arg 参数给callback的。
6、 Pname 定时器的名字
7、 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中os_tmr.c中的代码分析相关推荐
- 关于《机器学习实战》中创建决策树的核心代码分析
关于<机器学习实战>中创建决策树的核心代码分析 SIAT nyk 2017年10月21日星期六 一.源码内容 def create ...
- vin-slam中调用ceres库内部代码分析与性能优化
vin-slam中调用ceres库内部代码分析与性能优化 1,vin-slam中后端参数优化调用流程代码 2,ceres内部的求解流程(未完待续) 首先,很抱歉前几次上传的关于一些图像算法代码不全,主 ...
- C语言 带参数宏定义中 # 和 ## 知识点总结、代码分析
目录 一.宏定义中 "#"知识点 1.直接转换字符串,不展开. 2.转换出的结果一定是"字符串". 二.宏定义中 ## 知识点 1.应用场景 2."# ...
- AVS3中Intra预测过程 - HPM代码分析
视频编码中,帧内预测需要获取相邻块的参考像素才能获得重建,在AVS3参考软件平台HPM中,这个过程是如何实现的呢? HPM中的map_scu 1.什么是SCU? SCU是Smallest CU的缩写. ...
- OSEA中QRS波检测算法代码分析-未完待续
最近一直在搞R波检测算法,对OSEA代码主要是对注释做一个翻译,增加注释,使代码更容易理解. 一.首先看QRSDE.H /*************************************** ...
- vs 2015 C 语言,VS2015中C/C++代码分析
VS2015中C/C++代码分析 03/31/2015 8 分钟可看完 本文内容 [原文发表时间]:2015/2/24 1:00 PM 来自 Joe Morris & Jim Springfi ...
- 你不知道的常用 代码分析 规范
visual studio有个功能,代码分析,一般开发完毕后,除了处理常规的"错误列表"显示的"错误"和"警告",我们更加应该注意的是,运行 ...
- 【高通SDM660平台 Android 10.0】(10) --- Camera Sensor lib 与 Kernel Camera Probe 代码分析
[高通SDM660平台 Android 10.0]Camera Sensor lib 与 Kernel Camera Probe 代码分析 一.libmmcamera_imx258.so 代码分析 1 ...
- S3C6410开发板LED驱动代码分析及测试代码分析
在本文中,我们对S3C6410开发板LED驱动代码的实现过程进行分析,然后通过一个实例对LED进行控制.在本文的资源中包含了设备驱动的源码和测试的源码. 一.设备驱动源码分析 设备驱动主要实现了模块的 ...
最新文章
- 微信开发-ACCESS TOKEN 过期失效解决方案
- 6264:走出迷宫(DFS和BFS)
- Keepalived设置开机自启
- Linux下实现USB口的热插拔
- solr:关于dismax的使用情况(转:https://my.oschina.net/momohuang/blog/145379)
- Unity3d官方测试插件学习-单元测试,集成测试
- hive 计算周几_HIVE 计算指定日期本周的第一天和最后一天
- 无法复制 文件:无法读源文件或磁盘
- n分频器 verilog_verilog 语言实现任意分频
- 运行服务器(Tomcat)但是到JDBC这一步,一直报错java.lang.NoClassDefFoundError: Could not initialize class DruidDemo
- Xposed小白入门,动态修改IMEI实例代码
- 原神申鹤四星武器选哪个
- Excel手机号如何查询实名认证?
- 从物理意义上了解PCA
- c语言窄字符转换为宽字符,将窄字符串转换为宽字符串
- HDU4355-三分
- 我为什么没有成为华为元老,谈精准学习,避免低水平勤奋
- 虽然分模块了,但是 mapActions 写法,照样可用
- 虚荣 VG API 分析
- 昆仑通态MCGS与3台力士乐VFC-x610变频器通讯程序 实现昆仑通态触摸屏与3台力士乐VFC-x610变频器通讯
热门文章
- 8位小数mysql_纬度/经度(小数点后8位)应使用哪种MySQL数据类型?
- 爱奇艺笔试题——坝上草原滑草
- 使用coding和hexo快速搭建博客
- 一位程序员的一天工作清单:5:30下班,5:30起床
- 使用冰狐智能辅助实现找图(findImage)
- 基于VB编写的电力电缆载流量计算
- java 画图油漆桶_Flood Fill (洪水填充、泛洪填充、油漆桶)算法Java循环实现(BFS方式,非递归)...
- go proxy 快捷的高匿代理抓取工具
- 如何利用js实现选项卡效果(超简单)
- 【Django】debug模式简析