So let's do an ARM7 startup code analysis. Compared with the one on the Internet, I mainly focus on the startup.s file. The startup.s on the Internet is almost glossed over.
The source code is marked in red.
SVC_STACK_LEGTH EQU 0
FIQ_STACK_LEGTH EQU 0
IRQ_STACK_LEGTH EQU 256
ABT_STACK_LEGTH EQU 0
AND_STACK_LEGTH EQU 0
NoInt EQU 0x80
USR32Mode EQU 0x10
SVC32Mode EQU 0x13
SYS32Mode EQU 0x1f
IRQ32Mode EQU 0x12
FIQ32Mode EQU 0x11
The above lines of code do not need to be analyzed too much. They just define a few symbols. Just think of EQU as #define in C. I will explain the specific values defined in the following code.
IMP
The above statement is used to disable the semihosting mechanism in the code. I won't go into detail about what semihosting is, there are many online. Here I will just explain that Semihosting is mainly used for debugging and is generally disabled in the release version of the code.
IMP
IMP
IMP
The above three lines declare the external labels to be introduced for use below.
EXPORT bottom_of_heap
EXPORT StackUsr
EXPORT Reset
EXPORT __user_initial_stackheap
The above four lines declare the labels to be used in other files.
AREA vectors,CO
ENTRY
The above line declares the entry point of the assembly file, and the entire file starts executing from here.
Reset
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0xff0]
LDR PC, FIQ_Addr
The above lines configure the interrupt vector table. The order of the interrupt vector table cannot be changed because it is stipulated by ARM7. You can refer to relevant books. There are a few questions to explain here.
First, regarding DCD 0xb9205f80, according to the interrupt vector table distribution diagram of ARM7, this position is a reserved bit. But why should we use the value 0xb9205f80?
According to Zhou Ligong, the NXP series LPC21xx and LPC22xx chips require that "the sum of all 32-bit data in the interrupt vector table must be 0, otherwise the program cannot run offline". I disassembled it in AXD (as shown below), and added the 8 machine codes in the interrupt vector table: 0xe59ff018*6+0xe51ffff0+0xb9205f80. Yes, the result is zero. But I encountered a problem. In the experiment, I changed the value of 0xb9205f80 to any value, and the program ran without any problem. I am very confused. This problem needs to be solved... (I hope experts can give me some advice).
Second, about LDR PC, [PC, #-0xff0]. It should be IRQ interrupt, why is it this sentence? In fact, I mentioned this in one of my blog articles.
The three-stage pipeline structure of ARM7 causes PC to point to the last 8 bytes of the current instruction. Originally, IRQ should be placed at 0x00000018. After the statement LDR PC, [PC, #-0xff0] is executed, the current value of PC is 0x00000018+8-0xff0. It is easy to calculate that its result is 0xfffff030. Just look at the manual of lpc22xx and you will know. This address is VICVectAddr. In other words, this address should be the entry address of the IRQ service program, but this address is placed in the VICVectAddr register. There is a description of VICVectAddr in the English manual. After reading it, it is easy to understand what is going on: Vector Address Register. When an IRQ interrupt occurs, the IRQ service routine can read this register and jump to the value read
ResetAddr DCD ResetInit
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
Take off DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
These lines allocate memory space for the interrupt labels in the interrupt vector table above, that is, their execution addresses. At first, I had a question, why not just use LDR PC, ResetInit, but use DCD to transfer, then I checked online, and then I suddenly realized that the address in the ldr instruction must be within the 4KB range of the current instruction address, and using DCD to transfer can address the entire program space.
Undefined
B Undefined
SoftwareInterrupt
B SoftwareInterrupt
PrefetchAbort
B PrefetchAbort
DataAbort
B DataAbort
FIQ_Handler
STMFD SP!, {R0-R3, LR}
BL FIQ_Exception
LDMFD SP!, {R0-R3, LR}
SUBS PC, LR, #4
These lines do not require much explanation, they just illustrate how the above exceptions are executed.
InitStack
MOV R0, LR
; Set management mode stack
MSR CPSR_c, #0xd3
LDR SP, StackSvc
; Set up interrupt mode stack
MSR CPSR_c, #0xd2
LDR SP, StackIrq
; Set up fast interrupt mode stack
MSR CPSR_c, #0xd1
LDR SP, StackFiq
; Set up the abort mode stack
MSR CPSR_c, #0xd7
LDR SP, StackAbt
; Set up undefined mode stack
MSR CPSR_c, #0xdb
LDR SP, StackUnd
; Set up system mode stack
MSR CPSR_c, #0xdf
LDR SP, =StackUsr
MOV PC, R0
The above is a sub-function named InitStack. As the name implies, this function sets the stack for the seven working modes of ARM. There are three points to say about this code.
First, MSR CPSR_c, #0xdf, this sentence sets the ARM working mode to system mode, or user mode, because system mode and user mode share the same register set. Assigning 0xdf to the CPSR register turns off the IRQ interrupt (you can check the detailed description of CRSR). When the code is executed normally, the processor is in user mode, so the IRQ interrupt will not be executed. Therefore, if you use Zhou Ligong's startup code, when your program needs an interrupt, you should change 0xdf to 0x5f. I have seen many people say on the Internet that they cannot enter the interrupt when using Zhou Ligong's ADS project template. In many cases, this is the reason.
Second, not every mode needs to set up the stack. For example, if your program does not use FIQ, you do not need to set up the stack under fast interrupt.
Third, pay attention to the statement LDR SP, =StackUsr. The others do not have an = sign. Why does this one use an equal sign? This is the difference between the LDR pseudo-instruction and the LDR instruction. LDR SP, =StackUsr loads the address indicated by StackUsr into sp, and LDR SP, StackUnd loads the content of the address indicated by StackUnd into sp. Pay attention to the following sentences:
StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackAnd DCD AndtStackSpace + (AND_STACK_LEGTH - 1)* 4
As you can see, the labels without "=" have been initialized with DCD. What exactly is StackUsr? It is determined by the following statement:
(startup.s file)
AREA Stacks, DA
StackUsr
(scatter-loading file)
STACKS 0x40002000 UNINIT
{
Startup.o (Stacks)
}
Now we know that StackUsr must be a number between 0x40000000 and 0x400020000. This is the stack space in user mode.
ResetInit
BL InitStack
BL TargetResetInit
B __main
After the processor is powered on and reset, it enters this function through the interrupt vector table. The main work of the __main function is to initialize the C library function and enter the C main function through it.
__user_initial_stackheap
LDR r0,=bottom_of_heap
; LDR r1,=StackUsr
MOV pc,lr
The __user_initial_stackheap function is a library function of ADS. If the scatter-loading file is used in the program, this function must be implemented. The stack and heap of the application are established during the initialization process of the C library function. The location of the stack and heap can be changed by redirecting the corresponding subroutines. The address of the stack has been specified in the scatter-loading file, and this function should not modify their values. Use r0 and r1 to return the base address of the heap and stack respectively. You can go to the Internet to find more detailed information about the memory mechanism of ADS.
StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackAnd DCD AndtStackSpace + (AND_STACK_LEGTH - 1)* 4
AREA MyStacks, DA
SvcStackSpace SPACE SVC_STACK_LEGTH * 4 ;Stack spaces for Administration Mode
IrqStackSpace SPACE IRQ_STACK_LEGTH * 4 ;Stack spaces for Interrupt ReQuest Mode
FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 ;Stack spaces for Fast Interrupt reQuest Mode
AbtStackSpace SPACE ABT_STACK_LEGTH * 4 ;Stack spaces for Suspend Mode
UndtStackSpace SPACE UND_STACK_LEGTH * 4 ;Stack spaces for Undefined Mode
The above lines of code allocate space for the stack in each mode. The location of MyStacksA will be specified in the scatter loading file.
IF :DEF: EN_CRP
IF . >= 0x1fc
INFO 1,"\nThe da
ENDIF
CrpData
WHILE . < 0x1fc
NOP
APPLY
CrpData1
DCD 0x87654321 ;/*When the Data
ENDIF
The above lines are actually used for encryption chips, lpc21xx and lpc22xx series ARM7, when your project selects RelInFlash, the code is written into the flash, and the chip is also encrypted at the same time. In the encrypted state, JTAG cannot read the chip, and single-step debugging is not possible. If you want to decrypt, you must use ISP to completely erase it. The above code means to put the data 0x87654321 at the address 0x1fc, so as to realize the encryption function, but the premise is IF: DEF: EN_CRP, that is, the EN_CPP macro is defined. And this macro is automatically defined by ADS when RelInFlash is selected. Then, let's talk about the problem of 0x87654321. The LPC2100 series ARM7 microcontroller is the world's first encryptable ARM chip. The method of encrypting it is to set the specified data at the specified address through the user program. PHILIPS stipulates that for LPC2100 chips (except LPC2106/2105/2104), when the data at the FLASH address 0x000001FC is 0x87654321, the chip is encrypted. So the problem is solved.
Previous article:Reference ARM image file under ADS1.2
Next article:Detailed explanation of the interrupt handling process of the compiler in Realview MDK
Recommended ReadingLatest update time:2024-11-16 16:51
- 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
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Download Keysight Technologies' e-book "X-Apps Treasure Map: Essential Measurement Apps for Signal Analyzers That Accelerate Tests" and receive a gift!
- [Evaluation of EC-01F-Kit, the EC-01F NB-IoT development board] Power-on and serial port test
- ELEXCON 2022 Shenzhen International Electronics Exhibition will open on November 6 (new schedule), hurry up and get your tickets! There are also many gifts waiting for you!
- Registration reminder: In the last few hours, 100 sets of Pingtouge RISC-V ecological development boards worth 390 yuan will be given away for free~
- Visit Avnet New Energy Technology Innovation Cloud Exhibition and win great gifts!
- Python Learning Handbook (4th Edition)
- Small Automotive Front-End 16W Power Supply Reference Design
- What is stray capacitance
- Autodesk EAGLE Trial Record
- Wireless and RF Design Guide: Spread Spectrum Communications Overview