Write embedded bootloader by yourself (3)

Source: Internet
Author: User

This section briefly describes some of the key codes not mentioned above, introduces the source code organization structure and makefile system, displays the experiment running results, and provides download of all the source code.

 1. Timer initialization and latency Program

Because latency is required in the cs8900a driver, it is necessary to enable and initialize the S3C2440 timer and write a latency program.

S3c2440a has five timers numbered timer0 ~ Timer4. Timer0 ~ Timer3 has output pins that can be used to control periodic changes in pin levels. This is called the pulse width modulation (PWM: Pulse Width Modulation) function. Timer4 has no output pin, and thus has no PWM function. Therefore, timer4 is often used by the latency function in the program.

The clock source of the timer is pclk, but the timer is used only after two-level pre-division. The first-level pre-division is controlled by the t00000 register. Its bit [] sets the value of the pre-divider 0 for use by timer0 and timer1, and its bit [] sets the value of the pre-divider 1, timer2 ~ Timer4. The second-level pre-division is controlled by the tcfg1 register, and each fourth digit controls a timer, you can select from the following frequencies: 2, 4, 8, 16, and external tclk0/tclk1.

Our latency function uses timer4, and all other timers are disabled. Set in the initialization program: t00000 = 0x0f00; indicates that timer4's first-level pre-division value is 15 + 1 = 16. Register tcfg1 uses the default value of all 0, indicating that the second-level pre-division is 2. Pclk has been set to 50 MHz, so the actual working frequency of timer4 is:

50 MHz/16/2 = 50000000/32 = 1562500Hz

Note that the MHz used to calculate the clock frequency refers to 10 ^ 6, not 2 ^ 20; similarly, kHz refers to 1000Hz, not 1024Hz.

In tcon, we set timer4 to "auto load". When timer4 is started, the value of tcntb4 is automatically loaded into the internal register tcnt4. Then, at the operating frequency, tcnt4 starts to reduce the count by 1. When it reaches 0, the value of tcntb4 is automatically loaded into tcnt4, And the next counting process starts. If we set tcntb4 to 15625, the length of a counting process is 10 milliseconds.

Assume that the delay time is msec millisecond, the Total Count value is TMO = msec * 15625/10, and a variable timestamp is set to save the past timestamp, update timestamp every time you read the value of tcnt4 until it is greater than TMO. The procedure is as follows:

Code highlighting produced by actipro codehighlighter (freeware)
Http://www.CodeHighlighter.com/

While (Timestamp
<TMO)

{

Thisdec = tcnto4
& 0 xFFFF;

If (lastdec
> = Thisdec)
/* Normal Mode
*/

{

Timestamp + = lastdec
-Thisdec;

}

Else
/* We have an overflow...
*/

{

Timestamp + = lastdec
+ Timer_load_val
-Thisdec;

}

Lastdec = thisdec;

}

The tcnt4 value can be read from the tcnto4 register. The program saves the tcnto4 value read from the last two times. If the value is smaller than the previous one, it is in the same count process. If the value is greater than the previous one, it indicates that the next counting process is in progress.

Content navigation

2. Serial Port Standard Input and Output

It is not easy to use scanf () and print () in bootloader, because C library functions cannot be used directly. Scanf () needs to obtain input from the serial port, and print () needs to output to the serial port. You must implement common C library functions by yourself, including not only input and output functions, but also string operation functions such as strcmp () and strcpy. Fortunately, this simplified C library is provided in the source code of the book embedded Linux application development full manual, so it is used directly.

The Code defines two global arrays as the input and output buffer:

Static unsigned char g_pcoutbuf [1024];

Static unsigned char g_pcinbuf [1024];

In fact, we can locate the two buffers in the steppingstone of the CPU, which can save 2 K space.

The implementation of scanf () calls the GETC () function, and the implementation of printf () calls the putc () function. We write the GETC () function to read characters from the serial port, and the putc () function to send characters to the serial port, so that the standard input and output are associated with the serial port.

Code highlighting produced by actipro codehighlighter (freeware)
Http://www.CodeHighlighter.com/

/* Send one character
*/

Void putc (unsigned char C)

{

/* Wait until all data in the sending buffer has been sent
*/

While (! (Utrstat0
& Txd0ready ));

/* Write data to the utxh0 register, and UART automatically sends it out.
*/

Utxh0 = C;

}

/* Receive characters
*/

Unsigned char GETC (void)

{

Unsigned char ret;

/* Wait until there is data in the receiving buffer.
*/

While (! (Utrstat0
& Rxd0ready ));

/* Directly read the urxh0 register to obtain the received data.
*/

Ret = urxh0;

If (Ret
= 0x0d | RET
= 0x0a)

{

Putc (0x0d );

Putc (0x0a );

}

Else

{

Putc (RET );

}

Return ret;

} Content navigation

  3. source code structure

The source code and Directory have only two files, the main makefile and the link script sboot. LDS.

The folder start contains start. S and NAND. c. The former is the assembly code initially run after power-on, and the latter contains the READ function of NAND Flash, which is responsible for copying the S-boot code from NAND to ram.

The main. c folder contains an endless loop. It provides a number of menus for users to choose from and then calls the corresponding functional programs.

The LIB folder is a simplified and transplanted C standard library, including input and output and string operation functions.

The include folder contains some header files.

The folder app contains boot_linux.c and TFTP. C, and their functions can be seen from the name.

The device folder contains device drivers, such as serial port initialization, Timer initialization and delay functions, NIC driver, and network protocol implementation.

Each folder has its own makefile. The main makefile under the root directory enters each subdirectory and calls its own makefile. The makefile under each subdirectory links the compiled code into a build-in.o file, the main makefile links the build-in.o under each subdirectory into an executable file.

The compiler uses its own arm-hwlee-Linux-gnueabi-GCC. You can download it from here. Add the-nostdinc option to GCC, indicating that the standard C library function is not used. The inclusion file cannot be found in the/usr/include directory, only in-I $ (includedir) the specified directory looks for contained files.

Content navigation

4. Download all source code:

File: S-Boot.tar.gz

Size: 41kb

Download: Download

  5. Running result

  

In the figure, select 3 to download the kernel from the TFTP server to ram, and then select 4 to start the kernel from Ram.

Select 2 and download the kernel through the serial port Kermit protocol. The previous article did not analyze this part of the code, and I will try again later. The following is an example:

  

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.