1

Hello I have the following problem:

  • IDE: Eclipse Version: 2018-12 (4.10.0) with the Keil C51 plugin (for Language Mapping)
  • Compiler (external): Wickenhäuser uc51

Problem here: Eclipse Bad Character Sequence

Keil Language mapping is using this syntax:

xdata unsigned char Port = 0x1;

Wickenhäuser is slightly different:

xdata unsigned char Port @ 0x1;

So I came to this working solution:

#ifdef __CDT_PARSER__
    xdata unsigned char Port = 0x1;
#else
    //xdata unsigned char Port @ 0x1; //BAD Character Squence encountered: @
    #define AT_ADDRESS(n) @##n //Using this Macro to get around this problem
    xdata unsigned char Port_B AT_ADDRESS(0x1);
#endif

But this solution is not perfect, (doubles writing etc.) and should look like this:

#ifdef __CDT_PARSER__ //In Keil I have to define this too, to make use the Keil syntax
    //#define AT_ADDRESS(n) // This works
    #define AT_ADDRESS(n) =##n // Gives error
#else
    #define AT_ADDRESS(n) @##n
#endif

xdata unsigned char Port_B AT_ADDRESS(0x1); // GIVES ERROR: Invalid use of macro pasting in macro AT_ADDRESS

Unfortunately Eclipse flags this: Invalid use of macro pasting in macro AT_ADDRESS

  • Consider finding a macro set by the Wickenhäuser compiler and using that to trigger the `@` notation — or use a macro name such as `USE_WICKENHAUSER_INITIALIZER` and `#ifdef USE_WICKENHAUSER_INITIALIZER` to select the `@` notation, defaulting to the (standard) `=` notation. Then at worst you need to configure the Wickenhäuser build to set the `USE_WICKENHAUSER_INITIALIZER` macro. You use `##` to build a single identifier from multiple parts; you don't use it for material that cannot be part of an identifier. – Jonathan Leffler Feb 21 '19 at 17:45
  • Thanks. Will do so. I was considering something similar, as I wrote //In Keil I have to define this too, to make use the Keil syntax – Tick Tac Joe Feb 21 '19 at 17:54
  • In the circumstances, using a macro to hide the difference between the systems is almost certainly the best way to proceed (so `AT_ADDRESS` is a good idea). The implementation can be tidied up — put it in a header rather than botching the code into more than one source file, for example. (I work with code where there is *far* too much "this paragraph works here; let's copy it over there too" rather than properly isolating the issue. The problems come when the paragraph needs modifying; then there are an unpleasantly large number of places to change — and finding them all can be hard, too!) – Jonathan Leffler Feb 21 '19 at 17:57

2 Answers2

3

you don't need pasting at this point. Just replace

#define AT_ADDRESS(n) =##n

by

#define AT_ADDRESS(n) = n

same goes for the extended C version, both "expanded" examples you're showing have a space character inserted between the address symbol and the actual address so:

#ifdef __CDT_PARSER__ //In Keil I have to define this too, to make use the Keil syntax
    #define AT_ADDRESS(n) = n
#else
    #define AT_ADDRESS(n) @ n
#endif
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • Does this also work? I can not test it at the moment: #define CS_PPI_DIO 0xe800 \n xdata unsigned char PPI_DIO_Port_A AT_ADDRESS((CS_PPI_DIO + 0x0)); – Tick Tac Joe Feb 21 '19 at 18:00
  • 1
    @TickTacJoe — Yes, you could use `AT_ADDRESS((CS_PPI_DIO + 0x0))`, though you could also simply use `AT_ADDRESS(CS_PPI_DIO)` since adding zero doesn't change anything, and the extra parentheses were optional when the addition was used (if you need an offset, then `AT_ADDRESS(CS_PPI_DIO + 0x10)` would work). – Jonathan Leffler Feb 21 '19 at 18:23
0

Now I build this improved (with the tips above), working solution.

#ifndef COMPILER_COMPAT_H_
#define COMPILER_COMPAT_H_

#define COMPILER_COMPAT_WICKEN // Comment out for use project in Keil


#ifdef __CDT_PARSER__
#   undef COMPILER_COMPAT_WICKEN
#endif

#ifndef COMPILER_COMPAT_WICKEN
#   ifndef BIT_ADDRESS
#       define BIT_ADDRESS(n) = n
#   endif
#else
#   ifndef BIT_ADDRESS
#       define BIT_ADDRESS(n) @ n
#   endif
#endif


#endif /* COMPILER_COMPAT_H_ */
  • That's the general idea. Personally, I'd avoid having to comment out for the Keil compiler; you don't want to have to change the source code to get it to compile. (Such editing is error prone and leaves builds less easily and reliably reproduced.) Try to find a symbol analogous to `__CDT_PARSER__` that is defined by the Wickenhäuser compiler and not defined by either Eclipse/CDT or Keil. Use that to trigger conditions. (Also, you could move `#ifndef BIT_ADDRESS` outside the `#ifdef COMPILER_COMPAT_WICKEN` block so you don't have to repeat it.) – Jonathan Leffler Feb 21 '19 at 18:29