当前位置:编程学习 > C/C++ >>

uboot中timer定时器的设置

uboot中timer定时器的设置,uboot汇编部分没有对timer初始化,而是在C中。在C入口函数void start_armboot(void)中,首先是通过如下代码方式调用:
[cpp]  
typedef int (init_fnc_t) (void);  
[html] 
init_fnc_t *init_sequence[] = {  
 a/a/l/board.c                                                                                                                        
#if defined(CONFIG_ARCH_CPU_INIT)  
    arch_cpu_init,      /* basic arch cpu dependent setup */  
#endif  
    board_init,     /* basic board dependent setup */  
#if defined(CONFIG_USE_IRQ)  
    interrupt_init,     /* set up exceptions */  
#endif  
    timer_init,     /* initialize timer */  
#ifdef CONFIG_FSL_ESDHC  
    get_clocks,  
#endif  
    env_init,       /* initialize environment */  
    init_baudrate,      /* initialze baudrate settings */  
    serial_init,        /* serial communications setup */  
    console_init_f,     /* stage 1 init of console */  
    display_banner,     /* say that we are here */  
#if defined(CONFIG_DISPLAY_CPUINFO)  
    print_cpuinfo,      /* display cpu info (and speed) */  
#endif  
#if defined(CONFIG_DISPLAY_BOARDINFO)  
    checkboard,     /* display board info */  
#endif  
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)  
    init_func_i2c,  
#endif  
    dram_init,      /* configure available RAM banks */  
#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)  
    arm_pci_init,  
#endif  
    display_dram_config,  
    NULL,  
};  
这里是u-boot的C代码部分的入口:
[cpp]  
void start_armboot (void)  
{  
    init_fnc_t **init_fnc_ptr;  
              。  
              。  
              。  
     
    for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {  
        if ((*init_fnc_ptr)() != 0) {  
            hang ();  
        }  
    }  
上面的函数调用很复杂,不是讨论这个所以暂时不深究,直接看它调用arch/arm/cpu/arm920t/s3c24x0/timer.c文件中的函数int timer_init (void),代码如下:
 
 
[cpp]  
int timer_init(void)  
{  
    struct s3c24x0_timers *timers = s3c24x0_get_base_timers();  
    ulong tmr;  
  
    /* use PWM Timer 4 because it has no output */  
    /* prescaler for Timer 4 is 16 */  
    writel(0x0f00, &timers->TCFG0);  
    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);  
        timer_clk = get_PCLK() / (2 * 16);  
    }  
    /* load value for 10 ms timeout */  
    lastdec = timer_load_val;  
    writel(timer_load_val, &timers->TCNTB4);  
    /* auto load, manual update of Timer 4 */  
    tmr = (readl(&timers->TCON) & ~0x0700000) | 0x0600000;  
    writel(tmr, &timers->TCON);  
    /* auto load, start Timer 4 */  
    tmr = (tmr & ~0x0700000) | 0x0500000;  
    writel(tmr, &timers->TCON);  
    timestamp = 0;  
  
    return (0);  
}  
 
以下是对函数的详细分析:
 1、先看数据结构s3c24x0_timers
[cpp]  
struct s3c24x0_timers {  
    u32 TCFG0;  
    u32 TCFG1;  
    u32 TCON;  
    struct s3c24x0_timer    ch[4];  
    u32 TCNTB4;  
    u32 TCNTO4;   
};    
有引出来了另一个结构s3c24x0_timer
[cpp]  
struct s3c24x0_timer {  
    u32 TCNTB;  
    u32 TCMPB;  
    u32 TCNTO;  
};  
看下这两个结构是不是涵盖了所有timer的寄存器,对照s3c2440的datasheet得出结论是:timer寄存器地址空间从(0x51000000~0x51000040)依次对应的寄存器名是却是是上面的结构体中的寄存器,总共是17个寄存器.
为什么会有4个结构s3c24x0_timer呢?因为2440有5个timer,其中前四个timer0~timer3工作方式类似,都有外部引脚引出,而第五个timer4不同与他们,第一个就是它没有TCMPB寄存器,具体的区别可以看看这个文档或是datasheet:
 
2、s3c24x0_get_base_timers()函数返回的就是timer寄存器空间的起始地址0x51000000
[cpp]  
static inline struct s3c24x0_timers *s3c24x0_get_base_timers(void)  
{     
    return (struct s3c24x0_timers *)S3C24X0_TIMER_BASE;  
}    
3、
[cpp]  
/* use PWM Timer 4 because it has no output */  
   /* prescaler for Timer 4 is 16 */  
这个注释是不是有问题呢,我怎么查不到timer4预分频器是16位的,都是8位。是不是要表达计数器是16位的呢?
4、writel(0x0ff,&timers->TCFG0)的作用是什么呢?在arch/arm/include/asm/io.h文件中既然有3处定义了这个函数,考察了一下只有下面被编译:
[cpp] 
#define writel(v,a)         __arch_putl(v,a)  
[cpp]  
#define __arch_putl(v,a)        (*(volatile unsigned int *)(a) = (v))  
分析:就是往a寄存器写入v.
这里就是往寄存器TCFG0写入0x0ff,先看下TCFG0寄存器信息:
 
 将timer0、1的预分频器的值写ff就是255,
    &nbs
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,