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.

ESM error as FIQ interrupt occurs.

(TMS570 LC43, CCS 5.5, FreeRtos)

Hello,

As soon as I enter a FIQ interrupt, I have a ESM error. This is not the case if I configure the same interrupt in IRQ. I don't see any other ESM error for the rest of the code.

I have configured my linker with 8 bits padding and filling 0xfff...

--heap_size=0x0100
--retain="*(.intvects)"


MEMORY
{
    BOOTLOADER (RX)       : origin = 0x00000000 length = 0x00080000

    VECTORS (X)           : origin = 0x00080000 length = 0x00000040 vfill=0xFFFFFFFF
    CODECRC (R)           : origin = 0x00080040 length = 0x00000004 vfill=0xFFFFFFFF
    CODELENGTH (R)        : origin = 0x00080044 length = 0x00000004 vfill=0xFFFFFFFF
    APPLCAN1_SPD (R)      : origin = 0x00080048 length = 0x00000004 vfill=0xFFFFFFFF
    APPLCAN1_CRC (R)      : origin = 0x0008004C length = 0x00000004 vfill=0xFFFFFFFF
    APPLCAN2_SPD (R)      : origin = 0x00080050 length = 0x00000004 vfill=0xFFFFFFFF
    APPLCAN2_CRC (R)      : origin = 0x00080054 length = 0x00000004 vfill=0xFFFFFFFF
    CODE2ADDR (R)         : origin = 0x00080058 length = 0x00000004 vfill=0xFFFFFFFF
    CODE2LENGTH (R)       : origin = 0x0008005C length = 0x00000004 vfill=0xFFFFFFFF
    FLASHMO (RX)          : origin = 0x00080060 length = 0x0037FFA0 vfill=0xFFFFFFFF    

    RAM_DATA_EXCHANGE_ID  : origin = 0x08000000 length = 0x00000010   /* New meory map unique ID */
    RAM_BOOT_VER (R)      : origin = 0x08000010 length = 0x00000010
    RAM_CAN1_ADR (R)      : origin = 0x08000020 length = 0x00000004
    RAM_CAN2_ADR (R)      : origin = 0x08000024 length = 0x00000004
    RAM_CAN_SPD (R)       : origin = 0x08000030 length = 0x00000004
    RAM_CANPORT_USED (R)  : origin = 0x08000034 length = 0x00000004
    RAM_UDS_RX_ADDR (R)   : origin = 0x08000038 length = 0x00000004
    RAM_UDS_TX_ADDR (R)   : origin = 0x0800003C length = 0x00000004
    RAM_UDS_BOOT_MODE (RW): origin = 0x08000040 length = 0x00000004
    RAM_FREE (R)          : origin = 0x08000044 length = 0x000000BC    

    STACKS (RW)           : origin = 0x08000100 length = 0x00002000
    RAM_NOINIT (RW)       : origin = 0x08002100 length = 0x00000100
    IRAM (RW)             : origin = 0x08002200 length = 0x0007DE00    
}

SECTIONS
{
   .intvecs       : {} palign=8 > VECTORS
   .text          : {} palign=8 > FLASHMO
   .const         : {} palign=8 > FLASHMO
   .cinit         : {} palign=8 > FLASHMO
   .pinit         : {} palign=8 > FLASHMO
   .init_array    : {} palign=8 LOAD = FLASHMO,
                       RUN_START(__TI_INIT_ARRAY_Base),
                       RUN_END( __TI_INIT_ARRAY_Limit)

   .bss           : {} > IRAM
   .data          : {} > IRAM
   .sysmem        : {} > IRAM
   .stack         : {} > STACKS,
                         RUN_START(__STACK_BASE),
                         RUN_END( __STACK_END)


   codecrc        : {} > CODECRC
   codelength     : {} > CODELENGTH
   applcan1_crc   : {} > APPLCAN1_CRC
   applcan1_spd   : {} > APPLCAN1_SPD
   applcan2_crc   : {} > APPLCAN2_CRC
   applcan2_spd   : {} > APPLCAN2_SPD
   bootversion    : {} > RAM_BOOT_VER,      type=NOINIT
   can1address    : {} > RAM_CAN1_ADR,      type=NOINIT
   can2address    : {} > RAM_CAN2_ADR,      type=NOINIT
   udsbootmode    : {} > RAM_UDS_BOOT_MODE, type=NOINIT
   ramNoInit      : {} > RAM_NOINIT,    type=NOINIT

   ramfuncs : {
              }
              LOAD =  FLASHMO,
              RUN = IRAM,
              LOAD_START(_RamfuncsLoadStart),
              LOAD_END(_RamfuncsLoadEnd),
              RUN_START(_RamfuncsRunStart)



}

Simon

  • Thanks Simon,
    What is the ESM Error that you are seeing? [which group/channel?]
  • A general core error I think (0xF51C addr is 0x0008), this is a snap shot on JTAG debugging session showing ESM register address data:

  • Hi Simon,

    Are you seeing this ESM error set when you reach the vector for FIQ (0x1C) or is it later after branching to your handler?

    Then CP15 has some registers for Data Fault Status, Data Fault Address, Instruction Fault Status, Instruction Fault Address.
    and Auxiliary Data Fault Status, and Auxiliary Instruction Fault Status. These can be viewed in the CCS register view under CP15.

    Good chance you'd see these set indicating what the fault is and it's address because I think that the ESM channel in question means the error was detected by the CPU and reported to the ESM.

    If it's an error in the cache then maybe you need to do some cache cleaning operation. Might be caused by having the relocation (load address & run address in RAM)..

    -Anthony
  • I see this ESM error set as soon as I reach the vector for FIQ (0x1C), at the very beginning.

    I have code in RAM yes, the very code that run within this FIQ interrupt.

    Simon

  • Simon lapointe said:
    I have code in RAM yes, the very code that run within this FIQ interrupt.

    As Anthony has already mentioned, on Hercules devices with cache you need to clean the cache after copying a function from flash to RAM, before attempting to execute the function in RAM, to ensure the instruction cache is loaded with the contents of the function.

    In the thread Run code in RAM on flash based device there is an example project for how to do that.

    As mentioned in the referenced thread you also need to change the MPU settings to allow code execution from RAM.

  • Does it mean that I shouldn't have any related fault if the code is in flash ?

    In fact I've just tested and no, there is still ESM fault even with no code in RAM.

    Simon

  • I've get some CP15 register data as the ESM FIQ interrupt error in called, this is what I see: (refer to image)

    Since I have no code in RAM, I guess it's not relevant anymore to clean the cache or something. Do you have a hint ?

  • Sorry to send you a lot of information without waiting your response (I'm in a kind of rush now to make this thing work, as many others I guess !)

    Let-me describe my code related to interrupt. Because even in the case of having no fault in ESM (I have another project running on TMS LS3 without ESM fault of corse), the performance of my FIQ interrupt is poor and since the frequency is high, it's a problem for me. I have add some extra assembly code to deal with nested interrupt and I suspect this code the reason of the poor performance. I guess I don't really need to be nested of FIQ cause it is the only interrupt in FIQ, but the problem it is that it doen't work otherwise. Do you have other suggestion that could fix the ESM problem and enhance the performance ?

    NESTED_INTERRUPT_ENTRY_FIQ (OnNhetInterruptDirect)

    {

       CallApplStuff(); //application code.

    }

    NESTED_INTERRUPT_EXIT_FIQ (OnNhetInterruptDirect)

    where

    #define NESTED_INTERRUPT_ENTRY_IRQ( fn ) \

    _Pragma ("FUNC_CANNOT_INLINE") \

    static void internalIrq##fn (void)

    #define NESTED_INTERRUPT_EXIT_IRQ( fn ) \

    _Pragma ("CODE_STATE(32)") \

    void fn (void) \

    { \

    { \

    asm( " ADD SP, SP, #8 " ); \

    asm( " SUB LR, LR, #4 " ); \

    asm( " SRSFD #0x12 ! " ); \

    asm( " CPS #0x13 " ); \

    asm( " PUSH {R0-R12} " ); \

    asm( " FMRX R5,FPEXC " ); \

    asm( " PUSH {R5} " ); \

    asm( " FMRX R5,FPSCR " ); \

    asm( " PUSH {R5} " ); \

    asm( " FSTMDBD SP!, {D0-D7} " ); \

    asm( " MOV R1, SP " ); \

    asm( " AND R1, R1, #4 " ); \

    asm( " SUB SP, SP, R1 " ); \

    asm( " PUSH {R1, R14} " ); \

    } \

    internalIrq##fn(); \

    { \

    asm( " POP {R1, LR} " ); \

    asm( " ADD SP, SP, r1 " ); \

    asm( " FLDMIAD SP!, {D0-D7} " ); \

    asm( " POP {R5} " ); \

    asm( " FMXR FPSCR, R5 " ); \

    asm( " POP {R5} " ); \

    asm( " FMXR FPEXC, R5 " ); \

    asm( " POP {R0-R12} " ); \

    asm( " CPS #0x12 " ); \

    asm( " RFEFD SP! " ); \

    } \

    }

  • So no clue on the exception source yet. I was not expecting 0x0000's in all the fault status and address registers. And if you see these set at the exception vector itself then I'm not sure cache makes sense either.

    You definitely should not use the FIQ for anything other than the ESM though.

    It just doesn't make sense when you analyze it.. the cost is higher than using the IRQ level because so much has improved in IRQ (vectored dispatch directly to the ISR, fast context switch because CPU busses to memory are now x64) and on the flip side the cost to *not use* the vectored dispatch of IRQ and dispatch manually in FIQ has gone up (cache misses & flash pipeline effects, larger cost to access peripherals).

    So what you should really do is stick with the IRQ, and possibly adjust the IRQ priority and use nesting at the IRQ level if required.

    Is that what you are attempting? Last post seemed to indicate nesting at FIQ level...
  • I aim for performance, I tought FIQ is the best performance, that's the only reason I'd choose FIQ. So you suggest to go on IRQ and keep FIQ for the ESM interrupt ? I noticed tough that when I configure my high frequency interrupt in IRQ it crashes after a while, but I didn't investiguate very much. I'll check that.
    But I still need a fix about the ESM problem. Any suggestion on that ?
  • oh I might have missed it because your vectors are in RAM...

    you don't have a VFILL on the actual vector table in flash in the linker command file. try adding that.
  • What you mean, there is One, Line 9 in the first post ? 

  • Right that's what I saw too, but I think you need one on LINE 7 which is what actually links to address 0x000000xx.

    Line 9 links to RAM.

    You cannot actually relocate the vector table to RAM. It's always at address 0x0000000 even when you have a bootloader. all the bootloader can do is indirectly jump to the vector table in RAM.


    ----------------------
    NOTE:

    That's another reason why the FIQ is costing you so much more in this case. Because now you've got to branch from vector at 0x1C in the bootloader to vector in RAM and from there to your software dispatch.

    The VIM allows you to bypass the bootloader completely for all IRQs and go directly to your ISR because the IRQ supports vectored mode. But all the other exceptions have to route first through bootloader then to your applications' dispatcher and then to the actual handler. These extra steps plus any software dispatch really add up.

    And if you try to share FIQ the two main benefits of FIQ are also negated:
    - ability to execute the ISR directly from 0x1C .. negated if you need to dispatch
    - banked registers - negated if you are sharing between multiple handlers
    unless you are *really* hand-crafting the code.
    --
  • (by the way the last post/reply aren't there, that's strange)

    I have add vFill stuff in the application, but no change. I don't know if you want to say to add it on the application or in the boot loader.

    My bootloader seems already correct according to what we have talk about the vFill. It's another executable of course.

    So not big change sadly.

    This is the linker cmd file of the bootloader, you can see that VECTORS (X) have vfill stuff.

    --heap_size=0x0100

     

    --retain="*(.intvecs)"

     

    /*----------------------------------------------------------------------------*/

    /* Memory Map */

    MEMORY

    {

    VECTORS (X) : origin = 0x00000000 length = 0x00000040 vfill=0xFFFFFFFF

    BOOT_CRC (R) : origin = 0x00000040 length = 0x00000004 vfill=0xFFFFFFFF

    BOOT_LENGTH (R) : origin = 0x00000044 length = 0x00000004 vfill=0xFFFFFFFF

    FLASHBOOT (RX) : origin = 0x00000048 length = 0x0007FFB8 vfill=0xFFFFFFFF

    APPL_ENTRY (R) : origin = 0x00080000 length = 0x00000040

    APPL_CRC (R) : origin = 0x00080040 length = 0x00000004

    APPL_LENGTH (R) : origin = 0x00080044 length = 0x00000004

    CAN1_SPD (R) : origin = 0x00080048 length = 0x00000004

    CAN1_CRC (R) : origin = 0x0008004C length = 0x00000004

    CAN2_SPD (R) : origin = 0x00080050 length = 0x00000004

    CAN2_CRC (R) : origin = 0x00080054 length = 0x00000004

    FLASH (RX) : origin = 0x00080058 length = 0x0037FFA8

    FLASH_ECC (R) : origin = 0x00400000 length = 0x00100000

    RAM_DATA_EXCHANGE_ID : origin = 0x08000000 length = 0x00000010 /* New meory map unique ID */

    RAM_BOOT_VER (R) : origin = 0x08000010 length = 0x00000010 /* Bootloader version */

    RAM_CAN1_ADR (R) : origin = 0x08000020 length = 0x00000004 /* CAN address */

    RAM_CAN2_ADR (R) : origin = 0x08000024 length = 0x00000004 /* CAN address */

    RAM_CAN_SPD (R) : origin = 0x08000030 length = 0x00000004 /* Bootlader baudrate configuration BTC for secondary algo*/

    RAM_CANPORT_USED (R) : origin = 0x08000034 length = 0x00000004

    RAM_UDS_RX_ADDR (R) : origin = 0x08000038 length = 0x00000004

    RAM_UDS_TX_ADDR (R) : origin = 0x0800003C length = 0x00000004

    RAM_UDS_BOOT_MODE (RW): origin = 0x08000040 length = 0x00000004

    RAM_FREE (R) : origin = 0x08000044 length = 0x000000BC

    STACKS (RW) : origin = 0x08000100 length = 0x00002000

    RAM_VECTORS (RX) : origin = 0x08002100 length = 0x00000040

    RAM_ALGO_TYPE (R) : origin = 0x08002140 length = 0x00000004

    RAM_ALGO (RX) : origin = 0x08002144 length = 0x0001DEBC

    RAM_NOINIT (RW) : origin = 0x08020000 length = 0x00000100

    RAM_UNUSED_GAP (R) : origin = 0x08020100 length = 0x00000100 /* It is important to leave an unused gap between secondary algo and bootloader RAM

    because of the encription that will write up to 228 bytes after the last

    section of the program */

    RAM (RW) : origin = 0x08020200 length = 0x0005FE00

    }

    SECTIONS

    {

    .intvecs : {} palign=8 > VECTORS

    .text : {} palign=8 > FLASHBOOT

    .const : {} palign=8 > FLASHBOOT

    .cinit : {} palign=8 > FLASHBOOT

    .pinit : {} palign=8 > FLASHBOOT

    .init_array : {} palign=8 LOAD = FLASHBOOT,

    LOAD_START(__TI_INIT_ARRAY_Base),

    LOAD_END(__TI_INIT_ARRAY_Limit)

    .bss : {} > RAM

    .data : {} > RAM

    .sysmem : {} > RAM

    .stack : {} > STACKS

    codecrc : {} > BOOT_CRC, type = DSECT

    codelength : {} > BOOT_LENGTH, type = DSECT

    applEntry : {} > APPL_ENTRY, type = NOLOAD

    applCrc : {} > APPL_CRC, type = NOLOAD

    applLength : {} > APPL_LENGTH, type = NOLOAD

    can1_spd : {} > CAN1_SPD, type = NOLOAD

    can1_crc : {} > CAN1_CRC, type = NOLOAD

    can2_spd : {} > CAN2_SPD, type = NOLOAD

    can2_crc : {} > CAN2_CRC, type = NOLOAD

    ramDataExchangeId : {} > RAM_DATA_EXCHANGE_ID, type = NOLOAD

    bootVersion : {} > RAM_BOOT_VER, type = NOLOAD

    can1Address : {} > RAM_CAN1_ADR

    can2Address : {} > RAM_CAN2_ADR

    canSpeed : {} > RAM_CAN_SPD

    canPortUsed : {} > RAM_CANPORT_USED, type = NOLOAD

    udsrxAddress : {} > RAM_UDS_RX_ADDR, type = NOLOAD

    udstxAddress : {} > RAM_UDS_TX_ADDR, type = NOLOAD

    udsbootmode : {} > RAM_UDS_BOOT_MODE, type = NOLOAD, type = NOINIT

    algostart : {} > RAM_VECTORS, type = NOLOAD

    algotype : {} > RAM_ALGO_TYPE, type = NOLOAD, type = NOINIT

    ramNoInit : {} > RAM_NOINIT, type = NOLOAD, type = NOINIT

    ramfuncs : {

    }

    LOAD = FLASHBOOT,

    RUN = RAM,

    LOAD_START(_RamfuncsLoadStart),

    LOAD_END(_RamfuncsLoadEnd),

    RUN_START(_RamfuncsRunStart)

    }

     

    /*----------------------------------------------------------------------------*/

    /* Misc */

     

    /*----------------------------------------------------------------------------*/

  • Finalement, going in IRQ all the way fix the ESM problem.
  • Ok I've configured IRQ all the way and it runs OK. No ESM error using IRQ.
  • Hello Anthony,
    I'm really interrested to go in IRQ instead of FIQ (cause FIQ seems to involve more challenge about the ESM). I've read this application note: Application Report
    SPNA219–April 2015: Nested Interrupts on Hercules...
    It seems to me at first glance that this solution involves a lot of overhead in the ISR Handler and complexity also. But one interesting thing is that some ISR could be set as not interruptible and involve less overhead at the same time.
    I just want to describe my requirements to you: I only have 2 interrupts, one high frequency and also high priority. The other one is the FreeRtos tick (IRQ RTI compare0). So the high frequency shall be not interruptible.
    I've check the FreeRtos tick Handler, I'm not sure it will be compatible with the appl note proposed solution. Do you have an idea if the proposed solution could suite my requirements and how big the overhead compare to FIQ solution ?