UBOOT中的时间处理及延时函数的实现方法
前面移植UBOOT的时候饥不择食,没有仔细看延时处理函数,自己用一个非常简单的延时函数糊弄过去了。后来虽然可以运行了,但超时算法全不能用或者会出错。典型的问题就是sleep命令不能正确执行,无论是sleep 0,还是sleep 9999,都是一下子就过。
今天晚上仔细研究了一下UBOOT的时间处理及超时算法(还是蛮简单的,因为没有中断)。在UBOOT中,有两个全局变量与时间处理密切相关:timestamp和lastdec。在init和reset的过程中,timestamp初始化为零,lastdec初始化为timer装载值(一般32位定时器为全F,即0xFFFFFFFF)。定时器工作在自动装载模式,递减计数。
为了使问题简单化,假设是第一次取时间,即timestamp为零,lastdec为0xFFFFFFFF,在get_timer函数中,timestamp被赋值为lastdec减去定时器当前计数值(如果计时器溢出,需进行溢出修正,详见UBOOT代码),并返回timestamp。
在延时函数udelay中,先将传入的参数usec(毫秒)转化为时钟数,然后通过get_timer取出当前timestamp,将当前timestamp加上前面得到的时钟数,即得到超时timestamp,然后不断去取timestamp,直到取到的时间超出上面的计数值。
应该说UBOOT的时间处理和超时算法还是比较简单的。这种算法也存在缺陷,特别是对sep4020来说。由于sep4020的定时器没有预分频,定时器在系统时钟直接驱动下递减计数,当主频工作在96M的时候,timestamp最多只能保留45秒不到的计数值。一旦超过这个数,timestamp就要溢出。因此需要上层应用去检测并修正。
以上是对UBOOT时间处理及超时算法的一点心得。时间仓促,难免有错误,望指正
今天晚上仔细研究了一下UBOOT的时间处理及超时算法(还是蛮简单的,因为没有中断)。在UBOOT中,有两个全局变量与时间处理密切相关:timestamp和lastdec。在init和reset的过程中,timestamp初始化为零,lastdec初始化为timer装载值(一般32位定时器为全F,即0xFFFFFFFF)。定时器工作在自动装载模式,递减计数。
为了使问题简单化,假设是第一次取时间,即timestamp为零,lastdec为0xFFFFFFFF,在get_timer函数中,timestamp被赋值为lastdec减去定时器当前计数值(如果计时器溢出,需进行溢出修正,详见UBOOT代码),并返回timestamp。
在延时函数udelay中,先将传入的参数usec(毫秒)转化为时钟数,然后通过get_timer取出当前timestamp,将当前timestamp加上前面得到的时钟数,即得到超时timestamp,然后不断去取timestamp,直到取到的时间超出上面的计数值。
应该说UBOOT的时间处理和超时算法还是比较简单的。这种算法也存在缺陷,特别是对sep4020来说。由于sep4020的定时器没有预分频,定时器在系统时钟直接驱动下递减计数,当主频工作在96M的时候,timestamp最多只能保留45秒不到的计数值。一旦超过这个数,timestamp就要溢出。因此需要上层应用去检测并修正。
以上是对UBOOT时间处理及超时算法的一点心得。时间仓促,难免有错误,望指正