This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ARM/Thumb interworking problems

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.

    Jason.