We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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.