Merge pull request #8076 from kjbracey-arm/error_stderr

Error output improvements
pull/8272/head
Cruz Monrreal 2018-10-18 08:39:17 -05:00 committed by GitHub
commit e698f0b29f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 68 additions and 36 deletions

View File

@ -134,6 +134,23 @@ void UARTSerial::sigio(Callback<void()> func)
core_util_critical_section_exit();
}
/* Special synchronous write designed to work from critical section, such
* as in mbed_error_vprintf.
*/
ssize_t UARTSerial::write_unbuffered(const char *buf_ptr, size_t length)
{
while (!_txbuf.empty()) {
tx_irq();
}
for (size_t data_written = 0; data_written < length; data_written++) {
SerialBase::_base_putc(*buf_ptr++);
data_written++;
}
return length;
}
ssize_t UARTSerial::write(const void *buffer, size_t length)
{
size_t data_written = 0;
@ -143,6 +160,10 @@ ssize_t UARTSerial::write(const void *buffer, size_t length)
return 0;
}
if (core_util_in_critical_section()) {
return write_unbuffered(buf_ptr, length);
}
api_lock();
// Unlike read, we should write the whole thing if blocking. POSIX only

View File

@ -238,6 +238,9 @@ private:
/** Release mutex */
virtual void api_unlock(void);
/** Unbuffered write - invoked when write called from critical section */
ssize_t write_unbuffered(const char *buf_ptr, size_t length);
/** Software serial buffers
* By default buffer size is 256 for TX and 256 for RX. Configurable through mbed_app.json
*/

View File

@ -18,13 +18,8 @@
#include "platform/mbed_wait_api.h"
#include "platform/mbed_toolchain.h"
#include "platform/mbed_interface.h"
#include "platform/mbed_retarget.h"
#include "platform/mbed_critical.h"
#include "hal/serial_api.h"
#if DEVICE_SERIAL
extern int stdio_uart_inited;
extern serial_t stdio_uart;
#endif
WEAK void mbed_die(void)
{
@ -55,36 +50,41 @@ void mbed_error_printf(const char *format, ...)
{
va_list arg;
va_start(arg, format);
mbed_error_vfprintf(format, arg);
mbed_error_vprintf(format, arg);
va_end(arg);
}
void mbed_error_vprintf(const char *format, va_list arg)
{
core_util_critical_section_enter();
char buffer[132];
int size = vsnprintf(buffer, sizeof buffer, format, arg);
if (size >= sizeof buffer) {
/* Output was truncated - indicate by overwriting last 4 bytes of buffer
* with ellipsis and newline.
* (Note that although vsnprintf always leaves a NUL terminator, we
* don't need a terminator and can use the entire buffer)
*/
memcpy(&buffer[sizeof buffer - 4], "...\n", 4);
size = sizeof buffer;
}
#if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES || MBED_CONF_PLATFORM_STDIO_CONVERT_TTY_NEWLINES
char stdio_out_prev = '\0';
for (int i = 0; i < size; i++) {
if (buffer[i] == '\n' && stdio_out_prev != '\r') {
const char cr = '\r';
write(STDERR_FILENO, &cr, 1);
}
write(STDERR_FILENO, &buffer[i], 1);
stdio_out_prev = buffer[i];
}
#else
write(STDERR_FILENO, buffer, size);
#endif
core_util_critical_section_exit();
}
void mbed_error_vfprintf(const char *format, va_list arg)
{
#if DEVICE_SERIAL
#define ERROR_BUF_SIZE (128)
core_util_critical_section_enter();
char buffer[ERROR_BUF_SIZE];
int size = vsnprintf(buffer, ERROR_BUF_SIZE, format, arg);
if (size > 0) {
if (!stdio_uart_inited) {
serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
}
#if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
char stdio_out_prev = '\0';
for (int i = 0; i < size; i++) {
if (buffer[i] == '\n' && stdio_out_prev != '\r') {
serial_putc(&stdio_uart, '\r');
}
serial_putc(&stdio_uart, buffer[i]);
stdio_out_prev = buffer[i];
}
#else
for (int i = 0; i < size; i++) {
serial_putc(&stdio_uart, buffer[i]);
}
#endif
}
core_util_critical_section_exit();
#endif
mbed_error_vprintf(format, arg);
}

View File

@ -89,7 +89,7 @@ WEAK void error(const char *format, ...)
#ifndef NDEBUG
va_list arg;
va_start(arg, format);
mbed_error_vfprintf(format, arg);
mbed_error_vprintf(format, arg);
va_end(arg);
#endif
exit(1);

View File

@ -42,7 +42,7 @@ extern "C" {
#else //MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN
#if MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN > 64
//We have to limit this to 64 bytes since we use mbed_error_printf for error reporting
//and mbed_error_vfprintf uses 128bytes internal buffer which may not be sufficient for anything
//and mbed_error_vprintf uses 128bytes internal buffer which may not be sufficient for anything
//longer that 64 bytes with the current implementation.
#error "Unsupported error filename buffer length detected, max supported length is 64 chars. Please change MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN or max-error-filename-len in configuration."
#endif

View File

@ -26,6 +26,7 @@
#include <stdarg.h>
#include "mbed_toolchain.h"
#include "device.h"
/* Mbed interface mac address
@ -146,9 +147,15 @@ void mbed_error_printf(const char *format, ...);
* @param arg Variable arguments list
*
*/
void mbed_error_vprintf(const char *format, va_list arg);
/** @deprecated Renamed to mbed_error_vprintf to match functionality */
MBED_DEPRECATED_SINCE("mbed-os-5.11",
"Renamed to mbed_error_vprintf to match functionality.")
void mbed_error_vfprintf(const char *format, va_list arg);
/** @}*/
#ifdef __cplusplus
}
#endif

View File

@ -1250,6 +1250,8 @@ extern "C" void exit(int return_code)
#if MBED_CONF_PLATFORM_STDIO_FLUSH_AT_EXIT
fflush(stdout);
fflush(stderr);
fsync(STDOUT_FILENO);
fsync(STDERR_FILENO);
#endif
#endif

View File

@ -18,7 +18,6 @@
#include "device.h"
#include "platform/mbed_error.h"
#include "platform/mbed_interface.h"
#include "hal/serial_api.h"
#ifndef MBED_FAULT_HANDLER_DISABLED
#include "mbed_rtx_fault_handler.h"