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.

CCS/TMS320F280049C: Unable to copy interrupt vector table correctly

Part Number: TMS320F280049C
Other Parts Discussed in Thread: TMS320F28035

Tool/software: Code Composer Studio

Dear Sir,

I have tested your example code "adc_ex1_soc_epwm" with TMS320F280049C, and it is no problem (after compiler, the address of PieVectTableInit is 0x00A800).

I have made same code for TMS320F28035, and it is no problem.

And I re-used same code with TMS320F280049C but it couldn't copy interrupt vector table correctly (after compiler, the address of PieVectTableInit is 0x088F02).
It always copy a strange number into the destination.

I have modified my code in the following three situations.
1. Same as your example - Failed
2. Create a local variable for indirect copying - Failed
3. Create a global variable for indirect copying - Passed

Your example code "adc_ex1_soc_epwm":
C code -
void
InitPieVectTable(void)
{
    Uint16  i;
    Uint32  *Source  =  (void  *)  &PieVectTableInit;
    Uint32  *Dest  =  (void  *)  &PieVectTable;

    //
    // Do not write over first 3 32-bit locations (these locations are
    // initialized by Boot ROM with boot variables)
    //
    Source  =  Source  +  3;
    Dest  =  Dest  +  3;

    EALLOW;

    for(i  =  0;  i  <  221;  i++)
    {
        *Dest++  =  *Source++;
    }

    EDIS;

    //
    // Enable the PIE Vector Table
    //
    PieCtrlRegs.PIECTRL.bit.ENPIE  =  1;
}

Assembly code -
285     {
        InitPieVectTable():
0003db:   FE06        ADDB         SP, #6
287         Uint32  *Source  =  (void  *)  &PieVectTableInit;
0003dc:   8F00A800    MOVL         XAR4, #0x00a800
0003de:   A842        MOVL         *-SP[2], XAR4
288         Uint32  *Dest  =  (void  *)  &PieVectTable;
0003df:   8F000D00    MOVL         XAR4, #0x000d00
0003e1:   A844        MOVL         *-SP[4], XAR4
294         Source  =  Source  +  3;
0003e2:   0206        MOVB         ACC, #6
0003e3:   0742        ADDL         ACC, *-SP[2]
0003e4:   1E42        MOVL         *-SP[2], ACC
295         Dest  =  Dest  +  3;
0003e5:   0206        MOVB         ACC, #6
0003e6:   0744        ADDL         ACC, *-SP[4]
0003e7:   1E44        MOVL         *-SP[4], ACC
297         EALLOW;
0003e8:   7622        EALLOW      
299         for(i  =  0;  i  <  221;  i++)
0003e9:   2B45        MOV          *-SP[5], #0
0003ea:   9245        MOV          AL, *-SP[5]
0003eb:   52DD        CMPB         AL, #0xdd
0003ec:   670D        SB           C$L2, HIS
301             *Dest++  =  *Source++;
        C$L1:
0003ed:   8344        MOVL         XAR5, *-SP[4]
0003ee:   8A42        MOVL         XAR4, *-SP[2]
0003ef:   A0A9        MOVL         @ACC, XAR5
0003f0:   C484        MOVL         XAR6, *XAR4++
0003f1:   0902        ADDB         ACC, #2
0003f2:   A842        MOVL         *-SP[2], XAR4
0003f3:   1E44        MOVL         *-SP[4], ACC
0003f4:   C2C5        MOVL         *+XAR5[0], XAR6
299         for(i  =  0;  i  <  221;  i++)
0003f5:   0A45        INC          *-SP[5]
0003f6:   9245        MOV          AL, *-SP[5]
0003f7:   52DD        CMPB         AL, #0xdd
0003f8:   68F5        SB           C$L1, LO
304         EDIS;
        C$L2:
0003f9:   761A        EDIS        
309         PieCtrlRegs.PIECTRL.bit.ENPIE  =  1;
0003fa:   761F0033    MOVW         DP, #0x33
0003fc:   1A200001    OR           @0x20, #0x0001
310     }
0003fe:   FE86        SUBB         SP, #6
0003ff:   0006        LRETR       

My code in situation 1:
C code -
void PIEVECT_init()
{
    int16 i;
    Uint32 *pSource = (void *) &PieVectTableInit;
    Uint32 *pDest = (void *) &(PIE_VECT->PIE1_RESERVED_INT);    // get address of table

    // Do not write over first 3 32-bit locations (these locations are
    // initialized by Boot ROM with boot variables)
    pSource  =  pSource  +  3;
    pDest  =  pDest  +  3;

    EALLOW();
    for(i=0; i < 221; i++){
        *pDest++ = *pSource++;
    }
    EDIS();

    // Enable the PIE Vector Table
    PIE->PIECTRL.bit.ENPIE = 1;
}

Assembly code -
  21     pSource  =  pSource  +  3;
        PIEVECT_init():
08834e:   8F488F08    MOVL         XAR5, #0x088f08
088350:   7622        EALLOW      
  22     pDest  =  pDest  +  3;
088351:   8F000D06    MOVL         XAR4, #0x000d06
088353:   BEDC        MOVB         XAR6, #0xdc
  26            *pDest++ = *pSource++;
        C$L42:
088354:   0685        MOVL         ACC, *XAR5++
088355:   1E84        MOVL         *XAR4++, ACC
  25     for(i=0; i < 221; i++){
088356:   000EFFFE    BANZ         65534,AR6--
088358:   761A        EDIS        
  31     PIE->PIECTRL.bit.ENPIE = 1;
088359:   F5A90CE0    MOV          @AL, *(0:0x0ce0)
08835b:   FF69        SPM          #0
08835c:   5001        ORB          AL, #0x1
08835d:   F4A90CE0    MOV          *(0:0x0ce0), @AL
08835f:   0006        LRETR       

My code in situation 2:
C code -
void PIEVECT_init()
{
 int16 i;
 Uint32 *pSource = (void *) &PieVectTableInit;
 //Uint32 *Dest = (void *) &PieVectTable;
 Uint32 *pDest = (void *) &(PIE_VECT->PIE1_RESERVED_INT);    // get address of table
 Uint32 tempBuf;

    // Do not write over first 3 32-bit locations (these locations are
    // initialized by Boot ROM with boot variables)
 pSource  =  pSource  +  3;
 pDest  =  pDest  +  3;

    EALLOW();
 for(i=0; i < 221; i++){
     tempBuf = *pSource;
     *pDest = tempBuf;
     pSource++;
     pDest++;
 }
 EDIS();

 // Enable the PIE Vector Table
 PIE->PIECTRL.bit.ENPIE = 1;
}

Assembly code -
22     pSource  =  pSource  +  3;
        PIEVECT_init():
08834e:   8F488F08    MOVL         XAR5, #0x088f08
088350:   7622        EALLOW      
  23     pDest  =  pDest  +  3;
088351:   8F000D06    MOVL         XAR4, #0x000d06
088353:   BEDC        MOVB         XAR6, #0xdc
  28         *pDest = tempBuf;
        C$L42:
088354:   0685        MOVL         ACC, *XAR5++
088355:   1E84        MOVL         *XAR4++, ACC
  26     for(i=0; i < 221; i++){
088356:   000EFFFE    BANZ         65534,AR6--
088358:   761A        EDIS        
  35     PIE->PIECTRL.bit.ENPIE = 1;
088359:   F5A90CE0    MOV          @AL, *(0:0x0ce0)
08835b:   FF69        SPM          #0
08835c:   5001        ORB          AL, #0x1
08835d:   F4A90CE0    MOV          *(0:0x0ce0), @AL
08835f:   0006        LRETR       

My code in situation 3:
C code -
Uint32 tempBuf;
void PIEVECT_init()
{
    int16 i;
    Uint32 *pSource = (void *) &PieVectTableInit;
    Uint32 *pDest = (void *) &(PIE_VECT->PIE1_RESERVED_INT);    // get address of table

    // Do not write over first 3 32-bit locations (these locations are
    // initialized by Boot ROM with boot variables)
    pSource  =  pSource  +  3;
    pDest  =  pDest  +  3;

    EALLOW();
    for(i=0; i < 221; i++){
 tempBuf = *pSource;
 *pDest = tempBuf;
 pSource++;
 pDest++;
    }
    EDIS();

    // Enable the PIE Vector Table
    PIE->PIECTRL.bit.ENPIE = 1;
}

Assembly code -
  22     pSource  =  pSource  +  3;
        PIEVECT_init():
088330:   8F488F0C    MOVL         XAR5, #0x088f0c
088332:   7622        EALLOW      
  23     pDest  =  pDest  +  3;
088333:   8F000D06    MOVL         XAR4, #0x000d06
088335:   BEDC        MOVB         XAR6, #0xdc
  27         tempBuf = *pSource;
        C$L42:
088336:   0685        MOVL         ACC, *XAR5++
088337:   761F0296    MOVW         DP, #0x296
  28         *pDest = tempBuf;
088339:   1E84        MOVL         *XAR4++, ACC
  27         tempBuf = *pSource;
08833a:   1E32        MOVL         @0x32, ACC
  26     for(i=0; i < 221; i++){
08833b:   000EFFFB    BANZ         65531,AR6--
08833d:   761A        EDIS        
  35     PIE->PIECTRL.bit.ENPIE = 1;
08833e:   F5A90CE0    MOV          @AL, *(0:0x0ce0)
088340:   FF69        SPM          #0
088341:   5001        ORB          AL, #0x1
088342:   F4A90CE0    MOV          *(0:0x0ce0), @AL
088344:   0006        LRETR       

Best Regards,
Johnson

  • Johnson,
    For most/all example projects there are two build configurations(right click on the project and you will see this 3/4 of the way down).
    1)SARAM, loads and executes the project from RAM only
    2)Flash, loads into the Flash and executes from both RAM and Flash depending on the example size.

    For your "non-working" examples the PIE ISRs are still in Flash, if the code is failing it is most likely expecting them to be copied into the RAM locations you mention, but they are not. There is an extra step in most of the examples when built for Flash and that is a copy function that is a compile time option based on the config.

    You have two options:
    1)Look at our examples and find the copy function and add that to your code
    2)Modify the linker file(.cmd) to load AND run from flash(I suspect in the cmd file you are using you will see a LOAD and a different RUN address).

    You can also observe that when you change the build config the project will include/exclude the correct .cmd for that build.

    ISRs are almost always run from RAM in control type applications in order to have the shortest execution time(RAM on C28x devices is always faster than Flash in terms of access time). If this isn't a concern for you right now, then it is fine to load and run from flash, up to you.

    Best,
    Matthew
  • Hi Matthew,

    Please refer to the assembly code for more details.

    I used the same code with TMS320F28035, it is no problem.

    But I am using the same code in TMS320F280049C, and it is failed.

    Then I keep same "cmd" file and modify the code to use a global variables as below.

    And it can work properly no problem.

    Original code:

    *pDest++ = *pSource++;

    Modified code:

    createed a global variable:

    Uint32 tempBuf;

    tempBuf = *pSource;

    *pDest = tempBuf;

    pSource ++;

    pDest ++;

    Based on above test result, I think "cmd" file is no problem.

    Yes, I always put isr function in RAM.

    Normaly, the code will initial the interrupt vector table then assign an interrupt function to desired interrupt vector. Please refer to your example code.

    But my problem is occurred in "initial interrupt vector table".

    Best Regards,

    Johnson

  • Johnson,
    Sorry for my confusion, I realize now that you are talking about the vectors themselves.

    Can you elaborate on what you mean by failing? Is the device getting hung up when you service an ISR, or something else?

    Looking at both the TI example and your example, the vectors ultimately get copied to the PIE vector RAM at 0xD00. It is just where these vectors are stored on program load initially that is different.

    Can you confirm in your example 3 what is at locations 0x088f0c after program load? Even if it is incorrect, does that table match what gets copied to 0xD00 after you run the failing examples?

    The TI example is only different because it is likely built for SARAM only, and as such the vector table is initially in RAM. I believe if you built the adc_soc example in the flash config you will see the Init table in Flash.

    The linker is placing PieVectTable @0x0D00 as defined in the F28004x_headers_nonbios.cmd linker file

    The linker is placing PieVectTableInit in section .econst, which for our examples is either RAMLS5(based address 0xA800) or FLASH_BANK0_SEC4, which is 0x084000. This is defined in 28004x_generic_flash(or ram)_lnk.cmd

    From your code examples the linker is placing the init table in FLASH_BANK0_SEC8, which may mean you have redefined the placement for your example.


    Best,
    Matthew
  • Hi Matthew,

    The address are no problem, and these are made by CCS compiler.


    I found the problem and it made by CCS compiler due to different data page.


    Please refer to my posted code again, and I list my analysis below for your reference.


    In your example code:


    Destination and Source are located in same data page (destination is 0x000D00 and source is 0x00A800). So it is no problem.


    In my code situation-1 and situation-2:


    Destination and Source are located in different data page (destination is 0x000D00 and source is 0x088F02) but it doesn't set Data Page Pointer before data copying.

    So it doesn't work properly.


    In my code situation-3:

    Destination and Source are located in different data page (destination is 0x000D00 and source is 0x088F02), and it set Data Page Pointer before data copying.

    So it works properly.

    I believe that CCS compiler will make same error in same scenario. I cannot resolve this error after compiled one by one and every time.

    Do you have any comments to solve this compiler issue?

    Best Regards,


    Johnson

  • Hi Matthew,

    I re-checked same code with TMS320F28035 and TMS320F280049C, and we can get same assembly code by CCS compiler generated.
    TMS320F28035 works properly but TMS320F280049C fail.
    Now I doubt this problem is made by TMS320F280049C not CCS compiler.

    I list C and assembly code below for your reference.
    You can see the assembly code are same, I marked in RED.

    for TMS320F28035 (Source address 0x3EFEDA@Program, Destination address 0xD00@Data):
    C code -
    void PIEVECT_init()
    {
        int16 i;
        Uint32 *pSource = (void *) &PieVectTableInit;
        Uint32 *pDest = (void *) &(PIE_VECT->PIE1_RESERVED); // get address of table

        EALLOW();
        for(i=0; i < 128; i++)
            *pDest++ = *pSource++;
        EDIS();

        // Enable the PIE Vector Table
        PIE->PIECTRL.bit.ENPIE = 1;
    }

    Assembly code -
    PIEVECT_init():
    3ef006: 7622 EALLOW
    15 Uint32 *pSource = (void *) &PieVectTableInit;
    3ef007: 8F7EFEDA MOVL XAR5, #0x3efeda
    17 Uint32 *pDest = (void *) &(PIE_VECT->PIE1_RESERVED); // get address of table
    3ef009: 8F000D00 MOVL XAR4, #0x000d00
    3ef00b: BE7F MOVB XAR6, #0x7f
    21 *pDest++ = *pSource++;
    C$L29:
    3ef00c: 0685 MOVL ACC, *XAR5++
    3ef00d: 1E84 MOVL *XAR4++, ACC
    20 for(i=0; i < 128; i++)
    3ef00e: 000EFFFE BANZ 65534,AR6--
    3ef010: 761A EDIS
    25 PIE->PIECTRL.bit.ENPIE = 1;
    3ef011: F5A90CE0 MOV @AL, *(0:0x0ce0)
    3ef013: FF69 SPM #0
    3ef014: 5001 ORB AL, #0x1
    3ef015: F4A90CE0 MOV *(0:0x0ce0), @AL
    3ef017: 0006 LRETR

    for TMS320F280049C (Source address 0x88F08@Program, Destination address 0xD06@Data):
    C code -
    void PIEVECT_init()
    {
        int16 i;
        Uint32 *pSource = (void *) &PieVectTableInit;
        Uint32 *pDest = (void *) &(PIE_VECT->PIE1_RESERVED_INT); // get address of table

        // Do not write over first 3 32-bit locations (these locations are
        // initialized by Boot ROM with boot variables)
        pSource = pSource + 3;
        pDest = pDest + 3;

        EALLOW();
        for(i=0; i < 221; i++){
            *pDest++ = *pSource++;
        }
        EDIS();

        // Enable the PIE Vector Table
        PIE->PIECTRL.bit.ENPIE = 1;
    }

    Assembly code -
    PIEVECT_init():
    08834e: 8F488F08 MOVL XAR5, #0x088f08
    088350: 7622 EALLOW
    22 pDest = pDest + 3;
    088351: 8F000D06 MOVL XAR4, #0x000d06
    088353: BEDC MOVB XAR6, #0xdc
    26 *pDest++ = *pSource++;
    C$L42:
    088354: 0685 MOVL ACC, *XAR5++
    088355: 1E84 MOVL *XAR4++, ACC
    25 for(i=0; i < 221; i++){
    088356: 000EFFFE BANZ 65534,AR6--
    088358: 761A EDIS
    31 PIE->PIECTRL.bit.ENPIE = 1;
    088359: F5A90CE0 MOV @AL, *(0:0x0ce0)
    08835b: FF69 SPM #0
    08835c: 5001 ORB AL, #0x1
    08835d: F4A90CE0 MOV *(0:0x0ce0), @AL
    08835f: 0006 LRETR


    Could you please provide comments to solve this issue?
    Or can you arrange an experienced FAE engineer to our company "Schneider-electric Taiwan branch" to help me solve this problem?

    Thank you.

    Best Regards,
    Johnson

  • Johnson,
    In the failing example on F28004x device can you save the contents of memory at 0x88F08 before the PIEVECT_init is called and compare them to the contents at 0xD06 after the function is complete?

    As you have shown the assembly code is the same, so either the data at 0x88F08 is not getting copied to 0xD06 or the data at 0x88F08 is incorrect to start.

    Just to confirm, initially when we say the F28004x is failing, is the symptom that when an ISR is taken the device does not execute the ISR properly, ITRAP0, etc?

    If possible can you attach your .cmd(linker file) to your reply?

    Best,
    Matthew