-
Notifications
You must be signed in to change notification settings - Fork 5
only allow __FlashStringHelper on AVR #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just put some useful comments to explain code pieces.
rf24Logger.info((const __FlashStringHelper*) vendorID, F("RF24Log/examples/BasicSerialLogger")); | ||
rf24Logger.info((const __FlashStringHelper*) vendorIDFlash, F("RF24Log/examples/BasicSerialLogger")); | ||
|
||
RF24LOGGER_info("RF24LogExample", "Log message here"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A call of RF24LOGGER_info()
macro is independent on the used architecture. No FlashStringHelper
here.
This macro (instead of rf24Logger.info()
method) must be used for logging purposes.
@@ -54,6 +55,7 @@ class RF24LogHandler | |||
const __FlashStringHelper *vendorId, | |||
const __FlashStringHelper *message, | |||
va_list *args); | |||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be available only on AVR.
All log handlers are updated as well.
@@ -38,10 +38,11 @@ class RF24LogHandler | |||
* same order for which they appear in the @p message | |||
*/ | |||
virtual void log(uint8_t logLevel, | |||
const __FlashStringHelper *vendorId, | |||
const char *vendorId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is available for all architectures. However we could exclude it on AVR.
All log handlers are updated as well.
src/RF24Logger.h
Outdated
#if defined (ARDUINO_ARCH_AVR) | ||
#define RF24LOG_FLASHIFY(A) F(A) | ||
#define RF24LOGGER_info(vendorId, message, ...) (rf24Logger.log(RF24LogLevel::INFO, RF24LOG_FLASHIFY(vendorId), RF24LOG_FLASHIFY(message), ##__VA_ARGS__)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On AVR RF24LOGGER_info()
macro will wrap the provided texts in F()
macro. This will save RAM and store the texts in FLASH. Usage of this macro doesn't depend on architecture. The macro will be resolved during compilation time. This macro (instead of rf24Logger.info()
method) must be used for logging purposes.
src/RF24Logger.h
Outdated
#define RF24LOGGER_info(vendorId, message, ...) (rf24Logger.log(RF24LogLevel::INFO, vendorId, message, ##__VA_ARGS__)) | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On non AVR architectures the macro will pass the arguments just as they are, so as a char pointers (I hope - this is not tested yet).
00000d4c l F .text 000000a6 _ZN20RF24StreamLogHandler5writeEhPKcS1_PPv | ||
00000f36 l F .text 00000080 _GLOBAL__I_65535_0_RF24AbstractLogHandler.cpp.o.1928 | ||
008003f2 l O .bss 00000005 rf24SerialLogHandler | ||
00800141 l O .data 0000000e _ZTV20RF24StreamLogHandler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not seen here but the memory usage by the library components is still the same. I just replaced the templates into a methods with well known arguments.
I'm just not so happy with the following usage:
On AVR the macro will be translated into:
The vendor id is the same across the library (so it will not change) but with this solution it will be stored in FLASH three times, so FLASH will be a bit wasted here. We could make a requirement that on AVR platforms a
then we just need to rework the macro definition so on AVR it will acst the argument to
I have retested with Arduino Nano and it seems to be working. I have the feeling that on non AVR architectures the |
|
I thought that I read somewhere that the For simplicity, we could just do away with |
Replace '#elif' with '#else'.
For this I already reported #6
I'm not quite sure how it will behave when a user redefines macro or creates a new one. To support multi-platform (to be transparent for Maybe C/C++ offers some mechanism for scoping the variables, so |
Sorry I forgot about that thread.
Usually (in my experience), the compiler will output a warning when a macro is redefined. We could wrap the macro definitions with #ifndef RF24LOGGER_info
#define RF24LOGGER_info() //...
#endif This way someone could define the macro-wrapped function before including the src file that defines the lib's default definition. I imagine this would only be useful for a person that wants to make all their logged INFO messages to use a INFO sublevel instead. |
We need also to expose However I can imagine that the developer can still redefine macro. This may be dangerous because a macro provided by RF24Log library is an API method. There can be a situation where an end project uses two different libraries (from a different maintainers). Imagine now: first library uses our RF24Log macros and second library redefines macro (introduces a new sublevel parameter) and changes the API. The second library may compile and work correctly while the first one may not compile because the macro is now changed and the passed arguments doesn't match. |
We could encapsulate internal-only members with a namespace. As far as documenting the prohibited members, I think doxygen will show a lib-specific namespace in the "class list" (I need to test this though) which might be enough to signify that the encapsulated members are for internal-only usage (namespaces get a docstring just like any other data structure) - we could also add a |
…ed under ARDUINO_ARCH_AVR.
Ok. Now the arduino CI is outputting an error related to all examples that use explicit calls to functions that accept
It's possible that the previously seen error from the RF24LogHandler.h was because it wasn't
Or it could been from not including |
Does it relates the builds for non AVR architectures? Like i.e.
Those platforms may have not support for If we go with the solution with |
The more I think about it, I really like the idea of the user only using macros. That usage exactly matches the current |
That's what is perplexing. The platforms in question all use arduino/ArduinoCore-API (which defines |
src/RF24Logger.h
Outdated
@@ -18,10 +18,25 @@ | |||
#ifndef SRC_RF24LOGGER_H_ | |||
#define SRC_RF24LOGGER_H_ | |||
|
|||
#include <WString.h> | |||
#include <String.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do a
#if defined(ARDUINO_API_VERSION)
#include <String.h>
#else
#include <WString.h>
#endif
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean that sometimes must use WString.h
and in other cases String.h
?
Interesting.
I have both files for Arduino NANO:
packages\arduino\hardware\avr\1.8.3\cores\arduino\Wstring.h
packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\avr\include\string.h
However the second file is string.h
with lowercase. Does it matter when I use <String.h>
or <string.h>
?
Let's try with your suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is much better no. Thanks @2bndy5. On some non AVR platforms it still doesn't work:
In file included from /home/runner/work/RF24Log/RF24Log/examples/AllLogLevelsLogger/AllLogLevelsLogger.ino:18:0:
/home/runner/Arduino/libraries/RF24Log/src/RF24Logger.h:22:10: fatal error: String.h: No such file or directory
#include <String.h>
^~~~~~~~~~
compilation terminated.
Hm. I have built it locally against arduino:samd:nano_33_iot and it was working for me with #include <String.h>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it matter when I use <String.h> or <string.h>?
Hah, it matters. Now it looks nice when I included <string.h>
(lowercase).
Serial.println("Set log level to ALL"); | ||
rf24SerialLogHandler.setLogLevel(RF24LogLevel::ALL); | ||
logSimpleRamMessage(); | ||
logSimpleMessage(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love this example, but it could be simplified (and much more interactive) if we allow the user to change the logLevel
using the Serial terminal. That way we could dynamically demonstrate filtering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, with new changes it is a bit irrelevant where the message will be stored (RAM or FLASH) - from the point of the unified logging library - as it will be decided at compile time depending on the architecture (AVR or non-AVR).
Interactive examples is a cool idea. I have created #12 for this.
@wmarkow I pushed a change to master so that the Doxygen action should not fail on pull-requests. Can you please re-base your branch on current master? Its not important really, but this could be the 1st PR to pass all checks 🥇 |
Just realized I can rebase these commits when merging... @wmarkow @Avamander any objections? I very much like the direction this PR takes. |
@2bndy5 if you can merge this PR then go ahead. You suggested me to make a rebase on my local branch and the push the changes to the remote branch. I'm not quite convinced if this is good solution because after rebasing (rebase changes the git history tree) my local branch and remote branch will diverge, so they will not have a common root commit. I think I needed then to make a force push to the remote branch which may have its negative impact in some cases. I have no idea what is the best Github flow for this kind of situations. Just needed to read some docs about it. You can just merge the PR, it should be then fine. |
I'm also testing RF24Log library with ESP32 board where It looks correct; it compiles and run nice. |
I'm creating a new PR related to fix #5
With my changes:
__FlashStringHelper
) may cause problems on some non avr boards. because of this a introduce aRF24LOGGER_info
macro which on AVR will wrap the texts inF()
.This is just a preliminary work to show what options we have in this topic.
Any suggestions are welcome.