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.

ti-cgt-msp430_4.4.0 runtime support library: compile error in _link.h

Other Parts Discussed in Thread: MSP430F5529

I've just hit the compile error described in this thread on the MSP430 forum: http://e2e.ti.com/support/microcontrollers/msp430/f/166/t/389538

C:/ti/ccsv6/tools/compiler/ti-cgt-msp430_4.4.0/include/_lock.h", line 48: error #56-D: too many arguments in invocation of macro "_nop

It appears to be the result of a change to in intrinsics.h. Previously it declared:

void _nop(void);

Later versions changed that to:

void           __no_operation(void);
[...]
#define _nop()                  __no_operation()

Also the _nop declaration in _lock.h was changed from:

_CODE_ACCESS void _nop();

to:

_CODE_ACCESS void _nop(void);

Now the preprocessor tries to treat "void" as a parameter to the _nop macro from intrinsics.h while preprocessing _lock.h, resulting in the error.

From looking at the source for _lock.h and _lock.c it appears that the use of the identifier _nop is accidental. The intention was to define a function that is used as a default implementation for the lock and unlock functions. The default (which does nothing) can be optionally overridden using _register_lock/_register_unlock. The implementation of an empty function _nop in _lock.c implies that this "_nop" doesn't relate in any way to the _nop defined by intrinsics.h. Also the macros SYSTEM_WIDE_LOCK_REGISTERED and SYSTEM_WIDE_UNLOCK_REGISTERED defined in _lock.h use the address of the _nop function defined in _lock.h as a sentinel value. These macros are used by _pthread.c to check at runtime whether the lock/unlock functions have been overridden.

My suggested fix for the compile error is to change all instances of _nop in _lock.h/.c to something that won't collide with the _nop from intrinsics.h, eg:

_CODE_ACCESS void _lock_nop_implementation(void);

Note that this fix requires the RTS libraries be rebuilt from source, so isn't intended for end-users.

  • There are two known issues, SDSCM00051212 and SDSCM00051278, which cover this.
  • I just ran into this trying to build the FR5969 w/Sharp Booster before porting the demo to Dung Dang's MDD patch for the ES2 LP (I'm being purposely vague because this is general forum). What is the fix for this so I can continue ES2/MDD evaluation?
  • The preferred fix is to download the fixed version of the compiler, MSP430 4.4.1. If that is not feasible, copy the library header file _lock.h into your project and modify the declaration of _nop to remove the argument list.
  • Archaeologist said:
    The preferred fix is to download the fixed version of the compiler, MSP430 4.4.1. If that is not feasible, copy the library header file _lock.h into your project and modify the declaration of _nop to remove the argument list.

    I just tried upgrading to MSP430 compiler 4.4.2. While it prevents the original 'too many arguments in invocation of macro "_nop' error, there is another potential problem. As the function declaration _nop still shares its name with the unrelated _nop macro in intrinsics.h, a compile error may occur if _lock.h is ever included after instrinsics.h. Here's an example which demonstrates the error:

    #include "driverlib.h"
    #include "_lock.h"
    
    int main(void)
    {
    	if(!SYSTEM_WIDE_LOCK_REGISTERED)
    		WDT_A_hold(WDT_A_BASE);
    
        return (0);
    }

    Create a new driverlib project for MSP430F5529 with the 4.4.2 compiler and replace main.c with the above code. In the preprocessed output _lock.h becomes:

    #pragma diag_push
    
    /* _nop(), _lock(), and _unlock() all accept zero or more optional arguments,
       which must remain as empty rather than (void) parameter lists to avoid
       breaking the API */
    #pragma CHECK_MISRA("-16.5")
    
     void __no_operation();
    
    extern  void (  *_lock)();
    extern  void (*_unlock)();
    
     void _register_lock  (void (  *lock)());
     void _register_unlock(void (*unlock)());
    
    #pragma diag_pop

    Note that the prototype at line 8 has been changed from _nop to __no_operation by the macro in intrinsics.h. The SYSTEM_WIDE_LOCK_REGISTERED and SYSTEM_WIDE_UNLOCK_REGISTERED macros still refer to the original function name "_nop". This causes an error when compiling main.c as _nop is undefined.

    At present the runtime library compiles without this error because _lock.h is only included in _pthread.c, which doesn't include intrinsics.h.

  • Yes, that is the subject of SDSCM00051278, which has not yet been fixed.