How to modifiy existing MACRO calls without __VA_ARGS__ in Flash ?

Hello,

I'm integrating ansi C code from other projects in Arduino project...

So far, it seems to work, but have problem running out of memory when enabling debug prints on serial line.

I have a lot of these calls in code :

APPDBGBF_PRINTF(CAN,2,iex_NAD,"CAN_RX[%5d]: IX_DATA:  0x%02x  |Slot:%d|Class:%d|Dir:%d|Arg:%d|NAD:%d|Len:%d|IX:0x%02x \n", iex_NAD, ix_temp, iex_slot, iex_class, iex_dir, iex_arg, iex_NAD, msg_size,ix_temp);

And it seems that format strings are put into RAM, because I run out of memory if I enable this (tmpstr is statically allocated).

do {   {sprintf(tmpstr,__VA_ARGS__); Serial.print (tmpstr); Serial.println();};  } while (0)

When I disable these prints, it's ok.

Can I somehow solve this by using additional macro to put all format strings in program memory and then print on serial line using sprtinf_P ?

At the moment, I have this, but it complains about too many arguments to F() macro :

    #define  APPDBGBF_PRINTF(Type,Level,Nad,...) \
            APPDBGBF_ARDUINO_PRINTF (Type,Level,Nad,F(__VA_ARGS__))

Can I somehow get by without manually changing all existing MACRO debug calls in code ?

Thanks in advance,
regards.

can you share more code than this? full source of the macros, info about tmpstr or link to the original code?

Please provide the full declaration of the original macro APPDBGBF_PRINTF.

I think the solution might be something like:

#define  APPDBGBF_PRINTF(Type,Level,Nad, Fmt, ...) \
    do {sprintf_P(tmpstr, F(Fmt), __VA_ARGS__); Serial.print (tmpstr); Serial.println();} while (0)

Do you have parameters of the format String that would be '%s' like ?
Those would also end up in SRAM, not just the format string

johnwasser:
Please provide the full declaration of the original macro APPDBGBF_PRINTF.

I think the solution might be something like:

#define  APPDBGBF_PRINTF(Type,Level,Nad, Fmt, ...) \

do {sprintf_P(tmpstr, F(Fmt), VA_ARGS); Serial.print (tmpstr); Serial.println();} while (0)

Hello,
thanks all for help, this seems like a step in the right direction...
Now I get this error :

In file included from sketch\canbus.cpp:6:0:

sketch\canbus.cpp: In function 'uint_32 CANBus_Parse_RX_Message(uint_32, uint_8, unsigned char*)':

canbus.h:288:56: error: cannot convert 'const __FlashStringHelper*' to 'const char*' for argument '2' to 'int sprintf_P(char*, const char*, ...)'

               do {sprintf_P(tmpstr, F(Fmt), __VA_ARGS__); Serial.print (tmpstr); Serial.println();} while (0)

                                                        ^

sketch\canbus.cpp:114:33: note: in expansion of macro 'APPDBGBF_PRINTF'

                                 APPDBGBF_PRINTF(CAN,256,iex_NAD,"CAN_RX[%5d]: STAT_ID:0x%04x |Slot:%d|Class:%d|Dir:%d|Arg:%d|NAD:%d|Len:%d| CardID: %d  StatBits: 0b%016b \n", iex_NAD, FPData.IEXModules[iex_slot].Status.all, iex_slot, iex_class, iex_dir, iex_arg, iex_NAD, msg_size,dptr[2]*256+dptr[3],dptr[0]*256+dptr[1]);

                                 ^~~~~~~~~~~~~~~

canbus.h:288:56: error: cannot convert 'const __FlashStringHelper*' to 'const char*' for argument '2' to 'int sprintf_P(char*, const char*, ...)'

               do {sprintf_P(tmpstr, F(Fmt), __VA_ARGS__); Serial.print (tmpstr); Serial.println();} while (0)

                                                        ^

sketch\canbus.cpp:121:33: note: in expansion of macro 'APPDBGBF_PRINTF'

                                 APPDBGBF_PRINTF(CAN,1,iex_NAD,"CAN_RX[WARN]: CANBus_Parse_RX_Message: STATUS_ID CAN message with wrong length: Class:%d|Dir:%d|Arg:%d|NAD:%d|Len:%d\n", iex_class, iex_dir, iex_arg, iex_NAD, msg_size);

                                 ^~~~~~~~~~~~~~~

... (repeats for each macro call)

More info attached :

.cpp file:

#define TMPSTR_SIZE  48
char tmpstr[TMPSTR_SIZE ];
...
 APPDBGBF_PRINTF(CAN,256,iex_NAD,"CAN_RX[%5d]: STAT_ID:0x%04x |Slot:%d|Class:%d|Dir:%d|Arg:%d|NAD:%d|Len:%d| CardID: %d  StatBits: 0b%016b \n", iex_NAD, FPData.IEXModules[iex_slot].Status.all, iex_slot, iex_class, iex_dir, iex_arg, iex_NAD, msg_size,dptr[2]*256+dptr[3],dptr[0]*256+dptr[1]);
...



.h file:

#ifdef CFGAPP_DEBUG_ENABLE
      #define  APPDBGBF_PRINTF(Type,Level,Nad, Fmt, ...) \
              do {sprintf_P(tmpstr, F(Fmt), __VA_ARGS__); Serial.print (tmpstr); Serial.println();} while (0)

#else
        #define  APPDBGBF_PRINTF(Type,Level,Nad, Fmt, ...) {}
        
#endif

try with

#define  APPDBGBF_PRINTF(Type,Level,Nad, Fmt, ...) \
    do {sprintf_P(tmpstr, (const char*) F(Fmt), __VA_ARGS__); Serial.println(tmpstr);} while (0)

J-M-L:
try with

#define  APPDBGBF_PRINTF(Type,Level,Nad, Fmt, ...) \

do {sprintf_P(tmpstr, (const char*) F(Fmt), VA_ARGS); Serial.println(tmpstr);} while (0)

Hello,
thank you both for your suggestions. Now it seems to work... I only had minor problem, if there was macro with only text (no dynamic context), but have added dummy blank and it works now.
Thanks again for help,
regards.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.