This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28384S: Code branch in CM4.

Part Number: TMS320F28384S


Hi champs,

My customer wants to implement a bootloader in CM4, he cuts flash memory for boot and app code. The address of app code .resetisr is 0x00210000 and the entry point is 0x002103C5.

The boot code fails to branch to app code if software branch to .resetisr, and it works well if branch to entry point directly. When we look into this problem, find that when we branch to .resetisr the content of PC is 0x002103C4(app code will branch to _c_int00_noinit_noargs right away), not 0x002103C5.

We check the .map file and find that there are two different addresses of _c_int00_noinit_noargs, it seems that this problem is due to ARM Thumb mode, am I correct? What should we do so that CM4 branches to app code .resetisr and executes without problems please?

SECTION ALLOCATION MAP

 output                                 attributes/
section   page    origin      length      input sections
--------  ----  ----------  ----------  ----------------
.resetisr
*          0    00210000    00000006
                  00210000    00000006    startup_cm.obj (.resetisr:resetISR)

.text.1    0    0021017c    00000284
                  0021017c    0000009c    rtsv7M4_T_le_eabi.lib : memcpy_t2.asm.obj (.text)
                  00210218    00000094    app_led_blinky_cm.obj (.text:GPIO_writePin)
                  002102ac    00000076    cm.obj (.text:CM_enableAllPeripherals)
                  00210322    00000002    startup_cm.obj (.text:defaultISR)
                  00210324    00000050    app_led_blinky_cm.obj (.text:main)
                  00210374    00000008    driverlib_cm.lib : sysctl.obj (.tramp.SysCtl_delay.1)
                  0021037c    00000048                     : sysctl.obj (.text:SysCtl_enablePeripheral)
                  002103c4    00000020    rtsv7M4_T_le_eabi.lib : boot_cortex_m.c.obj (.text:_c_int00_noinit_noargs:_c_int00_noinit_noargs)
                  002103e4    0000001a    app_led_blinky_cm.obj (.text:GPIO_isPinValid)
                  002103fe    00000002    startup_cm.obj (.text:faultISR)

GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name

address    name
-------    ----
002103c5   _c_int00_noinit_noargs
002105db   _system_pre_init
002105df   abort

Thanks for your help,

Luke

  • Hi Luke,

    The subject matter expert is out of office due to holiday break until end of year. Please expect response by end of first week of January.

  • t seems that this problem is due to ARM Thumb mode, am I correct?

    Yes, for a Cortex-M which only supports ARM Thumb mode the least significant bit in the address of a branch must be set to set Thumb mode.

    The boot code fails to branch to app code if software branch to .resetisr, and it works well if branch to entry point directly.

    How is the boot code branching to .resetisr?

    And how does the boot code get the address of the .resetisr? Eg. does the boot code have a fixed address for the .resetisr.

    TMS320F28388D: In a CM bootloader, how to branch to a RAM entry-point? of how a boot loader can branch to a fixed entry address.

  • Chester,

    We create one .cmd file for app code and configure the address of .resetisr to 0x210000.

    MEMORY
    {
         /* Flash sectors */
         CMBANK0_RESETISR : origin = 0x00210000, length = 0x00000008 /* Boot to Flash Entry Point */

    In boot code, we use below C statement branch to the app code .resetisr. It fails to work if we branch to 0x210000 and it will work well if branching to 0x2103C5 directly.

    ((void(*)())((uint32_t *)0x210000))();

    It seems that CM4 gets wrong  _c_int00_noinit_noargs address due to Thumb mode if branch to .resetisr, please advise how to fix this problem if any idea, thanks for your help.

    Regards,

    Luke

  • In boot code, we use below C statement branch to the app code .resetisr.

    Try changing the C statement to the following:

    ((void(*)())((uint32_t *)0x210001))();

    That branches to an address with the least significant bit set which indicates Thumb mode.

  • Chester,

    You are right, branch to address 0x210001 fix this problem.

    In .resetisr, there is actually an assembly branch command, branch program counter to function _c_int00_noinit_noargs(). Do you mean when I branch to an address with the least significant bit set, CM4 will understand this is Thumb mode and branch to address 0x2103c5(not 0x2103c4)?

    Regards,

    Luke

  • Do you mean when I branch to an address with the least significant bit set, CM4 will understand this is Thumb mode

    Yes. See also Pointers to functions in Thumb state in the ARM documentation.

    and branch to address 0x2103c5(not 0x2103c4)

    Found ARM Cortex M0/M3/M4:Why PC is always Even number in Thumb State on StackOverflow explains that the PC always reads back with the least significant bit clear, but when you write to PC that the least significant bit is loaded into the EPSR T-bit. Where it is the EPSR T-bit which indicates if the processor is in ARM or Thumb mode.

    This allows other ARM processors such as Cortex-A to support inter-working where can mix calling functions written in ARM or Thumb mode. Whereas a Cortex-M only supports Thumb mode so the EPSR T-bit must always be set, since attempting to execute instructions when the T bit is 0 results in a fault or lockup.

  • Chester,

    For Thumb mode, I understand the least significant bit should be set for function pointers, but I didn't realize I should set LSB of address for branch command.

    Thanks for all the details.

    -Luke