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.

#pragma RETAIN generates Error # 18 expected a ")"

Dear C++ Compiler Wizards,

   The following code generates error #18 expected a ")":

typedef enum {
USCIAB1TX_isr, USCIAB1RX_isr,
PORT1_isr, PORT2_isr,
RESERVED20_isr, ADC12_isr,
USCIAB0TX_isr, USCIAB0RX_isr,
TIMERA1_isr, TIMERA0_isr,
WDT_isr, COMPARATORA_isr,
TIMERB1_isr, TIMERB0_isr,
NMI_isr,
NUM_VECTORS
} MSP430ISRs;
static unsigned TB0isrCount;
void interrupt CSL_Default_Timer_B0 (void)
{
++TB0isrCount;
TBCCTL0 &= ~CCIFG; /* Do I need to clear the IRQ pending bit? */
}
/*
* The MSP430's interrupt vectors are in flash. Sometimes however the
* application needs to be able to dynamically change the ISR. This jump
* table provides this capability.
*/
unsigned ISR_VectorTable [NUM_VECTORS*2u] = {
0x4010u, 0xFFFEu, /* BRanch to self opcode */
0x4010u, 0xFFFEu,
0x4010u, 0xFFFEu,
0x4010u, 0xFFFEu,
0x4010u, 0xFFFEu,
0x4010u, 0xFFFEu,
0x4010u, 0xFFFEu,
0x4010u, 0xFFFEu,
0x4010u, 0xFFFEu,
0x4010u, 0xFFFEu,
0x4010u, 0xFFFEu,
0x4010u, 0xFFFEu,
0x4010u, 0xFFFEu,
0x4010u, (unsigned) &CSL_Default_Timer_B0,
0x4010u, 0xFFFEu
};

#pragma SET_DATA_SECTION(".int13")
#pragma RETAIN (timerb0irq)
const unsigned timerb0irq = (unsigned) &ISR_VectorTable[TIMERB0_isr*2u];
#pragma SET_DATA_SECTION()

Is this a compiler defect or am I using these pragmas incorrectly?  I am using these tools: 

Code Composer Studio Version: 5.1.0.09000 
MSP430 C/C++ Codegen   PC v4.0.0

I also have tried using #pragma FUNC_NEVER_RETURNS (in a different context) but the function still ends with an RTS.

Regards,

Fred

  • The syntax for pragmas is different in C++; instead of specifying the name of the affected object, place the pragma just before the object affected, like this:

    #pragma SET_DATA_SECTION(".int13") 
    #pragma RETAIN
    const unsigned timerb0irq = (unsigned) &ISR_VectorTable[TIMERB0_isr*2u];
    #pragma SET_DATA_SECTION()
  • Dear Archaelogist,

       Changing the pragma line did indeed remove the error from the compilation.  Thank you.  I fear I must now report a documentation error on page 95 of Literature Number: SLAU132F  dated November 2011 which states:

    5.9.20 The RETAIN Pragma

    The RETAIN pragma can be applied to a code or data symbol. It causes a .retain directive to be
    generated into the section that contains the definition of the symbol. The .retain directive indicates to the
    linker that the section is ineligible for removal during conditional linking. Therefore, regardless whether or
    not the section is referenced by another section in the application that is being compiled and linked, it will
    be included in the output file result of the link.

    The syntax of the pragma in C/C++ is:

    #pragma RETAIN (symbol )

       The compilation/link is still not correct.  The linker shows no data in section .int13:

    MSP430 Linker PC v4.0.0
    < Intermediate lines removed >
     name   origin   length    used     unused  attr fill
    ------ -------- --------- -------- -------- ---- --------
    < More lines removed >
    INT08  0000fff0 00000002 00000002 00000000 RWIX

    INT09  0000fff2 00000002 00000002 00000000 RWIX
    INT10  0000fff4 00000002 00000000 00000002 RWIX
    INT11  0000fff6 00000002 00000000 00000002 RWIX
    INT12  0000fff8 00000002 00000000 00000002 RWIX
    INT13  0000fffa 00000002 00000000 00000002 RWIX
    INT14  0000fffc 00000002 00000000 00000002 RWIX
    RESET  0000fffe 00000002 00000002 00000000 RWIX
    FLASH2 00010000 00010000 00000000 00010000 RWIX

    Changing from SET_DATA_SECTION to SET_CODE_SECTION makes no difference.  Any ideas? 

    Regards,

    Fred

  • You are correct; I've submitted SDSCM00042868 to track the documentation issue.

    I'll get someone to look into RETAIN not retaining.  In the meantime, have a look at "#pragma vector", which might be a better fit.

  • Make it extern const:

    extern const unsigned timerb0irq = (unsigned) &ISR_VectorTable[TIMERB0_isr*2u]; 

    Otherwise, to C++, this is a true constant, not a global variable, and so it never gets space allocated for it.

    There's something fishy going on with the interaction between RETAIN and extern const.  I'll have someone look at that.

  • Dear Archaeologist,

       Thank you for reminding me that the C++ compiler has the option to treat const's as literals if it wants to.  I was able to confirm that 'extern const' removes the need for the #pragma RETAIN (a much better solution I believe).  Alas 'const' seems to trump the SET_DATA_SECTION pragma:

    468                   .global timerb0irq
    469 000000            .sect   ".const"
    470                   .align 2
    471 000000 timerb0irq:
    472 000000 0086!      .field ISR_VectorTable+52,16  ; timerb0irq @ 0
    473
    474          $C$DW$84 .dwtag DW_TAG_variable, DW_AT_name("timerb0irq")
    475                   .dwattr $C$DW$84, DW_AT_TI_symbol_name("timerb0irq")
    476                   .dwattr $C$DW$84, DW_AT_location[DW_OP_addr timerb0irq]
    477                   .dwattr $C$DW$84, DW_AT_type(*$C$DW$T$47)
    478                   .dwattr $C$DW$84, DW_AT_external

      I'll experiment with the vector pragma.

    Regards,

    Fred

  • Dear Archaeologist,

       In my previous post I wrote SET_DATA_SECTION instead of SET_CODE_SECTION.  Hmm, I wonder why the compiler silently ignored the SET_CODE_SECTION pragma?  A remark or warning would have been nice.  When I compile with SET_DATA_SECTION, the compiler does just what I expect:

    468                   .global timerb0irq
    469 000000            .sect   ".int13"
    470                   .align 2
    471 000000 timerb0irq:
    472 000000 0086!      .field ISR_VectorTable+52,16 ; timerb0irq @ 0

    and the linker now reports:

    name  origin   length   used     unused   attr fill
    ----- -------- -------- -------- -------- ---- --------
    INT09 0000fff2 00000002 00000002 00000000 RWIX
    INT10 0000fff4 00000002 00000000 00000002 RWIX
    INT11 0000fff6 00000002 00000000 00000002 RWIX
    INT12 0000fff8 00000002 00000000 00000002 RWIX
    INT13 0000fffa 00000002 00000002 00000000 RWIX     <-- Yaba daba do!
    INT14 0000fffc 00000002 00000000 00000002 RWIX

    Thank you for all your help!

    Regards,

    Fred

  • Here it is 2014, over a year later, and the documentation is *STILL* wrong for #pragma RETAIN in C++ code.  It would be nice to assign a priority to get this fixed.  It just cost me several hours of time to track this down.  If the documentation were correct, it would have worked to begin with.  :-)