Preface
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; and 16-bit processors have not made great breakthroughs in performance and cost. In addition, in the development of 8-bit machines, assembly language is mostly used to write user programs. This makes the maintainability and portability of the program extremely challenging. It is based on this that ARM has launched a series of 32-bit embedded microcontrollers in a timely manner. Currently, the ARM7 and ARM9 series are widely used. The ARM7 processor with ARM7TDMI core is widely used in embedded devices such as industrial control, instrumentation, automotive electronics, communications, and consumer electronics. This article mainly takes the LPC2119 of Philips' ARM7TDMI core as an example to analyze how to write the startup code of ARM7.
1. Startup code
In the development of embedded system software, applications are usually written in C language on the development platform of embedded operating system. However, after the ARM system is powered on and reset, it is necessary to set the interrupt vector table, initialize the stacks of each mode, set the system clock frequency, etc., and these processes are operations on the internal register structure of ARM, which are difficult to implement using C language programming. Therefore, before turning to the C/C++ writing of the application, it is necessary to write the startup code in ARM assembly language, which completes the system initialization and jumps to the user C program. In ARM design and development, the writing of startup code is an extremely important process. However, the startup code varies with the specific target system and development system, but usually includes the following parts:
Vector table definition
Address remapping and transfer of interrupt vector table
Stack initialization
Set the system clock frequency
Initialization of interrupt registers
Enter C application
The following will analyze and explain the writing of the startup code for the ARM7 processor in conjunction with the startup code of PHILIPS's LPC2119.
1.1 Vector table definition
After the ARM chip is powered on or reset, the system enters the management mode, ARM state, and PC (R15) points to the address 0x00000000. The interrupt vector table sets a storage space of 1 word for each interrupt, storing a jump instruction. Through this instruction, the PC pointer points to the corresponding interrupt service program entry, and then executes the corresponding interrupt handler. The interrupt vector table of LPC2219 is similar to the interrupt vector table of other chips based on the ARM core. As long as you pay attention to the fact that LPC2219 makes the 32-bit cumulative sum of all data in the vector table zero (the 8-word machine code accumulation of 0x00000000-0x0000001C), the user's program can be run offline.
1.2 Address remapping and transfer of interrupt vector table
The ARM7 processor reads the first instruction from address 0 after reset and executes it. Therefore, address 0 must be non-volatile ROM/FLASH after the system is powered on to ensure that the processor has the correct instructions available. In order to speed up the processing of interrupts and implement the processing of interrupts in different operating system modes, it is necessary to remap the interrupt vector table, Bootb LOC k and a small part of the SRAM space. ARM has a very flexible memory address allocation feature. There are two situations in the address remapping mechanism of the ARM processor:
① Remapping is done by a dedicated register, and you only need to set the corresponding bit of the corresponding Remap register.
② There is no dedicated Remap control register. The bank register used to control the memory start address needs to be rewritten to implement Remap. Remapping on LPC2119 can be achieved through the memory mapping controller. The program to implement the REMAP operation is as follows:
MOV R8,#0x40000000; /Set the starting address of the new vector table/
LDR R9,=Interrupt_Vector_Table; /Read the original vector table source address/
LDMIA R9!, (R0-R7); /Copy the interrupt vector table and the entry address of the interrupt handler to 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 stack space for each mode in the startup code is for interrupt processing and program jump. When the system responds to an interrupt or a program jumps, the current processor status and some important parameters need to be saved in a storage space, so the stack initialization work must be performed for each mode, and a stack base address and stack capacity are defined for the SP of each mode. There are two ways to initialize the stack: The first method is to define the stack in combination with the scattered loading file in the ADS development kit. The second method is the simplest and most commonly used one, which is to directly enter the corresponding processor mode and specify the corresponding value for the SP register. The following is a program for initializing the management mode and interrupt mode stack using the second method:
MSR CPSR_c, #0xD3; /Switch to management mode and initialize the management mode stack/
LDR SP, Stack_Svc
MSR CPSR_c, #0xD2; /Switch to IRQ mode and initialize the IRQ mode stack/
LDR SP, Stack_Irq
…
1.4 Initialization of some system clocks
The clock is the basis for the normal operation of all parts of the chip, and should be set before entering the main() function. Some ARM7 chips have integrated PLL ( phase-locked loop ) circuits . Users can use low-frequency crystal oscillators to obtain a higher-frequency clock through the PLL circuit. The input clock frequency range accepted by the PLL circuit inside the LPC2119 is 10-25MHz , and the input frequency is multiplied to the range of 10-60MHz through a current- controlled oscillator ( CCO ). At the same time, in order to enable the high-speed ARM processor to communicate normally with low-speed peripherals and reduce power consumption (reducing the operating speed of peripherals to reduce power consumption), LPC2119 integrates an additional 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 order, otherwise the changes will not take effect (write 0xAA, 0x55 to the PLLFEED register in consecutive VPB cycles , and interrupts must be disabled during this period.)
1.5 Interrupt initialization
ARM7's Vectored Interrupt Controller can program interrupts into three categories: FIQ, vectored IRQ, and non-vectored IRQ. FIQ interrupt requests have the highest priority, followed by IRQ interrupt requests, and non-vectored IRQ has the lowest priority. VIC has 32 interrupt request inputs, but only 17 interrupt inputs are occupied in LPC2219. The IRQ/FIQ selection of these 17 interrupt sources is controlled by the VICIntSelect register. When the corresponding bit is set to 1, the interrupt is a FIQ interrupt, otherwise it is an IRQ interrupt. If the IRQ interrupt is set to the vector control register (VICVectCntIn), the interrupt is a vectored IRQ interrupt, otherwise it is a non-vectored IRQ interrupt. FIQ interrupts are specifically used to handle special events that require timely responses, and only one interrupt source is assigned 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 you can directly transfer from the startup code to the main() function entry of the application. The example code for transferring from the startup code to the application is as follows:
IMPORT main
LDR R0, =main
BX
2. Summary
An excellent startup code will provide a good development platform for application development. This article discusses the writing and difficulties of startup code in detail. In the stack initialization process, special attention should be paid to two points:
① Try to allocate fast and high-bandwidth memory to the stack.
② Try to avoid switching the processor to user mode too early. Generally, it is switched to user mode in the final stage of system initialization (user mode does not have the authority to switch modes by modifying CPSR).
The rapid development of embedded systems has made the writing of boot code a skill that embedded system developers should have. This article helps readers who are engaged in embedded ARM development to understand the connotation of boot code and write boot code that suits them.
Previous article:Design of USB Host System in μCOS-II
Next article:Remote wireless water supply measurement and control system based on embedded and wireless communication technology
Recommended ReadingLatest update time:2024-11-15 07:33
- Popular Resources
- Popular amplifiers
- Practical Deep Neural Networks on Mobile Platforms: Principles, Architecture, and Optimization
- ARM Embedded System Principles and Applications (Wang Xiaofeng)
- ARM Cortex-M4+Wi-Fi MCU Application Guide (Embedded Technology and Application Series) (Guo Shujun)
- An ARM7-based automotive gateway solution
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- [GD32L233C-START Review] Part 1: Any surprises after unboxing?
- FAQ_About BlueNRG-2 port retention in low power mode
- A batch of KSZ8041NLI-TR Ethernet transceiver chips are available.
- GD32E230C finally downloaded and burned successfully
- MSP430 MCU general I/O port settings sharing
- STM32MP157A-DK1 Review (1) Official OpenSTLinux Flashing
- pyboard receives serial port data conversion problem
- Notepad Editor - Verilog Code Snippets and Syntax Checker
- [ESK32-360 Review] + Getting to know the ESK32-360 development board
- TI-83 Premium CE Python Edition Calculator