Zhou Ligong LPC21xx/LPC22xx series ARM7 startup code analysis

Publisher:静静思索Latest update time:2016-07-20 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
Someone has already written an article about Zhou Ligong's analysis of the boot code of lpc2000 (ARM7TDMI). I originally wanted to analyze the boot code of s3c2410 (ARM920T), but after reading the boot code of 2410, I found that some things were not very clear to me. I have little experience in ARM9.

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.

IMPORT __use_no_semihosting_swi

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.

IMPORT  FIQ_Exception                   

IMPORT  __main                             

IMPORT  TargetResetInit

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,CODE,READONLY

        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, DATA, NOINIT

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, DATA, NOINIT, ALIGN=2

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 data at 0x000001fc must be 0x87654321.\nPlease delete some source before this line."

        ENDIF

CrpData

    WHILE . < 0x1fc

    NOP

    APPLY

CrpData1

    DCD 0x87654321 ;/*When the Data is 0x87654321, user code be protected. When this number is 0x87654321, the user program is protected*/

    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.

Reference address:Zhou Ligong LPC21xx/LPC22xx series ARM7 startup code analysis

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

ARM7 Bluetooth hardware structure and software flow
1 Introduction In industrial sites, due to some harsh environments and inconvenient wiring, Bluetooth wireless communication technology can be used to achieve data communication. At the same time, there are many devices that are interconnected in different ways in industrial sites, including non-intelligent simple d
[Microcontroller]
ARM7 Bluetooth hardware structure and software flow
Design of Fingerprint Attendance Machine Based on ARM7
introduction Biometric technology relies on its uniqueness and reliability. After nearly ten years of development, its application has become more and more extensive and mature. At present, fingerprint recognition technology has become popular in the civilian market, and fingerprint attendance machine is
[Microcontroller]
Design of Fingerprint Attendance Machine Based on ARM7
Record a data transmission method, ARM7 transmits data to GPIO
/*********************************************************************** * Name: AD9850_SendToGPIO() * Function: Send data to GPIO * Entry parameters: DataTemp: sent data * Export parameters: None ***************************************************************************/ void AD9850_SendToGPIO(uint8 DataTemp) {    
[Microcontroller]
Chinese LCD technology based on ARM7 microprocessor
1 Introduction Liquid crystal display LCD, as a display device with low power consumption, small size and no radiation, has been widely used in various embedded electronic products in recent years. LCD can be divided into segment type, character type and There are three types of dot matrix LCD. Among them, segment LCD
[Power Management]
About the keyboard and VFD display interface technology of ARM7
introduction The instrumentation industry and industrial production processes have higher requirements for real-time performance, processing speed, intelligence, etc. ARM microprocessors have the characteristics of low power consumption, high instruction throughput, real-time interrupt response, and high cost-effect
[Microcontroller]
About the keyboard and VFD display interface technology of ARM7
ARM7 LPC2378 remote upgrade ---- soft interrupt SWI
Here, I would like to share with you the questions and understandings I encountered when studying this article. The relevant soft interrupt code in the LPC2300.S file is as follows:          EXPORT SWI_Handler     extern EnableIrqFunc ;Enable interrupt function name, implemented in C language     extern DisableIrqFunc
[Microcontroller]
ARM7 LPC2378 remote upgrade ---- soft interrupt SWI
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号