init_fnc_t *init_sequence[] 函数解析

本文详细解析了S5PC11X SoC的初始化过程,包括CPU初始化、网口配置、定时器设置、环境变量验证、串口速率设定以及内存映射等关键步骤,旨在帮助理解嵌入式系统的启动流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*初始化IRQ/FIQ模式的栈*/

int cpu_init (void)
{
   return 0;
}

/*初始化网口,设置机器码及标记启动参数起始地址*/

int board_init(void)
{

/*#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8") DECLARE_GLOBAL_DATA_PTR定义一个gd_t全局数据结构的指针,这个指针存放在指定的寄存器r8中。这个声明也避免编译器把r8分配给其它的变量任何想要访问全局数据区的代码,只要代码开头加入DECLARE_GLOBAL_DATA_PTR一行代码,然后就可以使用gd指针来访问全局数据区了 */
 DECLARE_GLOBAL_DATA_PTR;
 dm9000_pre_init();//初始化函数
 gd->bd->bi_arch_number = MACH_TYPE;//机器码,要与内核arch/arm/tools/mach_types中定义相同
 gd->bd->bi_boot_params = (PHYS_SDRAM_1+0x100);//启动参数标记列表在RAM中的起始地址

 return 0;
}

 

/*初始化定时器4为系统时钟,使用timer4来作为系统clock, 即时钟滴答,10ms一次,到点就产生一个中断*/

int interrupt_init(void)
{

 S5PC11X_TIMERS *const timers = S5PC11X_GetBase_TIMERS(); // timer位PWM寄存器数组,并指定起始地址即timers = 0xE2500000

 /* use PWM Timer 4 because it has no output */
 /* prescaler for Timer 4 is 16 */
 timers->TCFG0 = 0x0f00; //设置预分频值为16
 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  @ 66 MHz
   */
  timer_load_val = get_PCLK() / (16 * 100);  //#define __REG(x) (*(vu_long *)(x))取出X地址内的值,设置Timer Input Clock Frequency
 }

 /* load value for 10 ms timeout */
 lastdec = timers->TCNTB4 = timer_load_val;
 /* auto load, manual update of Timer 4 */
 timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | TCON_4_UPDATE;
 /* auto load, start Timer 4 */
 timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON;
 timestamp = 0;


 return (0);
}

/*检查FLASH上环境参数是否有效*/.

int env_init(void)
{
 size_t total;
 int crc1_ok = 0, crc2_ok = 0;
 env_t *tmp_env1, *tmp_env2;

 total = CFG_ENV_SIZE; //0x4000,环境变量大小

 tmp_env1 = env_ptr; //tmp_env1指向environment[0]起始地

 tmp_env2 = (env_t *)((ulong)env_ptr + CFG_ENV_SIZE); // tmp_env2指向environment[0]起始地址+0x4000地址处

 crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc);
 crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);

 if (!crc1_ok && !crc2_ok)
  gd->env_valid = 0;
 else if(crc1_ok && !crc2_ok)
  gd->env_valid = 1;
 else if(!crc1_ok && crc2_ok)
  gd->env_valid = 2;
 else {
  /* both ok - check serial */
  if(tmp_env1->flags == 255 && tmp_env2->flags == 0)
   gd->env_valid = 2;
  else if(tmp_env2->flags == 255 && tmp_env1->flags == 0)
   gd->env_valid = 1;
  else if(tmp_env1->flags > tmp_env2->flags)
   gd->env_valid = 1;
  else if(tmp_env2->flags > tmp_env1->flags)
   gd->env_valid = 2;
  else /* flags are equal - almost impossible */
   gd->env_valid = 1;
 }

 if (gd->env_valid == 1)
  env_ptr = tmp_env1;
 else if (gd->env_valid == 2)
  env_ptr = tmp_env2;
 return (0);
}

/*串口模特率设置*/

static int init_baudrate (void)
{
 char tmp[64]; /* long enough for environment variables */
 int i = getenv_r ("baudrate", tmp, sizeof (tmp)); //从环境中取字符串,获取环境变量的值,即将字符串baudrate的值存储在tmp中,i为得到的环境变量的长度
  /*将波特率的值存储进gd->bd->bi_baudrate  与gd->baudrate 中*/

gd->bd->bi_baudrate = gd->baudrate = (i > 0)  ? (int) simple_strtoul (tmp, NULL, 10) : CONFIG_BAUDRATE;

   return (0);
}

/*串口初始化,此处没有做任何设置,猜测是因为之前已经初始化了串口*/

int serial_init(void)
{
 serial_setbrg();

 return (0);
}

void serial_setbrg(void)
{
 DECLARE_GLOBAL_DATA_PTR;

 int i;
 for (i = 0; i < 100; i++);
}

/* Called before relocation - use serial functions,将串口初始化标志置1 */
int console_init_f (void)
{
 gd->have_console = 1;

 return (0);
}

/* 打印u-boot信息*/

static int display_banner (void)
{

/*version_string=U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")"CONFIG_IDENT_STRING;即打印出U-Boot 1.1.5 (Sep 22 2008 - 12:30:34),DATE为编译的日期,TIME为编译的时间*/
 printf ("\n\n%s\n\n", version_string); 

 debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
        _armboot_start, _bss_start, _bss_end);
 debug("\t\bMalloc and Stack is above the U-Boot Code.\n");
 return (0);
}

/*打印CPU信息*/

int print_cpuinfo(void)
{
 uint set_speed;
 uint tmp;
 uchar result_set;

 set_speed = 100000;

 tmp = (set_speed / (get_ARMCLK()/1000000));

 if((tmp < 105) && (tmp > 95)){
  result_set = 1;
 } else {
  result_set = 0;
 }

 printf("\nCPU:  S5PV210@%ldMHz(%s)\n", get_ARMCLK()/1000000, ((result_set == 1) ? "OK" : "FAIL"));
#if 1
 printf(" MPLL = %ldMHz, EPLL = %ldMHz\n",
   get_MPLL_CLK()/1000000, get_PLLCLK(EPLL)/1000000);
 printf("         HclkDsys = %ldMHz, PclkDsys = %ldMHz\n",
   get_HCLKD()/1000000, get_PCLKD()/1000000);
 printf("         HclkPsys = %ldMHz, PclkPsys = %ldMHz\n",
   get_HCLKP()/1000000, get_PCLKP()/1000000);
 printf("         SCLKA2M  = %ldMHz\n", get_SCLKA2M()/1000000);
#endif
 puts("Serial = CLKUART ");

 return 0;
}

/*初始化I2C*/

static int init_func_i2c (void)
{
 puts ("I2C:   ");
 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
 puts ("ready\n");
 return (0);
}

/*检测系统内存映射*/

int dram_init(void)
{
 DECLARE_GLOBAL_DATA_PTR;

 gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;

#if defined(PHYS_SDRAM_2)
 gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
 gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
#endif

 return 0;
}

/*打印内存信息*/

static int display_dram_config (void)
{
 int i;

#ifdef DEBUG
 puts ("RAM Configuration:\n");

 for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
  printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
  print_size (gd->bd->bi_dram[i].size, "\n");
 }
 for (i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
  size += gd->bd->bi_dram[i].size;
 }
#endif

 return (0);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值