cpainchaud / RFLink32

RFLink for ESP, with MQTT client
Other
134 stars 46 forks source link

Introduce a "debug to serial" method #29

Closed obones closed 3 years ago

obones commented 3 years ago

When writing a plugin, I often have the need to send debug information to the serial port, which I do like this:

 #ifdef PLUGIN_016_DEBUG
 Serial.print("packet = ");
 Serial.println(packet, 16);
 #endif

Now, this #ifdef structure being repeated quite a lot of time, I tried creating a code that would simplify this. But I also want this code to completely disappear from the firmware if the debug symbol is not defined. So, at first, I tried this:

#define SerialDebug(symbol, method, argument) #ifdef symbol Serial.method(argument) #endif

But this is not possible, the language does not allow using #ifdef inside #define

As a second try, I created this inside 7_Utils.h:

#ifdef SerialDebugActivated
#define SerialDebug(method, arguments...)  Serial.method(arguments)
#else
#define SerialDebug(method, arguments...)  /**/
#endif
#define SerialDebugPrintln(arguments...)   SerialDebug(println, arguments)
#define SerialDebugPrint(arguments...)     SerialDebug(print, arguments)

It then gets used like this:

SerialDebugPrint("packet =");
SerialDebugPrintln(packet, 16);

which works by adding this code at the top of the plugin file:

#define SerialDebugActivated
#include "../7_Utils.h"

Commenting out the first line gives the expected result, the code is completely absent from the firmware. And I believe this to be more readable and less "copy/paste" than the original code.

I'm creating this issue for discussion before submitting a pull request.

obones commented 3 years ago

Obviously, if SerialDebug is declared inside the #ifndef INCLUDE_UTIL_H_ section from 7_Utils.h, it will not be possible to control its activation on a plugin by plugin basis. This is because all the C files for each plugins are hard included in the main 5_Plugin.cpp file, which in and of itself is an issue that would be worth looking at.

That being said, it is possible to allow a per plugin control, by moving the above macro definitions out of the #ifndef INCLUDE_UTIL_H_ section while adding a #undef declaration at the end of the block, like so:

#ifdef SerialDebugActivated
#define SerialDebug(method, arguments...)  Serial.method(arguments)
#else
#define SerialDebug(method, arguments...)  /**/
#endif
#define SerialDebugPrintln(arguments...)   SerialDebug(println, arguments)
#define SerialDebugPrint(arguments...)     SerialDebug(print, arguments)
#undef SerialDebugActivated

This way, every plugin that includes 7_Utils.h gets a chance to set SerialDebugActivated for itself, effectively giving control on a per plugin basis.

However, this emits a warning: "SerialDebug" redefined This is fixed by undefining it before redefining it, which gives the final following block:

#ifdef SerialDebugActivated
#undef SerialDebug
#define SerialDebug(method, arguments...)  Serial.method(arguments)
#else
#undef SerialDebug
#define SerialDebug(method, arguments...)  /**/
#endif
#define SerialDebugPrintln(arguments...)   SerialDebug(println, arguments)
#define SerialDebugPrint(arguments...)     SerialDebug(print, arguments)
#undef SerialDebugActivated

Obviously, there would be an explanation comment in front of that block in the pull request.