I have a problem with calling ARM code from Thumb (C) code. The problem causes an 'undefined instruction' exception when using the 'switch' statement, because it is trying to call __ARM_switch8 from THUMB code like this:
0005b4 003b MOVS r3,r7 0005b6 f7ff fffe BL __ARM_switch8
Any suggestions? The address of __ARM_switch8 is even (0x10002cc4) and all THUMB code is at odd addresses, but the call to it is not being coded as a register-indirect call...
I have enabled ARM/Thumb interworking for this project.
Which compiler are you using? What C code is behind this?
Hi Reinhard,
I am using the RealView compiler:
IDE-Version: µVision3 V3.51 Copyright (c) Keil Elektronik GmbH / Keil Software, Inc. 1995 - 2007
License Information: XXX
Tool Version Numbers: Toolchain Path: I:\Keil\ARM\BIN30\ C Compiler: ARMCC.Exe V3.0.0.951 Assembler: ARMASM.Exe V3.0.0.951 Linker/Locator: ARMLINK.Exe V3.0.0.951 Librarian: ARMAR.Exe V3.0.0.951 Hex Converter: FROMELF.Exe V3.0.0.951 CPU DLL: SARM.DLL V3.05 Dialog DLL: DARMATS9.DLL Target DLL: BIN\UL2ARM.DLL V1.26b Dialog DLL: TARMATS9.DLL V1.00
Code sample:
do { char *pMs g; TestKey = GetCh(); switch (TestKey) { case KEY_0: pMsg = "0 "; break; case KEY_1: pMsg = "1 "; break; ... } GotoXY(6, 1); // display the key press's description Puts(pMsg); } while (TestKey != KEY_CANCEL);
This compiles to:
;;;506 do 0003c2 46c0 MOV r8,r8 ;;;507 { ;;;508 char *pMsg; ;;;509 ;;;510 TestKey = GetCh(); |L1.964| 0003c4 f7ff fffe BL GetCh 0003c8 0007 MOVS r7,r0 ;;;511 switch (TestKey) 0003ca e0f3 B |L1.1460| ... |L1.1460| 0005b4 003b MOVS r3,r7 0005b6 f7ff fffe BL __ARM_switch8 0005ba 0e1a DCB 0x1a,0x0e 0005bc 1411 DCB 0x11,0x14 0005be 1a17 DCB 0x17,0x1a ... ;;;512 { ;;;513 case KEY_0: ;;;514 pMsg = "0 "; 0005d6 a07e ADR r0,|L1.2000| 0005d8 9000 STR r0,[sp,#0] ;;;515 break; 0005da e045 B |L1.1640| ;;;516 case KEY_1: ;;;517 pMsg = "1 "; 0005dc a07e ADR r0,|L1.2008| 0005de 9000 STR r0,[sp,#0] ;;;518 break; 0005e0 e042 B |L1.1640| ... |L1.1640| 000668 46c0 MOV r8,r8 ;515 ;;;582 } ;;;583 GotoXY(6, 1); // display the key press's description 00066a 2101 MOVS r1,#1 00066c 2006 MOVS r0,#6 00066e f7ff fffe BL GotoXY ;;;584 Puts(pMsg); 000672 9800 LDR r0,[sp,#0] 000674 f7ff fffe BL Puts ;;;585 } while (TestKey != KEY_CANCEL); 000678 2f0a CMP r7,#0xa 00067a d000 BEQ |L1.1662| 00067c e6a2 B |L1.964| ;;;586 SetShiftLock(FALSE); // Makes using the unit difficult if it's left on |L1.1662| ...
My problem is the C 'switch' statement itself which is being handled by an (ARM-coded) function __ARM_switch8 which is being called using 'BL': the processor (Atmel AT91RM9200) isn't switching into ARM mode and the result is an 'undefined instruction' exception.
Thanks,
Jason.
we need to duplicate this issue. Please send a test case to support.intl@keil.com.
Thanks, Reinhard - I have submitted a Test Case.