Development report of a simple BSP based on S3C4510B
LMJX 2004-7-2 Email: Limiao@yeah.net
System environment
(1) Hardware environment
CPU: S3C4510B
SDRAM: W981216DH 16M
Flash: MX29LV160AB 2M
(2) software environment
Tornado2.01 for ARM (AKA's FTP has Tornado2.2 needs you to download :))
(3) debugging environment
TRACE32`
TRACE32
(1) Using Trace32 debugging vxworks
When the S3C4510B is powered on the system, the base address of the CPU register is 0x3FF0000, which is initialized using Trace32 to initialize the CPU, allocate memory layout, initializing SDRAM, and then load VxWorks.st for system debugging.
The script is as follows:
; T32Initial Script for S3C4510B
; Initial S4510B SDRAM AND FLASH
D.S 0x03FF0000% L 0x87ffffa0
D.S 0x03FF3010% L 0x00003001
D.S 0x03FF3014% L 0x12040060
D.S 0x03FF3018% L 0x60
D.S 0x03FF301C% L 0x60
D.S 0x03FF3020% L 0x60
D.S 0x03FF3024% L 0x60
D.S 0x03FF3028% L 0x60
D.S 0x03FF302C% L 0x10000398
D.S 0x03FF3030% L 0x00
D.S 0x03FF3034% L 0x00
D.S 0x03FF3038% L 0x00
D.S 0x03FF303C% L 0xCE2983FD
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;
; S3C4510B BOARD - Load coff file trace32 script file
B ::
Symbol.reset
; loading coff file
D.Load.coff e: /s4510b_bsp/vxworks.st / spath / lpath
R.S PC 0x1000
Load Symbol Path
Y.SPATH E: / S3C4510B_BSP /
Y.spath D: / TOR_ARM / TARGET / SRC / NETWRS
Y.spath D: / TOR_ARM / TARGET / SRC / Netinet
Enddo
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;
1: Initialization CPU
D.S 0x03FF0000% L 0x87fffa0 binary is 1000, 011, 1111, 1111, 1111, 1111, 1010,0000
[05:04] = 10B is 8-Kbyte SRAM 0-KBYTE CACHE
[15:06] = 1111111110B = 0x3FE SRAM start address is 0x3FE0000
[25:16] = 1111111111B = 0x3ff CPU register base address is 0x3FF0000
[31] = 1B SDRAM
2: Initialization internal departure bureau
D.S 0x03FF3010% L 0x00003001 binary is 00000000,0000,0000,0011,0000,00,000 0001 [01:00] = 01B Flash Bank0 data bus is BYTE (8-bit)
[13:12] = 11b SDRAM BANK0 Data Bus DWORD (32-bit)
Other DISABLE
D.S 0x03FF3014% L 0x12040060 binary is 0001,0010,0000,0100,0000,0000, 0110,0000
[01:00] = 00b NormaLrom
[03:02] = 00b 5 Cycles (Page Address Access Time (TPA))
[06:04] = 110B 7 CYCLE (ProgramMable Access Cycle (TACC))
[19:10] = 0100000000B = 0x100 Flash Bank0 base site is 0x1000000
[29:20] = 0100100000B = 0x120 Flash Bank0 End Address is 0x1200000-1
D.S 0x03FF302C% L 0x10000398 binary is 0001,0000,0000,0000,0000,0011,1001,1000
[00:00] = 00b Normal SDRAM
[02:01] = 00b 1 CYCLE (CAS STROBE TIME (TCS))
[03:03] = 01B 2 CYCLES (CAS pre-charge time (tcp))
[07:07] = 01B 2 CYCLES (Ras to Cas Delay (TRC or TRCD))
[09:08] = 11b 4 Cycles (Ras pre-charge time (trp))
[19:10] = 0000000000B = 0x00 SDRAM BANK0 base address is 0x000000
[29:20] = 0100000000B = 0x100 SDRAM BANK0 End Address is 0x1000000-1
[31:30] = 00b 8bits (Number of Column Address Bits in DRAM BANK0)
D.S 0x03FF303C% L 0xCE2983FD binary is 1100, 1110, 0010, 1001, 1110, 0011, 1111, 1101
[09:00] = 111111101B = 0x3FD External I / O Bank0 base address is 0x3fd0000
Please contact Datasheet in other points of meaning.
After the memory is initialized, the system memory layout is:
00-16M is SDRAM
16-18m is Flash
0x3FD0000 starts 64K for External I / O
0x3FE0000 start 8K is SRAM
0x3ff0000 starts 64K for CPU registers
3: Load VXWORKS.ST
D.Load.coff e: /s4510b_bsp/vxworks.st / spath / lpath loads VxWorks.st to SDRAM
R.S PC 0x1000 Sets the PC Pointer to RAM_ADRS (0x1000) You can use Trace32 to set breakpoints to debug.
(2) Boot Bootrom with Trace32
1: Flash erase
; S3C4510B - FLASH ERASE TRACE32 Script File
Flash Type: AM29F100
Erase Flash by trace32
Flash.reset
Flash.create 0x1000000--0X10FFFFF AM29F100 WORD
Flash.Rase 0x1000000--0X1001FFF
Flash.Rase 0x1002000--0X1003FFF
Flash.Rase 0x1004000--0X1005FFF
Flash.Rase 0x1006000--0X1007FFF
Flash.Rase 0x1008000--0X1009FFF
Flash.Rase 0x100A000--0X100BFFF
Flash.Rase 0x100C000--0X100DFFF
Flash.Rase 0x100e000--0X100FFFF
........................................
Enddo
2: Burning of bootrom
; S3C4510B Flash Write Trace32 Script File
Flash Type: AM29F100
Write Flash by trace32
B ::
Flash.reset
Flash.create 0x1000000--0X10FFFFF AM29F100 WORD
Flash.Program All
Download * .bin file
D.Load.binary E: /S4510B_BSP/Bootrom.bin 0x1000000
Flash.Program OFF
Enddo
BSP development process
(1) VxWorks's implementation process
In the system development period, we usually use the debugging tool to download the VxWorks of the compiled toned symbol to SDRAM for debugging. After all function debugging is completed, it is compiled to generate bootrom.bin to burn it. Therefore, VxWorks has a point in starting from the ROM and SDRAM.
1: Start VxWorks from SDRAM
Use Trace32 to download VxWorks.st to SDRAM, at this time, the PC pointer points to 0x1000 according to the Trace32 script, which is the entry point of sysinit (). VxWorks calls the function under normal restart, defined in sysalib.s, prohibiting the buffer, initializing system interrupt table, system fault table, clearing all waiting interrupts, calling usrinit (boottype).
USRINIT () is the first C program that is first running under VxWorks, which needs to complete the work you need to create the initial task USRROOT (). It first calls BZERO (EDATA, END - EDATA); Clears the system BSS segment, save the start type, call intVecbaseset (FUNCPTR *) VEC_BASE_ADRS); set the interrupt vector table, call eXcVecinit (); set an exception vector, call syshwinit (); Initialize system hardware, call usrkernelinit (); configure the Wind kernel, and finally call kernelinit () to start the system root task USRROOT;
USRROOT is the first task running in a multitasking environment that completes the final initialization and launches other tasks. USRROOT () Initialize the I / O system, install the driver, create a device, set the network, and so on in configall.h and config.h. In the development process, we can use Trace32 to track each step, observe the execution behavior of the program, check the contents of the relevant registers; you can also write some test functions, simple testing of the completed features, for example when we complete After the serial port works in polling mode, we can write an ECHO program to make a simple check on the input and output of the serial port.
2: Start VxWorks from the ROM
When we use Trace32 to debug a BSP, you need to modify the Rominit.s file, this file is the entry point at the cold start, it will start the type, disable interrupt, initialize the CPU, Configure SDRAM, FLASH, and transfer to Romstart () in BootInti.c, copy (text segment and) data segment to RAM_HIGH_ADRS in the SDRAM and finally call usrinit (boottype).
During the development, we need to use the burning tool or the debug tool to download the build-generated bootrom.bin to Flash. When the system is powered on, the CPU mirror the Flash mirror to the address 0x00000000 and start executing, when Rominit () After executing the necessary operation, it will jump to the real address of Flash, and perform the initialization of SDRAM, Flash, then map SDRAM to 0x0000000000FFFFF (0-16M), map Flash to 0x01000000 to Other executions are completed at 0x011FFFF (16-18M).
(2) Architecture of CPU
The S3C4510B is a CPU using the ARM7TDMI core, so it is necessary to have a certain understanding of ARM7TDMI. It is necessary to note that the 32-bit thin instruction set CPU's operation is done by a word length (4-byte), so we are in GCC In the compilation switch, it is necessary to use -Pack-struct to eliminate blank between structures. Special attention is also required when the mandatory type conversion is required, because once a odd address is interpreted as a short (16-bit) or int (32-bit) An exception will occur when the type of address is generated.
(3) Using debugging tools to assist
When developing BSPs, a heart-should-minded debugging tool will take half a job. In this project, I used TRACE32, which is simple and very easy to get.
In the early stage of development, we need to write script files to initialize CPU, SDRAM, FLASH. In order to verify that the initialization results are correct, we can read and write the address in the SDRAM, see if the results are consistent with our expectations. After this step, download VxWorks.st to SDRAM, execute if it is normal, locate the error code position, repeatedly modified until the system is running normally.
Hardware initialization
(1) VxWorks behavior
VxWorks calls syst () in usrinit (), which sets all devices into the quiet state, shields all screenable interrupts. SYSHWINIT calls sysserialhwinit (); to initialize the serial port device, and configure the serial correlation register in UARTDevinit (), set the baud rate, and set the serial port mode of operation. Call sysclkconnect () in USRROOT (), and sysclkconnect immediately calls systwinit2 () to complete the work that cannot be completed in SyshWinit () (because there is no initialization pool in the system memory when calling systwinit (), so you cannot call malloc related functions, For example INTCONNECT ()), it calls the Intlibinit () initialization interrupt library, call the IRQDevicnit () initialize the interrupt controller, and then use the INTCONNECT () mount clock interrupt, call sysserialhwinit2 () Set the serial port to interrupt mode.
(2) Interrupt Description of SC34510B
The SC34510B has 21 interrupt sources, as shown in the following table:
In this example I use [4], [5], [10], the serial port is transmitted, respectively, and the serial port 0 receives the interrupt, the timer 0 is interrupted. When initializing the interrupt controller, we need to set the INTMOD register, configure the interrupt source in the working mode we need, here I configure them into ordinary interrupt mode (IRQ), will be [20:00] bit clear. The INTMOD register is shown below:
INTPND interrupts unresser, which contains unrescribed interruptions of each interrupt source, need to clear the unconscious interrupt in the interrupt service program. The register is shown below:
The INTMSK interrupt mask register contains the interrupt mask of each interrupt source. When the corresponding bit is set, the interrupt will be blocked. The register is shown below:
In this example, I didn't change the priority order of each interrupt source in the system, that is, starting from 0 to 21,0, the highest priority, sequentially decreasing.
(3) Interrupt driver
In IrQDevicnit (), the interrupt controller is initialized, which initializes the interrupt driver structure, and initializes the interrupt controller register.
Check and return the most promising interrupts in IrqClvlVecchk (). During this time it sets the priority of the current interrupt priority to this unrealized interrupt to ensure that only the priority is allowed to be generated than its high interrupt during the interrupt service.
Reset in IrqClvlVecack () Reset the current interrupt as the previous interrupt level.
Set a new current interrupt level in IrqClVLCHG (), the priority used than the current interrupt will be blocked off, all of which will be opened than the current interrupt priority and is allowed to be interrupted.
Allows the specified interrupt to be generated in IrqClvlenable ().
Shield a specified interrupt in IrqClvldisable ().
(4) serial port interruption
In the initial port controller, set the baud rate, initialize the serial driver. The registers that need to be configured during the period are as follows: ULCON0 registers, which are set to 0x03, 8-bit data bits, no stop position, no idling.
UCON0 register, its value is set to 0x00, setting the received reception and transmitting interrupt invalid.
UbrDIV0 register, set the baud rate division factor, where I set the baud rate of 38400 can calculate the value of the register according to the formula 0x270. The formula is (FMCLK_MHz / (32 * (_ Rate)) - 1) The frequency of the CPU is 50 MHz, and the _rate is 38400, so the value of the CNT0 is 0x27, which is in a divided manner, so the CNT1 is 0000, so the result of the register is 0x270.
UARTPOLLINPUT () serial port Enter a handler in polling mode.
UARTPOLLOUTPUT () serial port outputs a handler in polling mode.
UARTTXSTARTUP () serial port launches an interrupt output.
UARTINTRX () Logs Interrupt Service, Note To clear the input interrupt, the corresponding interrupt unproduction.
UARTINTTX () outputs an interrupt service program, pay attention to clear the output interrupt corresponding interrupt unproduction.
A few registers USTAT0, URXBUF0, UTXBUF0 are required in the above several functions, and you can check the information yourself :).
(5) Clock interruption
sysclkint () is a service program that is interrupted by the clock, and invokes INTCONNECT () registration after the interrupt driver is initialized.
Sysclkenable () Start a timer that calculates the time interval that occurs each time the clock interrupts and calculates the value of TDATA0 according to the formula ((FMCLK_MHz) / (sysclktickspersecond) -1). Set TMOD to 0x03, turn on Timer0, open the clock interrupt.
Sysclkdisable () stops a timer. It sets TMOD to 0x00, shut down the clock interrupt. The relevant registers are as follows:
SysclkRateSet () Sets the number of Tick per second and updates the settings by continuously call sysclkdisable (), sysclkenable ().
Sysclkrateget () gets the number of Tick per second.
Rominit.s file analysis
When we use Trace32 to develop a VxWorks running in RAM, you need to modify rominit.s and bootinti.c, compile the connection to generate bootrom.bin, and then use the tool to burn into Flash. The following is the Rominit.s file, code and comments I have modified for S3C4510B, as follows:
/ * Rominit.s - ARM PID ROM INITIZATION MODULE * /
/ * CopyRight 1996-1999 Wind River Systems, Inc. * /
.DATA
.globl _copyright_wind_river
.long _copyright_wind_river
/ *
Modification History
--------------------
*********************************************************** ************************************* / # Define _asmlanguage
#include "vxworks.h"
#include "Arch / Arm / Arm.h"
#include "regs.h"
#include "syslib.h"
#include "config.h"
#include "s4510b.h"
/ * Internals * /
.globl _Rominit / * Start of system code * /
.globl _sdata / * start of data * /
/ * EXTERNALS * /
.extern _romstart / * system initialization routine * /
_SDATA:
.asciz "start of data"
.balign 4
.Text
.balign 4
/ ************************************************** *****************************
*
* Rominit - Entry Point for vxworks in rom
*
* Rominit
*
* Int StartType / @ Only used by 2nd entry point @ /
*)
* Internal
* Systomonitor Examines The Rom for the first instruction and the string
* "Copy" in The Third Word So if this change, systemonitor must be added.
* /
_Rominit:
Rominit:
Cold:
MOV R0, #boot_cold / * Fall Through To Warm Boot Entry * /
WARM:
B Start
/ * Copyright Notice APPEARS At Beginning of Rom (in text segment) * /
.ascii "CopyRight 2000-2001 STM / CAP GEMINI."
.balign 4
Start:
NOP
NOP
NOP
NOP
/ * Part 1 * /
/ ************************************************** *************** /
/ * Disable Interrupts in CPU and Switch To SVC32 MODE * /
MRS R0, CPSR
BIC R0, R0, #mask_mode
ORR R0, R0, # mode_svc32
ORR R0, R0, #i_bit
ORR R0, R0, #F_bit
MSR CPSR, R0
LDR R2, = ARM7_INTMASK / * R2-> Interrupt Controller * /
MVN R1, # 0 / * & fffffff * /
STR R1, [R2] / * Disable All Interrupt SoucRes * /
LDR R2, = ARM7_INTPEND / * R2-> Interrupt Pend Register. * /
MVN R1, # 0 / * & fffffff * / STR R1, [R2] / * CLEAR All Interrupt Flags. * /
/ * Part 2 * /
/ ************************************************** **************** /
LDR R0, = ARM7_SYSCFG
LDR R1, = 0x87fffa0 / * config syscfg * /
STR R1, [R0] / * Cache & WB Disabled * /
/ * part 3 * /
/ ************************************************** *************** /
/ * jump to flash addr exec @ 16m * /
LDR LR, L $ _HIPOSN / * LOAD LR with the ROM Address where * /
/ * TO JUMP AFTER Remap (this is an * /
/ * AddressAfter 0x20000000) * /
MOV PC, LR / * JUMP To Address Stored In LR * /
/ * Part 4 * /
/ ************************************************** *************** /
/ * Initalize the memory as followa: * /
/ * Flash @ 16 ~ 18 m * /
/ * SDRAM @ 0 ~ 16m * /
Hiposn:
LDR R1, = RextdbWTH / * EXTDBWTH * /
LDR R2, = RROMCON0 / * ROMCON0 @ 16m ~ 18m * /
LDR R3, = RROMCON1 / * ROMCON1 @ disabled * /
LDR R4, = RROMCON2 / * ROMCON1 @ disabled * /
LDR R5, = RROMCON3 / * ROMCON1 @ disabled * /
LDR R6, = RROMCON4 / * ROMCON1 @ disabled * /
LDR R7, = RROMCON5 / * ROMCON1 @ disabled * /
LDR R8, = RSDRAMCON0 / * SDRAMCON0 @ 0M ~ 16M * /
LDR R9, = RSDRAMCON1 / * SDRAMCON1 @ disabled * /
LDR R10, = RSDRAMCON2 / * SDRAMCON2 @ Disabled * /
LDR R11, = RSDRAMCON3 / * SDRAMCON3 @ disabled * /
LDR R12, = RSRefextcon
LDR R0, = ARM7_EXTDBWTH
STMIA R0, {R1-R12}
/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------- * /
/ *
* Initialize the Stack Pointer to Just Before Where The THE
* Uncompress Code, Copied from Rom To Ram, Will Run.
* /
/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------- * /
LDR SP, L $ _STACK_ADDR
MOV FP, # 0 / * ZERO FRAME POINTER * /
/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------- * /
/ * Jump to c entry Point in Rom: Routine - Entry Point ROM Base * /
/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------- * /
LDR PC, L $ _RSTRTIM / * USE ARM MODE (No thumb) * /
/ ************************************************** **************************** /
/ *
* PC-Relative-Addressable Pointers - LDR RN, = SYM IS BROKEN
* Note "_" After "$" to Stop PreProcessor Preforming Substitution
* /
.balign 4
L $ _hiposn:
.long rom_text_adrs hiposn - _Rominit
L $ _rstrtinrom:
.long rom_text_adrs _romstart - _Rominit
L $ _STACK_ADDR:
.long stack_adrs
Note: Flash will be mirrored to 0x00000000 after power-on, and start execution.
The value of ROM_TEXT_ADRS is 0x01000000. After the CPU is completed, it will jump to the real address of Flash, which continues to complete the initialization of SDRAM, allocation of memory layout, etc., please refer to TRACE32 one period.