Function pointers are the basis for implementing callback functions, and callback functions are the basis of C program architecture. Therefore, the importance of function pointers is self-evident. However, when testing the program on the ARM development board recently, I found that although the function pointer can be compiled, it always reports an error when running. The following is the source code of the simplest test program.
static void test()
{
puts("testn");
}
static void(*f)() = test;
void Main(void)
{
led_init();
key_init();
io_init(0);
f();
while(1){
puts("-------hello from main()----------n");
delay(100000);
}
}
The assembly code compiled with gcc -S is as follows:
.cpu arm10tdmi
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 34, 0
.eabi_attribute 18, 4
.file "main.c"
.section .rodata
.align 2
.LC0:
.ascii "test1200"
.text
.align 2
.syntax unified
.arm
.fpu softvfp
.type test, %function
test:
@ args = 0, pretend = 0, frame = 0
@frame_needed = 1, uses_anonymous_args = 0
push {fp, lr}
add fp, sp, #4
ldr r0, .L2
bl puts
nop
pop {fp, pc}
.L3:
.align 2
.L2:
.word .LC0
.size test, .-test
.data
.align 2
.type f, %object
.size f, 4
f:
.word test
.section .rodata
.align 2
.LC1:
.ascii "-------hello from main()----------1200"
.text
.align 2
.LC1:
.ascii "-------hello from main()----------1200"
.text
.align 2
.global Main
.syntax unified
.arm
.fpu softvfp
.type Main, %function
Main:
@ args = 0, pretend = 0, frame = 0
@frame_needed = 1, uses_anonymous_args = 0
push {fp, lr}
add fp, sp, #4
bl led_init
bl key_init
mov r0, #0
bl io_init
ldr r3, .L6
ldr r3, [r3]
blx r3
.L5:
ldr r0, .L6+4
bl puts
ldr r0, .L6+8
bl delay
b .L5
.L7:
.align 2
.L6:
.word f
.word .LC1
.word 100000
.size Main, .-Main
.ident "GCC: (GNU) 6.2.0"
.section .note.GNU-stack,"",%progbits
It can be seen that when the function pointer is called, it is compiled into a BLX instruction. This instruction jumps and changes the running state (ARM and THUMB switch). Obviously, this compilation is wrong. Can an expert help analyze what went wrong?
Are special compilation parameters required?
Headache!!!
2016-12-20 Update:
The reasons have been found, the key points are as follows:
GCC compiles absolute address calls (including function pointer calls) into BLX Rn instructions. BX, BLX instructions are used for absolute jumps (B, BL is used for jumps) to the address contained in Rn. In summary, the X has two meanings: (1) It indicates whether to switch between ARM/Thum based on whether the lowest bit of Rn is 0. (2) It can jump to an absolute address.
The instruction set of S3C2440A does not have BLX, but only BX. Therefore, an invalid instruction error will occur during operation.
Solutions:
(1) Run GCC with appropriate options to avoid generating BLX instructions. It is not clear what options are needed.
(2) Use the Undefined exception handler to simulate the BLX instruction. This may seem complicated, but it is actually very simple to implement and has been implemented in v0.9.
Previous article:Read data from NAND Flash and move the code to SDRAM for execution
Next article:GNU Freestanding (Naked) C ARM cross-development environment creation and testing
- Popular Resources
- Popular amplifiers
- 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
- How to detect power supply voltage in R7F0C001
- Ask for advice chip
- Commonly used algorithms for drones - Kalman filter (XII)
- Application of Torque Sensors in the Automotive Industry
- Vayo-CAM365 Function Detailed Explanation (I)
- Apply for DCM evaluation samples for free!
- ESP32 Arduino 2.0.3 has been released
- What is your understanding of Article 82 of the Labor Contract Law of the People’s Republic of China?
- [Synopsys IP Resources] Automotive SoCs will be reshaped, and IP will usher in new changes
- Technical Article: What is Switch Mode Power Supply Current Sensing?