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

Problem in converting the ARM code into THUMB

Hi,
Good Day.

I am working on ARM7TDMI core processor from Analog Devices family (ADuC703x). I developed a preemptive scheduler on the same in ARM environment. The functionality of the same is fine and its working well. For the purpose of optimization, i migrated into thumb mode using Keil RV compiler option (by changing the code generation option to THUMB mode and the optimization level option to 3 in C/C++ tab of the target settings option).

After changing the settings my code size is reduced by 2 KB. But, the complete functionality of the software got changed.

Can anybody help me out to get out of this problem?
Also, I would like to know why this kind of behavior is occurring... Please let me know your valuable suggesions.

Thanking you in anticipation,
Ravi Kumar Desaraju.

  • If I am not mistaken, a CPU scheduler must contain some code in assembly language to save/restore registers, manipulate the stack pointer and so on. Because of this, I don't think that switching to THUMB can be achieved by simply changing compiler options.
    Without seeing the code, I don't think much more can be said.

    Regards,
    - mike

  • Desaraju,
    Are you trying to increase code density? please not that if you are using a 32 bit data bus, you actually decreased your system performance. Note that not all processor registers are as easily accessable when in thumb mode: R8-R12 are only modifiable via MOV, ADD and CMP. Have you remembered to manually change to thumb mode before your context switch is taking place (can be done by a branch)? Also notice that the multiple-register load-store instructions only support the increment after (IA) addressing mode.
    Pay attention to the following table, which represents offsets available from a base pointer per instruction when in thumb mode:

    LDRB, LDRSB, STRB       0 to 31 bytes
    LDRH, LDRSH, STRH       0 to 62 bytes
    LDR, STR                0 to 124 bytes
    

    I am busy with a similar project, never tried it with thumb but I don't see how such a relatively small piece of assembly can win you that much performance when compiled in thumb.

  • Hi Mike,
    Thanks for your response.

    I understand your point. But, I enabled the option "ARM to THUMB interworking" option in the C/C++ and ASM tabs from the target settings menu. I think, the compiler will automatically generate the corresponding code in generating the object.

    Well, as you said, I am using many instructions in the assembly code like... MSR, MRS, PUSH and POP. As I conveyed in my previous message, I developed this code in ARM. ARM architecture doesn't support PUSH and POP instructions. By using the above mentioned option in the compiler (i.e. ARM/THUMB interworking), I observed the code in disassembly window and found that the compiler is internally changing the same. So, I did not modify my assembly code. Also, can you please suggest me any important areas in which I have to concentrate?

    Thanks and Regards,
    Ravi Kumar Deasaraju.

  • Hi Michel,

    Thanks for your response.

    Actually, my code is into 2 parts. The scheduling algorithms and task creation part is implemented in C and ISR, Context switching and Wait state machine are developed in assembly. The C code is consumed huge memory in ARM mode (around 3.5KB) and 1.3 KB is assembly (with ARM mode and optimization level as 0).

    for the above mentioned figures (ROM), I opted for THUMB mode and observed huge optimization result.

    Any ways, the functionality got affected. But, If we use "ARM/THUMB interworking" option from the C/C++ and ASM tab from the target options, I think we can work with any instruction set (ARM/THUMB) since the compiler is taking care about the conversion of instruction from one mode to another mode (ARM to THUMB or THUM to ARM).

    Please give me your valuable suggestions if any?

    Thanks and Regards,
    Ravi Kumar Desaraju.

  • can you explain what you mean by "the functionality got affected"? does you context switch no longer work?
    checking ARM/Thumb interworking will generate assembly code that can either be executed in ARM or in thumb. It has no effect, as far as I know, on pure assembly code.
    So if your context switch does not work, you better carefully check whether your assembly code complies with all thumb rules.

  • I'm not sure how intelligent the 'ARM/THUMB interworking' facility is. Hopefully, it detects all function calls and converts them appropriately.
    I would check the ISR, though. I don't know how interrupts are handled in ADuC703x, but in the MCU I'm dealing with the interrupt handling code enters the ISR in ARM mode.

    - mike

  • Hi Mike,

    Yes, you are right. The same thing is happening with ADuC703x. think its the architecture of ARM7TDMI. I read sme where in the ARM core architecture document saying that, the first instruction of your exception handling (FIQ/IRQ/DATA ABORT/PABORT/SWI) should be written with ARM instruction. The ISR exit will automatically switching the ARM mode into THUM mode in my case. The problem is, in context switching code (independent to ISR), I am invoking the THUMB mode using branch instruction which is not happening properly. The other point is, with in ISR and context switching code I am using few 32-bit move instructions for condition checking. Is there any impact for the same, while working on THUMB architecture (THUMB mode doesn't have any 32-bit move instructions)?

  • Hi,

    Yes.... the problem is with context switching only. I am using few 32-bit move instructions in context switching does it affects any functionality in THUMB mode?

  • The problem is, in context switching code (independent to ISR), I am invoking the THUMB mode using branch instruction which is not happening properly.

    More details would help, preferably the code.

    The other point is, with in ISR and context switching code I am using few 32-bit move instructions for condition checking. Is there any impact for the same, while working on THUMB architecture (THUMB mode doesn't have any 32-bit move instructions)?

    Not sure what you mean. Are you saying you are trying to execute ARM instructions in THUMB mode? If so, of course it won't work.

  • Make sure your branch instruction is the BX (branch and exchange) allowing branching to ARM or Thumb code.

  • Hi,

    Well, the Keil Real view compiler has an option to interwork with both ARM and THUMB mode. It will convert the code into the corresponding architecture.

  • Hi,

    I am executing the "BX LR" instruction with least significant bit of the LR register as 1. Also, I observed the state of T bit in CPSR register after executing the above mentioned instruction. Its switching from ARM mode to THUMB mode.

  • Hi All,

    Is there any impact of running the scheduler in FIQ mode?

    What is the difference between executing the code in user mode and FIQ mode?

    I am running the scheduler in FIQ mode only. The reason for the same is as follows:

    The stack for the FIQ interrupt is defined seperately. Hence, in the occurrence of FIQ interrupt, the ISR is referring the stack defined for FIQ instead of currently executing stack. Therefore, I am running the scheduler in FIQ mode only be y executing "BX LR" instruction in the ISR instead of SUBS PC, LR, #4. By executing the scheduler in FIQ mode, I am able to get the current executing stack reference in FIQ mode and my task switching is happening as expected in ARM mode. When I use the same code for THUMB mode it is not working. Is there any difference in executing the code in FIQ mode and user mode?

  • A major difference is that FIQ is a privileged mode and user mode is not, which affects access to CPSR (user mode can only read it). Why do you plan to execute your scheduling code in user mode? You can of course adjust CPSR while in FIQ mode (as you can from every privileged mode), but why would you? also note that CPSR is not saved automatically if you do that to switch to another privileged mode.

    Note:
    ------
    "There are several ways to enter or leave the Thumb state properly. The usual method is via the Branch and Exchange (BX) instruction. See also Branch, Link, and Exchange (BLX) if you're using an ARM with version 5 architecture. During the branch, the CPU examines the least significant bit (LSb) of the destination address to determine the new state. Since all ARM instructions will align themselves on either a 32- or 16-bit boundary, the LSB of the address is not used in the branch directly. However, if the LSB is 1 when branching from ARM state, the processor switches to Thumb state before it begins executing from the new address; if 0 when branching from Thumb state, back to ARM state it goes."

  • Hi Michel,

    Thanks for your response.

    You mean to say, scheduler should be running in privileged mode (FIQ) and the tasks should run in User mode right?

    Is there any way to switch the modes dynamically....? (i mean can we change the mode setting bits of the CPSR)