NBOOT - 基于VS2005的编程与编译(二)

四、增加串口功能

       串口在调试时,打印调试信息是很有用的;在nboot过程中,打印些信息,若是发生crash,也可判断是否在nboot阶段。

       串口采用UART0,115200波特率。

      1、Clone过来的bsp默认是采用UART1,修改"\SRC\INC\bsp_cfg.h"文件

  
    
1 // ------------------------------------------------------------------------------
2 // Debug UART0
3 // ------------------------------------------------------------------------------
4
5 #define BSP_UART0_ULCON 0x03 // 8 bits, 1 stop, no parity
6 #define BSP_UART0_UCON 0x0005 // pool mode, PCLK for UART
7 #define BSP_UART0_UFCON 0x00 // disable FIFO
8 #define BSP_UART0_UMCON 0x00 // disable auto flow control
9 #define BSP_UART0_UBRDIV (S3C2410X_PCLK/(115200*16) - 1)

2、在nboot目录下新建debug.c文件,并加入工程。debug.c文件完成串口的初始化和字符串输出功能,其代码可copy 

"\SRC\OAL\OALLIB\debug.c"文件,稍微修改即可,包括两个函数
VOID OEMInitDebugSerial()和VOID OEMWriteDebugString(LPWSTR string)
  
    
1 #include < bsp.h >
2
3
4
5 VOID OEMInitDebugSerial()
6 {
7
8 volatile S3C2410X_IOPORT_REG * pIOPortReg = (S3C2410X_IOPORT_REG * )(S3C2410X_BASE_REG_PA_IOPORT);
9 volatile S3C2410X_UART_REG * pUARTReg = (S3C2410X_UART_REG * )(S3C2410X_BASE_REG_PA_UART0);
10
11 // GPH2 and GHP3 are UART0 Tx and Rx, respectively.
12 //
13
14 pIOPortReg -> GPHCON &= ~ (( 3 << 4 ) | ( 3 << 6 ));
15 pIOPortReg -> GPHCON |= ( 2 << 4 ) | ( 2 << 6 );
16
17 // Disable pull-up on TXD0 and RXD0.
18 pIOPortReg -> GPHUP |= ( 1 << 2 ) | ( 1 << 3 );
19
20 // Configure the UART.
21 pUARTReg -> UFCON = BSP_UART0_UFCON; // FIFO disable
22 pUARTReg -> UMCON = BSP_UART0_UMCON; // AFC disable
23
24 pUARTReg -> ULCON = BSP_UART0_ULCON; // Normal,No parity,1 stop,8 bits
25 pUARTReg -> UCON = BSP_UART0_UCON;
26
27 pUARTReg -> UBRDIV = BSP_UART0_UBRDIV;
28
29
30 }
31
32 // ------------------------------------------------------------------------------
33 //
34 // Function: OEMWriteDebugByte
35 //
36 // Transmits a character out the debug serial port.
37 //
38 static VOID OEMWriteDebugByte(UINT8 ch)
39 {
40 volatile S3C2410X_UART_REG * pUARTReg = (S3C2410X_UART_REG * )(S3C2410X_BASE_REG_PA_UART0);
41
42 // Wait for transmit buffer to be empty
43 while (((pUARTReg -> UTRSTAT) & 0x02 ) == 0 );
44
45 // Send character
46 pUARTReg -> UTXH = ch;
47
48 }
49
50
51
52 // ------------------------------------------------------------------------------
53 //
54 // Function: OEMWriteDebugString
55 //
56 // Output unicode string to debug serial port
57 //
58 VOID OEMWriteDebugString(LPWSTR string )
59 {
60 while ( * string != L ' \0 ' )
61 OEMWriteDebugByte((UINT8) * string ++ );
62 }

 

3、以上两步已将串口功能实现,通过OEMWriteDebugString(TEXT("Hello World!\r\n"))这样的语句来打印debug信息了。

 

五、NAND FLASH部分

      NAND FLASH 读代码复杂,不过在BSP都基本有现成代码,拷贝过来修改即可。主要包含两个函数,初始化NANDFLASH和读NANDFLASH。

      1、nboot目录新建个Flash.c文件并加入工程,copy"\SRC\COMMON\SMARTMEDIA\FMD\ARM\nand.s"到nboot目录并加入工程;

           copy"\SRC\COMMON\SMARTMEDIA\FMD\nand.h"文件到目录下,并include到Flash.c文件。

      2、Flash_Iint ()函数实现。Flash.c

 

  
    
1
2 void Flash_Init()
3 {
4 // Caller should have specified NAND controller address.
5 //
6 s2410NAND = (S3C2410X_NAND_REG * )NAND_BASE;
7
8 // Set up initial flash controller configuration.
9 //
10 s2410NAND -> NFCONF = ( 1 << 15 ) | /* Enable/Disable */
11 ( 1 << 14 ) | /* Page Size : 512Bytes */
12 ( 1 << 13 ) | /* 4 Step Address */
13 ( 1 << 12 ) | /* Initialize ECC */
14 ( 1 << 11 ) | /* nFCE control nFCE = HIGH */
15 (TACLS << 0 ) | /* CLE & ALE = HCLK * (TACLS + 1) */
16 (TWRPH0 << 3 ) | /* TWRPH0 = HCLK * (TWRPH0 + 1) */
17 (TWRPH1 << 0 ); /* TWRPH1 = HCLK * (TWRPH1 + 1) */
18
19 NF_nFCE_L(); // Select the flash chip.
20 NF_CMD(CMD_RESET); // Send reset command.
21 NF_WAITRB(); // Wait for flash to complete command.
22 // Get manufacturer and device codes.
23
24 NF_nFCE_H(); // Deselect the flash chip.
25 }

 

3、Flash读函数,Flash_ReadSector()函数实现。Flash.c

 

  
    
1
2 /*
3 @func BOOL | FMD_ReadSector | Reads the specified sector(s) from NAND flash.
4 @rdesc TRUE = Success, FALSE = Failure.
5 @comm
6 @xref
7
*/
8 BOOL Flash_ReadSector(DWORD startSectorAddr, LPBYTE pSectorBuff, DWORD dwNumSectors)
9 {
10 ULONG SectorAddr = (ULONG)startSectorAddr;
11 ULONG blockPage;
12
13 NF_RSTECC(); // Initialize ECC.
14 NF_nFCE_L(); // Select the flash chip.
15 NF_CMD(CMD_RESET); // Send reset command.
16
17 while (dwNumSectors -- )
18 {
19 blockPage = (((SectorAddr / NAND_PAGE_CNT) * NAND_PAGE_CNT) | (SectorAddr % NAND_PAGE_CNT));
20
21 NF_WAITRB(); // Wait for flash to complete command.
22
23 if (pSectorBuff)
24 {
25 NF_CMD(CMD_READ); // Send read command.
26 NF_ADDR( 0 ); // Column = 0.
27 NF_ADDR(blockPage & 0xff ); // Page address.
28 NF_ADDR((blockPage >> 8 ) & 0xff );
29 NF_ADDR((blockPage >> 16 ) & 0xff );
30 NF_WAITRB(); // Wait for command to complete.
31
32 // Handle unaligned buffer pointer
33 RdPage512(pSectorBuff); // Read page/sector data.
34
35 NF_RDDATA(); // Read/clear status.
36 NF_RDDATA(); //
37 }
38
39 ++ SectorAddr;
40 pSectorBuff += NAND_PAGE_SIZE;
41 }
42
43 NF_nFCE_H(); // Deselect the flash chip.
44
45 return (TRUE);
46 }

4、修改Flash Controller的寄存器地址,#define NAND_BASE 0x4e000000。另外nand.s文件内,也要改过来(NFDATA)。nand.s文件内除了Rdpage512()之外函数都可以删除。

      这样,NAND FLASH 部分也就完成了。

 

 六、main文件,完成

      经过以上工作,nboot差不多就完成了,在main函数中调用就可了

      1、在main函数内,按顺序调用下面的函数

    OEMInitDebugSerial();
 Flash_Init();
 Flash_ReadSector(0x30021000,32,0x00040000/512)); 
            //0x3002_1000是EBOOT的ram地址,0x00040000的大小,
           //32是FlashPage Bloack-1的地址(也即Eboot烧到block-0)

      2、运行EBOOT。copy eboot目录下的ulit.s文件,删除两句语句,

       ;       ldr     r3, = (VIR_RAM_START - PHY_RAM_START)
      ;       sub     r2, r2, r3

       然后再main函数内调用Launch(0x300021000)即可启动EBOOT了。

 

 七、完结

       将nboot编译,烧进Flash,并烧录eboot,上电,看到EBOOT启动了。

 

转自:http://www.cnblogs.com/wincee/articles/1689139.html

 

你可能感兴趣的:(Boot)