Chinaunix首页 | 论坛 | 博客
  • 博客访问: 115940
  • 博文数量: 49
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-23 17:29
文章分类
文章存档

2014年(39)

2013年(10)

我的朋友

分类: 嵌入式

2014-02-07 13:54:54

原文地址:1. board_init 作者:changyongID

board_init 函数位于 board/smdk2410/smdk2410.c

...

     3            S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
     4            S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

...
1.  上面第3行 S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
这是uboot中对寄存器访问的方式
首先定义
S3C24X0_CLOCK_POWER 结构,结构里包含的是2410中CLOCK_POWER相关的一几个寄存器
typedef struct {
    S3C24X0_REG32    LOCKTIME;
    S3C24X0_REG32    MPLLCON;
    S3C24X0_REG32    UPLLCON;
    S3C24X0_REG32    CLKCON;
    S3C24X0_REG32    CLKSLOW;
    S3C24X0_REG32    CLKDIVN;
} S3C24X0_CLOCK_POWER;

而,S3C24X0_GetBase_CLOCK_POWER();位于 include/s3c2410.h 中

static inline S3C24X0_CLOCK_POWER * S3C24X0_GetBase_CLOCK_POWER(void)
{
    //#define S3C24X0_CLOCK_POWER_BASE 0x4C000000
    return (S3C24X0_CLOCK_POWER * const)S3C24X0_CLOCK_POWER_BASE;
}

这里是.h文件,所以其中用static修饰这个函数
inline 修饰的函数是内嵌函数,意思是在编译时会像将这个函数嵌入到调用它的函数体中,避免了函数调用带来的开销。

同理,对一些IO特殊寄存器的访问也是采用的这种方式



     5 /* to reduce PLL lock time, adjust the LOCKTIME register */
     6 clk_power->LOCKTIME = 0xFFFFFF;

     7 /* configure MPLL */
     8 clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);

     9 /* some delay between MPLL and UPLL */
    10 delay (4000);

    11 /* configure UPLL */
    12 clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);

    13 /* some delay between MPLL and UPLL */
    14 delay (8000);

上面这段代码设置时钟频率。
这里主时钟频率为200MHz M_DIV = 0X5C , M_PDIV = 0X04 , M_SDIV = 0X00
USB 时钟为48MHz      U_M_MDIV = 0X28, U_M_PDIV = 0X01, U_M_SDIV = 0X02



    15 /* set up the I/O ports */
    16 gpio->GPACON = 0x007FFFFF;
    17 gpio->GPBCON = 0x00044555;
    18 gpio->GPBUP = 0x000007FF;
    19 gpio->GPCCON = 0xAAAAAAAA;
    20 gpio->GPCUP = 0x0000FFFF;
    21 gpio->GPDCON = 0xAAAAAAAA;
    22 gpio->GPDUP = 0x0000FFFF;
    23 gpio->GPECON = 0xAAAAAAAA;
    24 gpio->GPEUP = 0x0000FFFF;
    25 gpio->GPFCON = 0x000055AA;
    26 gpio->GPFUP = 0x000000FF;
    27 gpio->GPGCON = 0xFF95FFBA;
    28 gpio->GPGUP = 0x0000FFFF;
    29 gpio->GPHCON = 0x002AFAAA;
    30 gpio->GPHUP = 0x000007FF;

初始各IO口


    31 /* arch number of SMDK2410-Board */
    32 gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

    33 /* adress of boot parameters */
    34 gd->bd->bi_boot_params = 0x30000100;

    35 icache_enable();
    36 dcache_enable();


32行 和 34行 是初始化板子的ID 以及 向内核传递的参数(taglist)的地址
内核启动后会0x30000100这个地址取参数

最后在启动内核的函数do_bootm_linux()中,会用到这里的两个值做参数,然后进入内核
theKernel (0, machid, bd->bi_boot_params);

35,36 便能指令cache 和 数据 cache
位于 cpu/arm920t/cpu.c 中

#define C1_IC        (1<<12)        /*cp15中寄存器1的第12位 icache off/on */
void icache_enable (void)
{
    ulong reg;

    reg = read_p15_c1 ();        /* mrc    p15, 0, %0, c1, c0, 0 */
    cp_delay ();
    write_p15_c1 (reg | C1_IC);  /* mcr    p15, 0, %0, c1, c0, 0 */
}

#define C1_DC        (1<<2)        /* cp15中寄存器1的第2位 dcache off/on */
void dcache_enable (void)
{
    ulong reg;

    reg = read_p15_c1 ();       /* mrc    p15, 0, %0, c1, c0, 0 */
    cp_delay ();
    write_p15_c1 (reg | C1_DC); /* mcr    p15, 0, %0, c1, c0, 0 */
}
阅读(1225) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~