网站导航: 首页 > 设计参考 > 正文 文章搜索
U-Boot 在44B0X 开发板上的移植以及代码分析
 
文章编号:
081229094424
文章分类: 单片机 ARM
点 击:
...
关 键 词: U-Boot,44B0X
文章来源:
网络
摘 要:
u-boot 是一个open source 的bootloader,目前版本是1.1.2。u-boot 是在ppcboot 以及armboot 的基础上发展而来,相当的成熟和稳定,已经在许多嵌入式系统开发过程中被采用。由于其开发源代码,其支持的开发板众多


7) 转到RAM 中执行
使用指令ldr,pc,RAM 中C 函数地址就可以转到RAM 中去执行。
ldr pc, _start_armboot

5. 系统初始化部分
1) 串口部分(u-boot-1.1.2/cpu/s3c44b0/serial.c)
串口的设置主要包括初始化串口部分,值得注意的串口的Baudrate 与时钟MCLK 有很大关系,是通过:rUBRDIV0=( (int)(MCLK/16./(gd ->baudrate) + 0.5) -1 )计算得出。这可以在手册中查到。由于u-boot支持可变的波特率,所以采用宏定义设置默认波特率(64Mhz,115200bps)和其他波特率。代码如下:

 
  1. void serial_setbrg (void)       
  2. {       
  3.     DECLARE_GLOBAL_DATA_PTR;       
  4.   
  5.     u32 divisor = 0;       
  6.   
  7.     /* get correct divisor */      
  8.     switch(gd->baudrate)    
  9.     {       
  10.   
  11.     case 1200:       
  12.         #if CONFIG_S3C44B0_CLOCK_SPEED==66       
  13.         divisor = 3124;       
  14.         #elif CONFIG_S3C44B0_CLOCK_SPEED==75       
  15.         divisor = 3905;       
  16.         #elif CONFIG_S3C44B0_CLOCK_SPEED==64 /默认       
  17.         divisor = 3332;       
  18.         #else       
  19.         # error CONFIG_S3C44B0_CLOCK_SPEED undefined       
  20.         #endif       
  21.         break;       
  22.   
  23.     case 9600:       
  24.         #if CONFIG_S3C44B0_CLOCK_SPEED==66       
  25.         divisor = 390;       
  26.         #elif CONFIG_S3C44B0_CLOCK_SPEED==75       
  27.         divisor = 487;       
  28.         #elif CONFIG_S3C44B0_CLOCK_SPEED==64 /默认       
  29.         divisor = 416;       
  30.         #else       
  31.         # error CONFIG_S3C44B0_CLOCK_SPEED undefined       
  32.         #endif       
  33.         break;       
  34.   
  35.     case 19200:       
  36.         #if CONFIG_S3C44B0_CLOCK_SPEED==66       
  37.         divisor = 194;       
  38.         #elif CONFIG_S3C44B0_CLOCK_SPEED==75       
  39.         divisor = 243;       
  40.         #elif CONFIG_S3C44B0_CLOCK_SPEED==64 /默认       
  41.         divisor = 207;       
  42.         #else       
  43.         # error CONFIG_S3C44B0_CLOCK_SPEED undefined       
  44.         #endif       
  45.         break;       
  46.   
  47.     case 38400:       
  48.         #if CONFIG_S3C44B0_CLOCK_SPEED==66       
  49.         divisor = 97;       
  50.         #elif CONFIG_S3C44B0_CLOCK_SPEED==75       
  51.         divisor = 121;       
  52.         #elif CONFIG_S3C44B0_CLOCK_SPEED==64 /默认       
  53.         divisor = 103;       
  54.         #else       
  55.         # error CONFIG_S3C44B0_CLOCK_SPEED undefined       
  56.         #endif break;       
  57.   
  58.     case 57600:       
  59.         #if CONFIG_S3C44B0_CLOCK_SPEED==66       
  60.         divisor = 64;       
  61.         #elif CONFIG_S3C44B0_CLOCK_SPEED==75       
  62.         divisor = 80;       
  63.         #elif CONFIG_S3C44B0_CLOCK_SPEED==64 /默认       
  64.         divisor = 68;       
  65.         #else       
  66.         # error CONFIG_S3C44B0_CLOCK_SPEED undefined       
  67.         #endif break;       
  68.   
  69.     case 115200:       
  70.         #if CONFIG_S3C44B0_CLOCK_SPEED==66       
  71.         divisor = 32;       
  72.         #elif CONFIG_S3C44B0_CLOCK_SPEED==64       
  73.         divisor = 34;       
  74.         #elif CONFIG_S3C44B0_CLOCK_SPEED==75 /默认       
  75.         divisor = 40;       
  76.         #else       
  77.         # error CONFIG_S3C44B0_CLOCK_SPEED undefined       
  78.         #endif break;       
  79.     }       
  80.   
  81.     serial_flush_output();       
  82.     serial_flush_input();       
  83.     UFCON0 = 0x0;       
  84.     ULCON0 = 0x03;       
  85.     UCON0 = 0x05;       
  86.     UBRDIV0 = divisor;       
  87.   
  88.     UFCON1 = 0x0;       
  89.     ULCON1 = 0x03;       
  90.     UCON1 = 0x05;       
  91.     UBRDIV1 = divisor;       
  92.   
  93.     for(divisor=0; divisor<100; divisor++)    
  94.     {       
  95.         /* NOP */      
  96.     }       
  97. }  

 

其他的函数包括发送,接收。这个时候没有中断,是通过循环等待来判断是否动作完成。
例如,接收函数:

 
  1. static int serial_flush_input(void)   
  2. {   
  3.     volatile u32 tmp;   
  4.   
  5.     /* keep on reading as long as the receiver is not empty */  
  6.     while(UTRSTAT0&0x01) {   
  7.         tmp = REGB(URXH0);   
  8.     }   
  9.   
  10.     return 0;   
  11. }   

2) 时钟部分(u-boot-1.1.2/cpu/s3c44b0/interrupt.c)
实现了延时函数udelay。
这里的get_timer 由于没有使用中断,是使用全局变量来累加的。

 
  1. void udelay (unsigned long usec)   
  2. {   
  3.     ulong tmo;   
  4.   
  5.     tmo = usec / 1000;   
  6.     tmo *= CFG_HZ;   
  7.     tmo /= 8;   
  8.   
  9.     tmo += get_timer (0);   
  10.   
  11.      while (get_timer_masked () < tmo)   
  12.     /*NOP*/;   
  13. }   


3) flash 部分(u-boot-1.1.2/board/gold44b.c)
flash 作为内存的一部分,读肯定没有问题,关键是flash 的写部分。
Flash 的写必须先擦除,然后再写。
flash_init 完成初始化部分,这里的主要目的是检验flash 的型号是否正确。

 
  1. unsigned long flash_init (void)   
  2. {   
  3. #ifdef __DEBUG_START_FROM_SRAM__   
  4. return CFG_DUMMY_FLASH_SIZE;   
  5. #else   
  6. unsigned long size_b0;   
  7. int i;   
  8.   
  9. /* Init: no FLASHes known */  
  10. for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {   
  11. flash_info[i].flash_id = FLASH_UNKNOWN;   
  12. }   
  13.   
  14. /* Static FLASH Bank configuration here - FIXME XXX */  
  15.   
  16. size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);   
  17.   
  18. if (flash_info[0].flash_id == FLASH_UNKNOWN) {   
  19. printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",   
  20. size_b0, size_b0<<20);   
  21. }   
  22.   
  23. /* Setup offsets */  
  24. flash_get_offsets (0, &flash_info[0]);   
  25.   
  26. /* Monitor protection ON by default */  
  27. (void)flash_protect(FLAG_PROTECT_SET,   
  28. -CFG_MONITOR_LEN,   
  29. 0xffffffff,   
  30. &flash_info[0]);   
  31.   
  32. flash_info[0].size = size_b0;   
  33.   
  34. return (size_b0);   
  35. #endif   
  36. }   
  37.   
  38.   
  39. flash_erase 擦除flash,BlankCheck 则检查该部分内容是否擦除成功。   
  40.   
  41. int flash_erase (flash_info_t *info, int s_first, int s_last)   
  42. {   
  43. volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *)(info->start[0]);   
  44. volatile CFG_FLASH_WORD_SIZE *addr2;   
  45. int flag, prot, sect, l_sect;   
  46. ulong start, now, last;   
  47. int i;   
  48.   
  49. if ((s_first < 0) || (s_first > s_last)) {   
  50. if (info->flash_id == FLASH_UNKNOWN) {   
  51. printf ("- missing\n");   
  52. else {   
  53. printf ("- no sectors to erase\n");   
  54. }   
  55. return 1;   
  56. }   
  57.   
  58. if (info->flash_id == FLASH_UNKNOWN) {   
  59. printf ("Can't erase unknown flash type - aborted\n");   
  60. return 1;   
  61. }   
  62.   
  63. prot = 0;   
  64. for (sect=s_first; sect<=s_last; ++sect) {   
  65. if (info->protect[sect]) {   
  66. prot++;   
  67. }   
  68. }   
  69.   
  70. if (prot) {   
  71. printf ("- Warning: %d protected sectors will not be erased!\n",   
  72. prot);   
  73. else {   
  74. printf ("\n");   
  75. }   
  76.   
  77. l_sect = -1;   
  78.   
  79. /* Disable interrupts which might cause a timeout here */  
  80. flag = disable_interrupts();   
  81.   
  82. /* Start erase on unprotected sectors */  
  83. for (sect = s_first; sect<=s_last; sect++) {   
  84. if (info->protect[sect] == 0) { /* not protected */  
  85. addr2 = (CFG_FLASH_WORD_SIZE *)(info->start[sect]);   
  86. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {   
  87. addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;   
  88. addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;   
  89. addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00800080;   
  90. addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;   
  91. addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;   
  92. addr2[0] = (CFG_FLASH_WORD_SIZE)0x00500050; /* block erase */  
  93. for (i=0; i<50; i++)   
  94. udelay(1000); /* wait 1 ms */  
  95. else {   
  96. if (sect == s_first) {   
  97. addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;   
  98. addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;   
  99. addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00800080;   
  100. addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;   
  101. addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;   
  102. }   
  103. addr2[0] = (CFG_FLASH_WORD_SIZE)0x00300030; /* sector erase */  
  104. }   
  105. l_sect = sect;   
  106. }   
  107. }   
  108.   
  109. /* re-enable interrupts if necessary */  
  110. if (flag)   
  111. enable_interrupts();   
  112.   
  113. /* wait at least 80us - let's wait 1 ms */  
  114. udelay (1000);   
  115.   
  116. /*  
  117. * We wait for the last triggered sector  
  118. */  
  119. if (l_sect < 0)   
  120. goto DONE;   
  121.   
  122. start = get_timer (0);   
  123. last = start;   
  124. addr = (CFG_FLASH_WORD_SIZE *)(info->start[l_sect]);   
  125. while ((addr[0] & (CFG_FLASH_WORD_SIZE)0x00800080) != (CFG_FLASH_WORD_SIZE)0x00800080) {   
  126. if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {   
  127. printf ("Timeout\n");   
  128. return 1;   
  129. }   
  130. /* show that we're waiting */  
  131. if ((now - last) > 50000000) { /* every second */  
  132. putc ('.');   
  133. last = now;   
  134. }   
  135. }   
  136.   
  137. DONE:   
  138. /* reset to read mode */  
  139. addr = (CFG_FLASH_WORD_SIZE *)info->start[0];   
  140. addr[0] = (CFG_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */  
  141.   
  142. printf (" done\n");   
  143. return 0;   
  144. }   
  145.   


wirte_word 则想flash 里面写入unsigned long 类型的data,因为flash 一次只能写入16bits,所以这里分两次写入。

 
  1. /*-----------------------------------------------------------------------     
  2. * Write a word to Flash, returns:     
  3. * 0 - OK     
  4. * 1 - write timeout     
  5. * 2 - Flash not erased     
  6. */      
  7. static int write_word (flash_info_t *info, ulong dest, ulong data)       
  8. {       
  9.     volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *)(info->start[0]);       
  10.     volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *)dest;       
  11.     volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *)&data;       
  12.     ulong start;       
  13.     int flag;       
  14.     int i;       
  15.   
  16.     /* Check if Flash is (sufficiently) erased */      
  17.     if ((*((volatile ulong *)dest) & data) != data)    
  18.     {       
  19.         return (2);       
  20.     }       
  21.     /* Disable interrupts which might cause a timeout here */      
  22.     flag = disable_interrupts();       
  23.   
  24.     for (i=0; i<4/sizeof(CFG_FLASH_WORD_SIZE); i++)       
  25.     {       
  26.         addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;       
  27.         addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;       
  28.         addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00A000A0;       
  29.   
  30.         dest2[i] = data2[i];       
  31.   
  32.         /* re-enable interrupts if necessary */      
  33.         if (flag)       
  34.             enable_interrupts();       
  35.   
  36.         /* data polling for D7 */      
  37.         start = get_timer (0);       
  38.         while ((dest2[i] & (CFG_FLASH_WORD_SIZE)0x00800080) !=       
  39.             (data2[i] & (CFG_FLASH_WORD_SIZE)0x00800080))    
  40.         {       
  41.             if (get_timer(start) > CFG_FLASH_WRITE_TOUT)    
  42.             {       
  43.                 return (1);       
  44.             }       
  45.         }       
  46.     }       
  47.   
  48.     return (0);       
  49. }      

 

 
相关文章:

上一页 12
 
最新开源项目
 
 
  查看更多...  
 
本站相关产品   淘宝网店
 




 
  查看更多...  

 

本站程序由百合电子工作室开发和维护
Copyright @ baihe electric studio
渝ICP备09006681号-4