Skip to content
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

ESP printf support #18

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Flexible logging library for the Arduino SDK. This library allows the same loggi

## Dependencies

This library requires the following Arduino library to be installed on your system:
This library requires the following Arduino library to be installed on your system if you are using a non-ESP8266/ESP32 setup:

* [embeddedartistry/arduino-printf](https://github.com/embeddedartistry/arduino-printf)

Expand Down Expand Up @@ -280,7 +280,7 @@ These settings can be changed in the build system, but it is easiest to define t

By default, the logging library does not echo logging calls to the serial console. You can change the default setting at compile-time using the `LOG_ECHO_EN_DEFAULT` definition.

The logging library will print the output using the `printf` function. To change that output, see the instructions in the [embeddedartistry/arduino-printf](https://github.com/embeddedartistry/arduino-printf) library.
The logging library will print the output using the `printf` function. To change that output, see the instructions in the [embeddedartistry/arduino-printf](https://github.com/embeddedartistry/arduino-printf) library. If you are using the ESP8266 or ESP32, we use the built-in `printf` support instead of the external library.

The setting can be changed in your build system or by defining the desired value in `platform_logger.h` before including the necessary logging library header.

Expand Down
32 changes: 31 additions & 1 deletion src/ArduinoLogger.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
#ifndef ARDUINO_LOGGER_H_
#define ARDUINO_LOGGER_H_

#ifdef __XTENSA__
#include <ets_sys.h>
#include <internal/lambda.h>
#else
#include <LibPrintf.h>
#endif
#if !defined(__AVR__)
#include <utility>
#endif

#ifdef __XTENSA__
void _putchar(char c);
#endif

/// Logging is disabled
#define LOG_LEVEL_OFF 0
/// Indicates the system is unusable, or an error that is unrecoverable
Expand Down Expand Up @@ -270,6 +279,26 @@ class LoggerBase
#endif
}

#ifdef __XTENSA__
/// Prints directly to the log with no extra characters added to the message.
void print(const char* format, ...) noexcept
{
// We need to capture this with a lambda to call log_putc,
// Then decay that into a function pointer for a callback
auto f = [this](char c) { log_putc(c); };
void (*callback)(char) = Lambda::ptr(f);

va_list va;
va_start(va, format);
ets_vprintf(callback, format, va);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line would cause compilation error if in ets_sys.h function declaration is as follows:
int ets_vprintf(int (*print_function)(int), const char * format, va_list arg) __attribute__ ((format (printf, 2, 0)));
and this is the case for ArduCAM ESP8266 UNO
error:
arduino-logger/src/ArduinoLogger.h:293:35: error: invalid conversion from 'void (*)(char)' to 'int (*)(int)' [-fpermissive] ets_vprintf(callback, format, va); ^

va_end(va);

if(echo_)
{
ets_vprintf(ets_putc, format, va);
}
}
#else
/// Prints directly to the log with no extra characters added to the message.
template<typename... Args>
void print(const Args&... args) noexcept
Expand All @@ -282,6 +311,7 @@ class LoggerBase
printf(args...);
}
}
#endif

/** Add data to the log buffer
*
Expand All @@ -301,7 +331,7 @@ class LoggerBase

log_customprefix();

// Send the primary log statement
// Send the primary log statementets_vprintf
print(fmt, args...);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/CircularBufferLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ class CircularLogBufferLogger final : public LoggerBase
{
while(!log_buffer_.empty())
{
#ifdef __XTENSA__
ets_putc(log_buffer_.pop_front());
#else
_putchar(log_buffer_.pop_front());
#endif
}
}

Expand Down
59 changes: 59 additions & 0 deletions src/internal/lambda.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#ifndef LAMBDA_HELPERS_H_
#define LAMBDA_HELPERS_H_

/** Lambda Helper: Decay to Function Pointer
*
* When you need to convert a lambda with captures to a C pointer,
* such as when a callback interface doesn't provide a variable for private data
* which can store a `this` pointer, use this helper.
*
* @code
* int a = 100;
* auto b = [&](void*) {return ++a;};
*
* // Converting lambda with captures to a C pointer
* void (*f1)(void*) = Lambda::ptr(b);
* f1(nullptr);
* printf("%d\n", a); // 101
*
* // In case return value should be used
* int (*f3)(void*) = Lambda::ptr<int>(b);
* printf("%d\n", f3(nullptr)); // 103
*
* // In case data is used
* auto b2 = [&](void* data) {return *(int*)(data) + a;};
* int (*f4)(void*) = Lambda::ptr<int>(b2);
* int data = 5;
* printf("%d\n", f4(&data)); // 108
* @endcode
*
* Source: https://stackoverflow.com/questions/7852101/c-lambda-with-captures-as-a-function-pointer
*/
struct Lambda
{
template<typename Tret, typename T>
static Tret lambda_ptr_exec(char data)
{
return (Tret)(*(T*)fn<T>())(data);
}

template<typename Tret = void, typename Tfp = Tret (*)(char), typename T>
static Tfp ptr(T& t)
{
fn<T>(&t);
return (Tfp)lambda_ptr_exec<Tret, T>;
}

template<typename T>
static void* fn(void* new_fn = nullptr)
{
static void* fn;
if(new_fn != nullptr)
{
fn = new_fn;
}
return fn;
}
};

#endif // LAMBDA_HELPERS_H_