这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 软件与操作系统 » 【8.05更新μTenux工程下1-wire总线器件二叉树算法驱动有视频+μTe

共69条 4/7 |‹ 2 3 4 5 6 7 跳转至
高工
2013-07-03 00:25:16     打赏
31楼

实验十 系统时间管理

驱动过外围芯片的筒子们都知道,芯片的时序是非常重要的,其实指的无非就是高低电平保持的时间和出现的顺序。尤其是各类总线器件,对时序的要求相当严苛。

那么对于一个操作系统而言,时间管理就显得尤为重要了。

μTenux提供的时间管理函数很简单,不过这里要整清楚系统时间和工作时间。

个人理解,系统时间是指上电初始化后,系统保存的时间,如果芯片自带RTC和电池的话,可以通过修改系统初始化,让系统保存真实世界的时间,那么每次调用tk_get_tim函数,将获得真实世界的时间,如果没有RTC或者支持RTC工作的电池,系统时间则为默认的1985年1月1日0点0时0分;而工作时间是指系统上电后,芯片会不断计时,每次调用tk_get_otm函数,将获得系统自上电以来经历的时间。

理清这两个概念,μTenux的基本时间管理就比较简单了。

实验代码调用的是tk_get_otm,那么获取的时间就应该是上电以来系统经历的时间。

上实验结果图

SYSTIM定义了高位和低位,低位保存时分秒,高位保存年月日。

我这里把高低位全部打印输出,实验代码调用tk_get_otm后,SYSTIM全为0,系统从0开始计时。



实验十 思考题


1) 如果把获取系统工作时间的 tk_get_otm 函数更换为获取系统时间的 tk_get_t im 函数,结果如何 ?
如果直接简单的把tk_get_otm更换为tk_get_tim,其实系统运行的结果和之前的是一样的,没变化。

这里有一点点没有想清楚,内核规范上所写“系统时间表示成从 1985 年 1 月 1 日 0:00:00(GMT) 开始以 ms 为单位的累加”,意思是说如果没有设置系统时间,那么默认时间应该是1985 年 1 月 1 日 0:00:00,但是实际试验的结果是从0000年00月00日0点0分0秒开始计时的。

如果我们调用tk_set_tim来设置系统时间,那就可以获得真实世界的时间了。

修改代码:

增加y、m、d代表年月日(大侠们不要吐槽变量命名方式)

直接将十进制数20130702赋值给otm.hi,用最粗俗的算法,计算年月日。

时分秒的计算比较坑,我尝试了一下,发现算法是这样:otm.lo=(小时*3600+分钟*60+秒)*1000+毫秒.

如果要从22点26分5秒开始作为系统时间,那么otm.lo=(22*3600+26*60+5)*1000+0=80766000=0x4d06340.

run......


2) 如果开发板带 RTC 电池,使用 tk_get_otm 函数和 tk_get_t im 函数的程序结果有没有不同?

手头上的sam3s4c芯片虽然支持RTC,但开发板没有带RTC电池。如果有的话,在系统初始化时调用相关函数,SYSTIM就能共RTC模块获取数据,应该就能始终保持实时的时间。那么调用tk_get_otm 函数和 tk_get_tim 函数,得到的结果肯定就不一样了。个人认为,tk_get_tim受到系统所保存时间的影响,而tk_get_otm只受系统上电时刻的影响。

为了验证想法,调用tk_set_tim模拟系统有RTC电池,然后同时调用tk_get_otm 函数和 tk_get_tim 函数并打印相关信息。

run..run...run......


从结果来看,系统运行时间和系统时间的概念就能很容易厘清了。

如果有RTC电池,这两者的结果肯定就不一样咧。


TBC......



高工
2013-07-03 00:25:37     打赏
32楼
消灭本页0回复。

菜鸟
2013-07-03 09:12:38     打赏
33楼

实验做的蛮快的,好帖子必须顶!!


高工
2013-07-03 11:53:42     打赏
34楼
每天都是0点到1点之间发帖!这习惯,这作风!老王必须奖励

高工
2013-07-05 00:16:09     打赏
35楼

高工
2013-07-05 01:02:44     打赏
36楼

实验十一 周期性处理

这个实验很简单,主要为了验证周期性的调用任务这种功能。

我个人理解可以看成一种定时软中断,一旦一个周期结束,软中断就会调用相关的任务或函数,实验代码里面是CycHandler()。

这里不得不提两个概念:周期时间和周期相位。

周期时间,是指相邻2次激活的时间间隔;而周期相位,则是指调用tk_cre_cyc到第一次激活的时间间隔。

周期相位是个很有意思的咚咚,要吃透它,还得仔细看看讲义和内核规范。

这里要注意,一个周期性处理任务没有被激活,调用tk_sta_cyc也是无法使它运行的。

如果cycatr里面没有指定TA_PHS,那么系统会在调用tk_cre_cyc后经过cycphs时间(也就是周期相位)后,由tk_sta_cyc来激活和运行;如果cycatr里面指定了TA_PHS,那么调用tk_cre_cyc后经过cycphs时间(也就是周期相位)后,周期性处理任务会一直保持在激活状态,等待tk_sta_cyc来调用。貌似系统默认的是TA_STA,也就是一旦创建周期性处理任务,立马激活。

可以尝试验证一下这个分析,实验代码中总的时间是20S,如果我们将ccyc.cycphs赋值为5000000mS并将ccyc.cycatr=TA_HLNG|TA_PHS,那么周期性任务CycHandler()在整个程序时间内一直未被激活,即使调用tk_sta_cyc,它也无法运行。

上图:


系统压根就没执行CycHandler(),这个周期相位就很好理解了。

实验代码里面有个延时函数Delay(CFN_TIMER_CLOCK*1000*1000);值得引起注意,查看定义

EXPORT void Delay(UW count)
{
    for(;count>0;count--);
}

#define CFN_TIMER_CLOCK           168U           /* Timer clock input (MHz)£¬select MCK */
Delay()只是简单的一个for语句,而CFN_TIMER_CLOCK则表示选择MCU的主频,取值为168.

呃,我现在的实验平台是STM32F407VG,主频是168MHz。

那么这个延时函数是如何完成20s的延时呢?

秘密在下面:

进入DeBug,发现这个Delay()函数被编译成4句ASM,明朗了,那么Delay(1)至少就要经过4个机器周期。

而一个机器周期是(1/168兆)s,再加上CFN_TIMER_CLOCK*5*1000*1000=168X5X1000X1000=5X168兆。

那么Delay(CFN_TIMER_CLOCK*1000*1000)所经历的时间就应该是(1/168兆)X5X168兆X4=20s

呃,我只是觉得有必要搞清楚程序里面延时的情况。

上实验结果图:


很常规,加上上面的分析,不解释。


实验十一思考题


1) 改变延时时间,运行程序,测试周期性处理时间的准确性!

有了前面的思考和分析,这个问题并不难。

修改Delay(CFN_TIMER_CLOCK*5*1000*1000)变成Delay(CFN_TIMER_CLOCK*15*1000*1000),延时变成60秒。

那么周期性处理任务应该被调用6次。

RunRun看:

灰常准确的执行次数,坑的是跑了1分钟。。。。



TBC......



高工
2013-07-05 12:36:07     打赏
37楼

为什么不试试Printf呢??



高工
2013-07-05 12:43:13     打赏
38楼

标准库的printf函数还是自己写的?

个人感脚,都差不多。 


高工
2013-07-05 17:23:19     打赏
39楼
printf用着爽很多的。。。。。

高工
2013-07-08 22:51:58     打赏
40楼

实验十二 警报处理

警报处理的工作流程十分好理解,指在特定长度的时间后,启动一个特定的事件处理程序。

和前面几个实验非常类似,基本方法就是创建、启动、查询和结束。

但是需要注意的一点是,只有启动了警报程序,系统才开始针为警报计时,到达所设定的时间长度后,警报处理程序才会被调用。

不多说,上实验结果:

实验代码中tk_sta_alm(almid,30000)将警报时间设置为30000ms,也就是调用tk_sta_alm函数30s后才执行AlarmHandler()。

程序中的延时Delay(0x100000)在30ms左右,打印信息会很多,所以这里设置了一个static变量UW timer = 168(我用的是STM32F407),再修改Delay(timer*1000*250),这样得到的延时是1s,打印信息就清晰多了。

细心的筒子可能发现第27s的打印信息不见了。呃,系统运行的误差吧,如果要精确打印的话,还是使用上个实验所提到的周期处理方式相对比较精确。


实验十二 警报处理思考题

1) 减小警报时间,看看最小的警报时间能够有多少?

报警时间主要由ER ercd = tk_sta_alm ( ID almid, RELTIM almtim ) ;后面那个参数决定。

貌似都是ms级的,直接修改就能实验了。

1ms


0.999999ms


从打印信息来看,1ms还能正常按顺序执行主函数,小于1ms警报服务程序就直接被调用了。

可见最小的警报时间为1ms。


TBC......


共69条 4/7 |‹ 2 3 4 5 6 7 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]