With the improvement of living standards and the advancement of IT technology, the processing power of 8-bit processors can no longer meet the needs of embedded systems; while 16-bit processors have not made great breakthroughs in performance and cost. And in the development of 8-bit machines, most of the assembly language is used to write user programs. This makes the program maintainability, portability, etc. are greatly challenged. Based on this, ARM has introduced a series of 32-bit embedded microcontrollers in a timely manner. Currently widely used ARM7 and ARM9 series, ARM7TDMI core ARM7 processor is widely used in industrial control, instrumentation, automotive electronics, communications, consumer electronics and other embedded devices. This article mainly uses the LPC2119 of the ARM7TDMI core of philips as an example to analyze how to write the startup code of ARM7.
1, the startup code
In the development of embedded system software, applications are usually written in C language on the development platform of embedded operating systems. However, after the ARM system power-on reset, it is necessary to set the interrupt vector table, initialize each mode stack, set the system clock frequency, etc. These processes are all directed to the operation of the ARM internal register structure, and programming in C language is difficult to achieve. So before going to the application c / c + + to write, you need to write the startup code in ARM assembly language, the startup code to complete the system initialization and jump to the user C program. In ARM design development, the writing of startup code is a very important process. However, the startup code differs from the specific target system and development system, but usually contains the following parts:
·Vector table definition
Address remapping and transfer of interrupt vector table
·Stack initialization
·Set the system clock frequency
·Interrupt register initialization
·Enter C application
The following is a combination of PHILIPS LPC2119 startup code to analyze and explain the ARM7 processor startup code.
1.1 vector table definition
After the ARM chip is powered on or reset, the system enters the management mode, ARM state, and the PC (R15) points to the address 0x00000000. The interrupt vector table sets a memory space for each interrupt, and stores a jump instruction. This instruction causes the PC pointer to point to the corresponding interrupt service routine entry, and then executes the corresponding interrupt handler. The interrupt vector table of LPC2219 is similar to other ARM core-based chip interrupt vector table. Just pay attention to LPC2219 to make the 32-bit accumulation of all data in the vector table and zero (the machine code of 8 words of 0x00000000-0x0000001C is accumulated). The program runs offline.
1.2 Address Remapping and Transfer of Interrupt Vector Table
After reset, the ARM7 processor reads the first instruction from address 0 and executes it. Therefore, after system power-on, address 0 must be non-volatile ROM/FLASH, so that the processor has the correct available instructions. In order to speed up the processing of interrupts and to handle interrupts in different operating system modes, this requires re-mapping a small portion of the interrupt vector table, BootbLOCk, and SRAM space. ARM has a very flexible memory address allocation feature. There are two cases of the ARM processor's address remapping mechanism:
1 Remap is done by a special register, just set the corresponding bit of the corresponding Remap register.
2 There is no special Remap control register that needs to rewrite the Bank register used to control the memory start address to implement Remap. The remapping on the LPC2119 can be implemented by a memory map controller. The program that implements the REMAP operation is implemented as follows:
MOV R8, #0x40000000; /Set new vector table start address /
LDR R9, =Interrupt_Vector_Table; /read the original vector table source address /
LDMIA R9!, (R0-R7); / copy the interrupt vector table and the interrupt handler's entry address into RAM (64 bytes) /
STMIA R8!, (R0-R7)
LDMIA R9!, (R0-R7)
STMIA R8!, (R0-R7)
LDR R8, =MEMMAP ; /REMMAP operation /
MOV R9, #0x02
STR R9, [R8]
1.3 Stack Initialization
The setting of each mode stack space in the startup code is for interrupt processing and program jump. When the system responds to an interrupt or a program jump, it needs to save the current processor state and some important parameters in a storage space. Therefore, stack initialization is required for each mode, and a stack base is defined for each mode SP. Address and stack capacity. There are two ways to initialize the stack: the first is to define the stack in conjunction with the scatter-loading file in the ADS development kit. The second and simplest method is to go directly to the corresponding processor mode and specify the corresponding value for the SP register. The procedure for initializing the management mode and interrupt mode stack using the second method is given below:
MSR CPSR_c, #0xD3 ; /Switch to management mode and initialize the stack of management mode /
LDR SP, Stack_Svc
MSR CPSR_c, #0xD2 ; /Switch to IRQ mode and initialize the stack of IRQ mode /
LDR SP, Stack_Irq
...
1.4 System part clock initialization
The clock is the basis for the normal operation of each part of the chip and should be set before entering the main() function. Some ARM7 chips integrate a PLL (phase-locked loop) circuit inside, and users can obtain a higher-frequency clock through the PLL circuit with a low-frequency crystal oscillator. The PLL circuit inside the LPC2119 accepts an input clock frequency range of 10 to 25 MHz, and the input frequency is multiplied by a current controlled oscillator (CCO) to a range of 10 to 60 MHz. At the same time, in order to enable high-speed ARM processor to communicate with low-speed peripherals and reduce power consumption (lower peripheral operation speed to reduce power consumption), LPC2119 integrates an additional frequency divider. The activation of the PLL is controlled by the PLLCON register. The values ​​of the PLL multiplier and divider are controlled by the PLLCFG register. Changes to the PLLCON or PLLCFG registers must follow a strict sequence, otherwise the changes will not take effect (write 0xAA, 0x55 to the PLLFEED register for consecutive VPB cycles, during which the interrupt must be disabled.)
1.5 interrupt initialization
ARM7's Vectored Interrupt Controller can program interrupts into three categories: FIQ, vector IRQ, and non-vector IRQ. The FIQ interrupt request has the highest priority, followed by the IRQ interrupt request, and the non-vector IRQ has the lowest priority. The VIC has 32 interrupt request inputs, but only 17 interrupt inputs are occupied in the LPC2219. The IRQ/FIQ selection for these 17 interrupt sources is controlled by the VICIntSelect register. When the corresponding bit is set to 1, the interrupt is FIQ interrupt, otherwise it is IRQ interrupt. If the IRQ interrupt is set to the vector control register (VICVectCnTIn), the interrupt is a vector IRQ interrupt, otherwise it is a non-vector IRQ interrupt. FIQ interrupts are designed to handle special events that require timely response, and only assign an interrupt source to FIQ as much as possible.
1.6 Entering the C application
At this point, the initialization of each part of the system is basically completed, and can be directly transferred from the startup code to the main() function entry of the application. The example code that goes from the startup code to the application is as follows:
IMPORT main
LDR R0, = main
BX R0
2, summary
A good startup code will provide a good development platform for application development. The writing and difficulty of the startup code is discussed in more detail in this article. There are two special points to note during the stack initialization process:
1 Try to allocate fast and high bandwidth memory to the stack.
2 Try to avoid switching the processor to user mode too early, usually switch to user mode in the final stage of system initialization (user mode does not have permission to modify the CPSR for mode switching).
The rapid development of embedded systems has made the creation of startup code a capability that embedded system developers should have. This article helps readers who are engaged in embedded ARM development understand the meaning of the startup code and write the startup code that suits them.
Suizhou simi intelligent technology development co., LTD , https://www.msmvape.com