linux内核学习初笔记(4)u-boot的board_init()函数clk_power与gpio妙用

来源:互联网 发布:车铣复合编程 编辑:程序博客网 时间:2024/06/03 17:55

在学到board_init()函数内部时发现,居然通过结构指针就可以设置cpu寄存器的值了,这还蛮有意思,研究一炮吧~

经研究发现其实原理很简单,都不好意思写在这里了,所以大神看到这篇文章就请默默移驾吧~

归根结底,就是这两句

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

而函数S3C24X0_GetBase_CLOCK_POWER():

static inline S3C24X0_CLOCK_POWER * const S3C24X0_GetBase_CLOCK_POWER(void)
{
 return (S3C24X0_CLOCK_POWER * const)S3C24X0_CLOCK_POWER_BASE;

我草还是个内敛函数,算了,都差不多,继续研究。

S3C24X0_CLOCK_POWER_BASE:

#define S3C24X0_CLOCK_POWER_BASE 0x4C000000

啊,原来如此呀~

其实就是在S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();处定义一个指针常量并初始化之。这个指针的类型是:

typedef struct {
 S3C24X0_REG32 LOCKTIME;
 S3C24X0_REG32 MPLLCON;
 S3C24X0_REG32 UPLLCON;
 S3C24X0_REG32 CLKCON;
 S3C24X0_REG32 CLKSLOW;
 S3C24X0_REG32 CLKDIVN;
} /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;

OK!那么S3C24X0_GetBase_GPIO();这个函数返回值是一个S3C24X0_CLOCK_POWER类型的指针常量,而且这个指针常量其实是s3c2440时钟控制寄存器组的基地址(可以在数据手册中查明,这里不多说),那么就显而易见了,最终我们初始化clk_power这个指针的值为s3c2440时钟控制寄存器组的基地址,而且指针指向的是一个S3C24X0_CLOCK_POWER类型的数据,而恰好,这个S3C24X0_CLOCK_POWER结构体中的数据分布与s3c2440时钟控制寄存器组的寄存器分布情况一样(当然是故意这么做的),那这样对应看来,我们就可以通过这个指针访问他指向的这个位于s3c2440时钟控制寄存器组的基地址处的S3C24X0_CLOCK_POWER结构体来访问s3c2440的时钟控制寄存器组,那么这样就很方便了啊,不用老是要和寄存器地址打交道,那样很麻烦。