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.

interrupt jumps to the wrong location

Genius 5910 points

It is probably something stupid.

IER    <16-bit unsigned>    0x2000    Register IER    
IFR    <16-bit unsigned>    0x2000    Register IFR    
SystemTimer    void (*)()    0x009AFF    
(*((*(halHandle)).pieHandle)).INT14    void (*)()    0x00009AFF    0x00000D1C@Data    

After the following instruction:

 asm(" clrc INTM");

IER    <16-bit unsigned>    0x0000    Register IER    
IFR    <16-bit unsigned>    0x0000    Register IFR    
 I end up  at memory location: "0x3ff599"   and not at 0x009AFF

So what I'm I missing?

edit:

 I can reduce the problem to this:

 IER    = 0x2000

 asm(" clrc INTM");

other  interrupt (IER = 0x020) ends up at the address.

edit2:

 It seems it is in the memory range of the bootrom. How is that possible?

  • Usually you end up in the boot ROM when there's an illegal instruction (ITRAP). This can happen when the CPU tries to execute from the wrong address.

    Are you sure there's valid code at address 0x9AFF? Have you tried putting a breakpoint there? Also, what part number is this?

    Thanks,
  • It is the 28035.
    See the address of the function SystemTimer in the initial post.
    Yes, I placed a breakpoint at the beginning of SystemTimer function. He is not getting there.

    The only thing I can think of is that the CPU is looking at an other interrupt table then I provided. I don't know why.

    Edit: It happens when I compile with option Release it works corrects when I compile for DEBUG. Suggestions?

    This is the line of code that cause the problem:

    #pragma CODE_SECTION(SystemTimer,"ramfuncs");

    So I guess the interrupt controller jumps to the  flash location and not to the mem location. How and why?  Please tell me how to solve this.

  • You need to copy any RAM functions you have from flash to RAM. You can do this using the memcpy() function. The addresses come from the LOAD and RUN statements in your linker command file.

  • I did that, see below:

    #ifdef FLASH
    // Used for running BackGround in flash, and ISR in RAM
    extern volatile uint16_t *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart;
    #endif

    #ifdef FLASH
        // Copy time critical code and Flash setup code to RAM
        // The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
        // symbols are created by the linker. Refer to the linker files.
        memCopy((uint16_t *) &RamfuncsLoadStart, (uint16_t *) &RamfuncsLoadEnd,
                (uint16_t *) &RamfuncsRunStart);
    #endif

    And in the cmd file:

    RAML3      : origin = 0x009AFF, length = 0x005FF     /* on-chip RAM block L3 */

    FLASHDATA  : origin = 0x3F5FF6, length = 0x002000     /* on-chip FLASH */

       ramfuncs            : LOAD = FLASHDATA,
                             RUN = RAML3,
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_END(_RamfuncsLoadEnd),
                             RUN_START(_RamfuncsRunStart),
                             PAGE = 0

    More suggestions?

  • This is my complete CMD file:

    _Cla1Prog_Start = _Cla1funcsRunStart;
    CLA_SCRATCHPAD_SIZE = 0x200;
    --undef_sym=__cla_scratchpad_end
    --undef_sym=__cla_scratchpad_start

    MEMORY
    {
    PAGE 0 :
    /* BEGIN is used for the "boot to SARAM" bootloader mode */
    RAML3 : origin = 0x009AFF, length = 0x005FF /* on-chip RAM block L3 */
    BEGIN : origin = 0x3F7FF6, length = 0x000002 /* Part of FLASHA. Used for "boot to Flash" bootloader mode. */
    CLAPROG : origin = 0x009000, length = 0x00AFF /* on-chip RAM block L3 */
    FLASHDATA : origin = 0x3F5FF6, length = 0x002000 /* on-chip FLASH */
    FLASHCODE : origin = 0x3E8000, length = 0x00DFF6 /* on-chip FLASH */

    RESET : origin = 0x3FFFC0, length = 0x000002
    IQTABLES : origin = 0x3FE000, length = 0x000B50 /* IQ Math Tables in Boot ROM */
    IQTABLES2 : origin = 0x3FEB50, length = 0x00008C /* IQ Math Tables in Boot ROM */
    IQTABLES3 : origin = 0x3FEBDC, length = 0x0000AA /* IQ Math Tables in Boot ROM */

    BOOTROM : origin = 0x3FF27C, length = 0x000D44


    PAGE 1 :
    RAML0L1 : origin = 0x008000, length = 0x000A00
    // RAML0L1 : origin = 0x008000, length = 0x000C00
    RAMM0 : origin = 0x000050, length = 0x0007B0
    BOOT_RSVD : origin = 0x000002, length = 0x00004E /* Part of M0, BOOT rom will use this for stack */
    // RAMM1 : origin = 0x000480, length = 0x000380 /* on-chip RAM block M1 */
    // RAML2 : origin = 0x008C00, length = 0x000400
    //RAML3 : origin = 0x009000, length = 0x001000
    CLARAM0 : origin = 0x008A00, length = 0x000600
    CLAFLASHTABLES : origin = 0x3F5F80, length = 0x002000
    CLA1_MSGRAMLOW : origin = 0x001480, length = 0x000080
    CLA1_MSGRAMHIGH : origin = 0x001500, length = 0x000080

    }


    SECTIONS
    {
    /* Setup for "boot to SARAM" mode:
    The codestart section (found in DSP28_CodeStartBranch.asm)
    re-directs execution to the start of user code. */
    codestart : > BEGIN, PAGE = 0

    #ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
    .TI.ramfunc : {} > RAML3, PAGE = 0
    #endif
    #endif

    .text : > FLASHCODE, PAGE = 0
    .cinit : > FLASHCODE, PAGE = 0
    .pinit : > FLASHCODE, PAGE = 0
    //.cio : > FLASHCODE, PAGE = 0
    .switch : > FLASHCODE, PAGE = 0
    .reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */

    ramfuncs : LOAD = FLASHDATA,
    RUN = RAML3,
    LOAD_START(_RamfuncsLoadStart),
    LOAD_END(_RamfuncsLoadEnd),
    RUN_START(_RamfuncsRunStart),
    PAGE = 0


    .stack : > RAMM0, PAGE = 1
    .ebss : > RAML0L1, PAGE = 1
    .esysmem : > RAML0L1, PAGE = 1
    .bss_cla : > CLARAM0, PAGE = 1
    // .const_cla : > CLARAM0, PAGE = 1 // fixme incorrect!!

    .econst : > FLASHDATA, PAGE = 0
    //.econst : > RAML0L1, PAGE = 1
    .esysmem : > RAML0L1, PAGE = 1

    IQmath : > FLASHDATA, PAGE = 0
    IQmathTables : > IQTABLES, PAGE = 0, TYPE = NOLOAD

    Cla1Prog : LOAD = FLASHDATA,
    RUN = CLAPROG,
    LOAD_START(_Cla1funcsLoadStart),
    LOAD_END(_Cla1funcsLoadEnd),
    LOAD_SIZE(_Cla1funcsLoadSize),
    RUN_START(_Cla1funcsRunStart),
    PAGE = 0

    Cla1ToCpuMsgRAM : > CLA1_MSGRAMLOW, PAGE = 1
    CpuToCla1MsgRAM : > CLA1_MSGRAMHIGH, PAGE = 1

    Cla1DataRam0 : > CLARAM0, PAGE = 1
    Cla1DataRam1 : > CLARAM0, PAGE = 1

    CLAscratch :
    { *.obj(CLAscratch)
    . += CLA_SCRATCHPAD_SIZE;
    *.obj(CLAscratch_end)
    *<*.obj>(CLAscratch_end)
    } > CLARAM0,
    PAGE = 1

    /* Note for running from RAM the load and RUN can be the same */

    CLA1mathTables : LOAD = CLAFLASHTABLES,
    RUN = CLARAM0,
    LOAD_START(_Cla1mathTablesLoadStart),
    LOAD_END(_Cla1mathTablesLoadEnd),
    RUN_START(_Cla1mathTablesRunStart),
    PAGE = 1
  • If you're using the CLA, you can't share RAML3 with the CPU. Configuring RAML3 to be CLA program memory blocks normal accesses from the C28x CPU. This is determined by the PROGE bit in the MMEMCFG register. There's more information in the CLA user guide (literature number SPRUGE6). You'll need to make space for your RAM functions in L0 or L1.
  • OK.
    I changed it to this:
    SystemTimer void (*)() 0x008700
    (*((*(halHandle)).pieHandle)).INT14 void (*)() 0x00008700 0x00000D1C@Data

    Disassambly:
    RamfuncsRunStart, SystemTimer():
    008700: 761B ASP
    008701: 0005 PUSH AR1H:AR0H // Breakpoint
    008702: ABBD MOVL *SP++, XT
    008703: AABD MOVL *SP++, XAR2
    008704: A2BD MOVL *SP++, XAR3
    008705: A8BD MOVL *SP++, XAR4
    008706: A0BD MOVL *SP++, XAR5
    008707: C2BD MOVL *SP++, XAR6
    008708: C3BD MOVL *SP++, XAR7
    008709: FE04 ADDB SP, #4
    00870a: FF69 SPM #0
    00870b: 2942 CLRC OVM|PAGE0
    00870c: 5616 CLRC AMODE
    00870d: 761F020D MOVW DP, #0x20d

    Only the result is the same:
    No source available for "0x3ff599"

    Edit:

      is a bit different:

     This works:

    #ifdef FLASH
    #pragma CODE_SECTION(SystemTimer,"ramfuncs");
    //#pragma CODE_SECTION(SPI_Slave,"ramfuncs");
    #endif

    This also works:

    #ifdef FLASH
    //#pragma CODE_SECTION(SystemTimer,"ramfuncs");
    #pragma CODE_SECTION(SPI_Slave,"ramfuncs");
    #endif

    But this doesn't:

    #ifdef FLASH
    #pragma CODE_SECTION(SystemTimer,"ramfuncs");
    #pragma CODE_SECTION(SPI_Slave,"ramfuncs");

    #endif

    (*((*(halHandle)).pieHandle)).SPIRXINTB    void (*)()    0x000087CF    0x00000D94@Data    
    SPI_Slave    void (*)()    0x0087CF    
    (*((*(halHandle)).pieHandle)).INT14    void (*)()    0x00008700    0x00000D1C@Data    
    SystemTimer    void (*)()    0x008700    

    How strange. Interrupt in interrupt issue?

  • That is strange. Can you see any difference at the end of the SystemTimer function for the various #pragma combinations?

    Also, can you post the C code for your timer interrupt handler?

    Thanks,