S3C2440-11.und exception

Publisher:暗里著迷Latest update time:2021-09-01 Source: eefocusKeywords:S3C2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1 Undefined instruction

Let's first look at the format of instructions in ARM:

insert image description here

Note: The corresponding bits at the top of this table are from high to low, so 0Xdeadc0de is an undefined instruction (easy to understand)


2 Interrupt vector table

Undefined exceptions, first look at the interrupt vector table:

insert image description here

After the board is powered on, the CPU starts executing from address 0, first executing the reset operation, and after triggering an exception, it will jump to the corresponding address to enter the exception handler, so we need to start at address 0 and follow the instructions of the interrupt vector table to write the corresponding exception handler, as follows:


.text

.global _start


_start:

/* Exception vector table */

bl reset /* 0X0 Reset Power-on reset, start executing the program from address 0, in order: turn off the watchdog, configure the clock system, initialize sdram, copy the code to sdram (relocation), clear the .bcc segment, enter the main function*/

ldr pc, =und_addr /* 0X4 Undefined instruction */

// bl do_swi /* 0X8 Software Interrupt */

// bl do_ap /* 0XC Abort(prefetch) */

// bl do_ad /* 0X10 Abort(data) */

// bl do_re /* 0X14 Reserved */

// bl do_irq /* 0X18 IRQ */

// bl do_fiq /* 0X1C FIQ */  


3 Set an undefined instruction

Artificially introduce an undefined instruction. If you encounter an undefined instruction, such as the following instruction 0Xeeadc0de: (Correction: Change 0Xdeadc0de to 0Xeeadc0de, because 0Xdeadc0de is actually a conditional execution statement. Only when the condition is triggered will the following code be executed)

insert image description here

When the CPU executes here, it will fetch the instruction. If it finds that this is an undefined instruction, it will automatically trigger the und exception. The CPU will find the address mapping of the und handler in the interrupt vector table and execute the und handler through the jump instruction.


4 Calling C functions

The und processing function can be written in C language and called in assembly, but pay attention to the passing of parameters:


The C function is as follows:


void Und_Process( unsigned int cpsr )

{

    puts("nrEnter Und_Process!!!nrCPSR is:");//Print prompt information and enter the und processing program

    printHex( cpsr ); // Output the value of the CPSR register to confirm the current mode

    puts("nr");

}


The und exception handling function prints some information.


The parameters are passed in assembly as follows:


  mrs r0, cpsr /* mrs reads the value of the register and passes the parameter to the following function through the r0 register*/


==Note: == The und processing function written in C must use the stack!!! Although we have set the stack pointer sp in the assembly (it is in management mode after power-on, so the stack pointer sp in management mode is set), but for exception mode, each exception mode has its own stack pointer!!! As follows:


insert image description here

Therefore, after entering the und processing program, you must first set the sp_und stack pointer to allocate space for the called C processing function, and just point it to an unused space, such as


 ldr sp, =0x34000000 /* points to the highest address of 64M SDRAM*/


Now you can call the C function!


5 UND exception handler

With the und exception handler, you can call the handler function in assembly, but there are other operations for the exception handler in assembly.


The und exception handler in assembly is as follows:


und_addr:

.word do_und


/* und exception handling, before entering the exception, the hardware completes the following: copy CPSR to SPSR, store the address of the interrupted instruction in lr*/

do_und:

ldr sp, =0x34000000 /* und's stack pointer, pointing to the highest address of 64M SDRAM, allocating space for C function*/

stmdb sp!, {r0-r12,lr} /* Save the scene*/


mrs r0, cpsr /* mrs reads the value of the register and passes the parameter to the following function through the r0 register*/

bl Und_Process


ldmia sp!, {r0-r12, pc}^ /* Restore the scene, note: be sure to add ! to save the changes of sp*/



After the und exception is triggered, before entering the exception program processing, the hardware will perform some operations:


1. Copy CPSR to SPSR


2. M4-M0 in CPSR is automatically set to 11011, entering und mode


3. Store the address of the interrupted instruction in the lr register


4. The program jumps to the address (und) of the interrupt vector table 0X4 to execute the interrupt exception handler


In the exception handler, the following operations are performed:


1. Set up the stack through sp_und


2. Save the scene, including r0~r12 registers and lr register. Saving lr is also necessary because lr contains the return address after the exception is handled.


3. Call C processing function


4. Restore the scene, use ldmia sp!, {r0-r12,pc}^ to restore the values ​​of each register, assign the value of the lr register to the pc register (to be verified, ia is the order), ^ and restore the value in SPSR to CPSR


6 Assembly source code


.text

.global _start


_start:

/* Exception vector table */

bl reset /* 0X0 Reset Power-on reset, start executing the program from address 0, in order: turn off the watchdog, configure the clock system, initialize sdram, copy the code to sdram (relocation), clear the .bcc segment, enter the main function*/

ldr pc, =und_addr /* 0X4 Undefined instruction */

// bl do_swi /* 0X8 Software Interrupt */

// bl do_ap /* 0XC Abort(prefetch) */

// bl do_ad /* 0X10 Abort(data) */

// bl do_re /* 0X14 Reserved */

// bl do_irq /* 0X18 IRQ */

// bl do_fiq /* 0X1C FIQ */ 


und_addr:

.word do_und


/* und exception handling, before entering the exception, the hardware completes the following: copy CPSR to SPSR, store the address of the interrupted instruction in lr*/

do_und:

ldr sp, =0x34000000 /* und's stack pointer, pointing to the highest address of 64M SDRAM, allocating space for C function*/

stmdb sp!, {r0-r12,lr} /* Save the scene*/


mrs r0, cpsr /* mrs reads the value of the register and passes the parameter to the following function through the r0 register*/

bl Und_Process


ldmia sp!, {r0-r12, pc}^ /* Restore the scene, note: be sure to add ! to save the changes of sp*/


.align 4


reset:

/* Disable watchdog */

ldr r0, =0x53000000

ldr r1, =0

str r1, [r0]


/* Set MPLL, FCLK : HCLK : PCLK = 400m : 100m : 50m */

/* LOCKTIME(0x4C000000) = 0xFFFFFFFF */

ldr r0, =0x4C000000

ldr r1, =0xFFFFFFFF

str r1, [r0]


/* CLKDIVN(0x4C000014) = 0X5, tFCLK:tHCLK:tPCLK = 1:4:8 */

ldr r0, =0x4C000014

ldr r1, =0x5

str r1, [r0]


/* Set the CPU to work in asynchronous mode */

mrc p15,0,r0,c1,c0,0

orr r0,r0,#0xc0000000 //R1_nF:OR:R1_iA

mcr p15,0,r0,c1,c0,0


/* Set MPLLCON(0x4C000004) = (92<<12)|(1<<4)|(1<<0) 

* m = MDIV+8 = 92+8=100

* p = PDIV+2 = 1+2 = 3

* s = SDIV = 1

* FCLK = 2*m*Fin/(p*2^s) = 2*100*12/(3*2^1)=400M

*/

ldr r0, =0x4C000004

ldr r1, =(92<<12)|(1<<4)|(1<<0)

str r1, [r0]


/* Once the PLL is set, the lock time will be locked until the PLL output is stable

* Then the CPU operates at the new frequency FCLK

*/


/* Set up memory: sp stack */

/* Distinguish whether it is NOR/NAND startup

* Write 0 to address 0, then read it out

* If you get 0, it means the content at address 0 has been modified, it corresponds to ram, this is nand boot

* Otherwise, it is NOR start

*/

mov r1, #0

ldr r0, [r1] /* read out the original value backup */

str r1, [r1] /* 0->[0] */ 

ldr r2, [r1] /* r2=[0] */

cmp r1, r2 /* r1==r2? If they are equal, it means NAND boot*/

ldr sp, =0x40000000+4096 /* Assume that it is NOR startup*/

moveq sp, #4096 /* nand start */

streq r0, [r1] /* restore the original value */


/* When relocating the code, first initialize SDRAM, then copy the code, then clear the .bss segment (to prevent memory access errors), and finally execute the main function, which is executed in the relocated SDRAM*/

bl sdram_init

//bl sdram_init2 /* Uses an array with initial values, not position-independent code*/


/* Relocate the entire program in text, rodata, and data segments*/

bl copy2sdram


/* Clear BSS segment */

bl clean_bss


ldr pc, =UartInit

UartInit:

bl uart0_init

/* Introduce the und instruction to trigger the und exception*/

und_test:

.word 0Xeeadc0de


//bl main /* Use BL command for relative jump, the program is still executed in NOR/sram*/

ldr pc, =main /* Absolute jump, jump to SDRAM */


halt:

b halt


7. Notes

LR and PC

When an exception occurs, the current interrupted address will be automatically saved in the lr register by the hardware. You can view the value of the address to be stored in the lr register in the corresponding table:

insert image description here

It can be found that when the und exception occurs, the value of the lr register is PC+4 (ARM instruction set)


Save the scene

Save the scene, that is, save registers r0~r12 (after entering the exception mode, the hardware will save the CPSR to the SPSR)


So when saving r0~r12, the lr register is also saved:


 stmdb sp!, { r0-r12, lr }


Perform the opposite operation when restoring the site:


 ldmia sp!, { r0-r12, pc }^ /* ia: read first and then add ^ will restore the value of spsr to cpsr*/


Interrupt vector table jump

When jumping, use ldr pc, =do_und (to prevent errors due to relocation). The C function of bl Und_Process below is also in SDRAM, which is the running address after relocation.


In fact, ldr pc, =do_und is a pseudo instruction, which stores the value of do_und (that is, the first address of the und exception handler) in memory, then reads the memory and assigns a value to pc. This memory is often immediately following the assembly file, but when the assembly file is too large (more than 4K, the value outside the 4K address will not be read when NAND is started), it may cause an error.


You can indirectly place the value of do_und in the assembly file:


 und_addr:

  .word do_und


In this way, only the following are required in the interrupt vector table:


 ldr pc. = und_addr


As shown:

insert image description here

Program execution order

The memory execution order of the program is:


1.0 Address b reset


2.0X4 address ldr pc, =und_addr


3. The next memory space is the relocation related code


4.ldr pc, =sdram jumps to the relocated code to execute the program (all codes are copied to SDRAM 0X30000000)

[1] [2]
Keywords:S3C2440 Reference address:S3C2440-11.und exception

Previous article:S3C2440—12.Key interrupt
Next article:ARM—Exception interrupt handling

Recommended ReadingLatest update time:2024-11-16 11:48

linux 2.6.22.6 porting
The board is GQ2440 made by China Embedded Technology Co., Ltd. For the main transplantation steps, please refer to Mr. Wei Dongshan’s "Complete Manual of Embedded Linux Application Development" 1. Download the kernel and apply patches 2. Use config_ok to configure the kernel. 3. Modify the value of MACH_TYPE_S3C2440
[Microcontroller]
How to write the interrupt vector of s3c2440 bare metal (1)
Use the jump instruction directly (B) b reset b undefined_instruction b software_interrupt b prefetch_abort b data_abort b not_used b q b fiq /* ... */ After disassembly, it looks like this (the starting address when linking is 0x33f80000): 33f80000 .text : 33f80000: ea000006 b 33f80020 reset 33f80004: ea000006 b 33f
[Microcontroller]
S3C2440 chip clock (2)
Read the manual   Questions about formulas in the manual Frequency division ratio If the frequency of some parts is too high, the device will not work properly, so in order to meet different needs, the clock on some buses needs to be reduced. Clock Setting Example
[Microcontroller]
S3C2440 chip clock (2)
Porting OpenCV open source image processing function library to S3C2440
1. Introduction OpenCV is an open source image processing library based on C/C++ language. Its code is optimized for real-time image processing Good portability Can perform routine operations of image/video loading, saving and acquisition Has low-level and high-l
[Microcontroller]
s3c2440 memory controller and SDRAM basic test
In the LED and serial port programs we experimented with earlier, the CPU sent the address to a specific register and wrote the corresponding bits in the register to meet the control requirements. The first type is GPIO gate circuits such as LEDs, and the second type is protocol types such as serial ports. These are
[Microcontroller]
s3c2440 memory controller and SDRAM basic test
IIC control of s3c2440
Both the tq2440 and mini2440 are connected with EEPROMs, and their function is just to test whether the I2C bus is available. The EEPROM model on mini2440 is AT24C08, and on tq2440 it is AT24C02A. They have different capacities and address lines. The S3C2440A RISC microprocessor can
[Microcontroller]
IIC control of s3c2440
Detailed explanation of S3C2440 interrupt process (ADS, TQ2440)
The following takes the serial port UART0 receive interrupt as an example: When the serial port receive interrupt is initialized, there is such a sentence: pISR_UART0=(unsigned)__irq UART0 _GetInt /Put the entry address of the interrupt service subroutine UART0 _GetInt into pISR_TICK, S3C2440addr.h #define pISR_UART
[Microcontroller]
Detailed explanation of S3C2440 interrupt process (ADS, TQ2440)
Porting Qt graphical interface application to S3C2440 arm development board
1. Enter a GUI application directory that has been written by Qt. For example, my application directory is /home/czd/qt_project/mp3player/. $ cd /home/czd/qt_project/mp3player/. I found that there is a mp3player.pro file in it. In the qt-embedded-linux environment configured above, a Trolltech directory is automatical
[Microcontroller]
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号