uboot中void udelay (unsigned long usec)函数

来源:互联网 发布:苹果5s能用4g网络吗 编辑:程序博客网 时间:2024/06/07 12:40

在uboot中会有一些需要用到延时的场景,像延时输入进入uboot中。

uboot的延时相对简单,主要是利用定时器4一直循环递减统计时间。

1、int interrupt_init (void)  定时器初始化函数。

函数对定时器进行初始化,以10ms的周期循环递减。内容如下,寄存器设置可以参考datasheet

int interrupt_init (void){S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();/* use PWM Timer 4 because it has no output *//* prescaler for Timer 4 is 16 */timers->TCFG0 = 0x0f00;if (timer_load_val == 0){/* * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 * (default) and prescaler = 16. Should be 10390 * @33.25MHz and 15625 @ 50 MHz */timer_load_val = get_PCLK()/(2 * 16 * 100);}/* load value for 10 ms timeout */lastdec = timers->TCNTB4 = timer_load_val;/* auto load, manual update of Timer 4 */timers->TCON = (timers->TCON & ~0x0700000) | 0x600000;/* auto load, start Timer 4 */timers->TCON = (timers->TCON & ~0x0700000) | 0x500000;timestamp = 0;return (0);}

2、时间的两个变量。

static ulong timestamp;//时间戳,标记节拍数
static ulong lastdec;//上一次读取定期的值

int timer_load_val = 0;//定时器加载数值。在初始化函数中,赋值10ms

3、um函数函数:void udelay (unsigned long usec)

void udelay (unsigned long usec){ulong tmo;ulong start = get_timer(0);tmo = usec / 1000;tmo *= (timer_load_val * 100);tmo /= 1000;while ((ulong)(get_timer_masked () - start) < tmo)/*NOP*/;}
start = get_timer(0)函数首先读取当前的时间戳
下面三行将时间值值转化为节拍数。
while ((ulong)(get_timer_masked () - start) < tmo)//读取时间戳的值,并减去本来就存在的时间戳,当运行的时间值大于延时值退出循环。
说明:这种延时方法有一定的问题,没有考虑到 ulong timestamp时间戳溢出的问题,时间戳溢出要相对长的时间。

考虑到溢出问题,在udelay函数中,首先应该调用void reset_timer_masked (void)函数,这个函数对时间戳进行复位。

4、ulong get_timer_masked (void)读取时间戳函数

读取当前定时器的值,当前值大于上次定时器的值时,表明定时器溢出,要对时间戳增加定时器的加载值。函数实现内容如下。

ulong get_timer_masked (void){ulong now = READ_TIMER();if (lastdec >= now) {/* normal mode */timestamp += lastdec - now;} else {/* we have an overflow ... */timestamp += lastdec + timer_load_val - now;}lastdec = now;return timestamp;}




阅读全文
0 0
原创粉丝点击