Skip to content

Commit e698f0b

Browse files
author
Cruz Monrreal
authored
Merge pull request #8076 from kjbracey-arm/error_stderr
Error output improvements
2 parents ad6ada0 + 2df322c commit e698f0b

File tree

8 files changed

+64
-32
lines changed

8 files changed

+64
-32
lines changed

drivers/UARTSerial.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,23 @@ void UARTSerial::sigio(Callback<void()> func)
134134
core_util_critical_section_exit();
135135
}
136136

137+
/* Special synchronous write designed to work from critical section, such
138+
* as in mbed_error_vprintf.
139+
*/
140+
ssize_t UARTSerial::write_unbuffered(const char *buf_ptr, size_t length)
141+
{
142+
while (!_txbuf.empty()) {
143+
tx_irq();
144+
}
145+
146+
for (size_t data_written = 0; data_written < length; data_written++) {
147+
SerialBase::_base_putc(*buf_ptr++);
148+
data_written++;
149+
}
150+
151+
return length;
152+
}
153+
137154
ssize_t UARTSerial::write(const void *buffer, size_t length)
138155
{
139156
size_t data_written = 0;
@@ -143,6 +160,10 @@ ssize_t UARTSerial::write(const void *buffer, size_t length)
143160
return 0;
144161
}
145162

163+
if (core_util_in_critical_section()) {
164+
return write_unbuffered(buf_ptr, length);
165+
}
166+
146167
api_lock();
147168

148169
// Unlike read, we should write the whole thing if blocking. POSIX only

drivers/UARTSerial.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ class UARTSerial : private SerialBase, public FileHandle, private NonCopyable<UA
238238
/** Release mutex */
239239
virtual void api_unlock(void);
240240

241+
/** Unbuffered write - invoked when write called from critical section */
242+
ssize_t write_unbuffered(const char *buf_ptr, size_t length);
243+
241244
/** Software serial buffers
242245
* By default buffer size is 256 for TX and 256 for RX. Configurable through mbed_app.json
243246
*/

platform/mbed_board.c

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,8 @@
1818
#include "platform/mbed_wait_api.h"
1919
#include "platform/mbed_toolchain.h"
2020
#include "platform/mbed_interface.h"
21+
#include "platform/mbed_retarget.h"
2122
#include "platform/mbed_critical.h"
22-
#include "hal/serial_api.h"
23-
24-
#if DEVICE_SERIAL
25-
extern int stdio_uart_inited;
26-
extern serial_t stdio_uart;
27-
#endif
2823

2924
WEAK void mbed_die(void)
3025
{
@@ -55,36 +50,41 @@ void mbed_error_printf(const char *format, ...)
5550
{
5651
va_list arg;
5752
va_start(arg, format);
58-
mbed_error_vfprintf(format, arg);
53+
mbed_error_vprintf(format, arg);
5954
va_end(arg);
6055
}
6156

62-
void mbed_error_vfprintf(const char *format, va_list arg)
57+
void mbed_error_vprintf(const char *format, va_list arg)
6358
{
64-
#if DEVICE_SERIAL
65-
#define ERROR_BUF_SIZE (128)
6659
core_util_critical_section_enter();
67-
char buffer[ERROR_BUF_SIZE];
68-
int size = vsnprintf(buffer, ERROR_BUF_SIZE, format, arg);
69-
if (size > 0) {
70-
if (!stdio_uart_inited) {
71-
serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
72-
}
73-
#if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES
74-
char stdio_out_prev = '\0';
75-
for (int i = 0; i < size; i++) {
76-
if (buffer[i] == '\n' && stdio_out_prev != '\r') {
77-
serial_putc(&stdio_uart, '\r');
78-
}
79-
serial_putc(&stdio_uart, buffer[i]);
80-
stdio_out_prev = buffer[i];
60+
char buffer[132];
61+
int size = vsnprintf(buffer, sizeof buffer, format, arg);
62+
if (size >= sizeof buffer) {
63+
/* Output was truncated - indicate by overwriting last 4 bytes of buffer
64+
* with ellipsis and newline.
65+
* (Note that although vsnprintf always leaves a NUL terminator, we
66+
* don't need a terminator and can use the entire buffer)
67+
*/
68+
memcpy(&buffer[sizeof buffer - 4], "...\n", 4);
69+
size = sizeof buffer;
70+
}
71+
#if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES || MBED_CONF_PLATFORM_STDIO_CONVERT_TTY_NEWLINES
72+
char stdio_out_prev = '\0';
73+
for (int i = 0; i < size; i++) {
74+
if (buffer[i] == '\n' && stdio_out_prev != '\r') {
75+
const char cr = '\r';
76+
write(STDERR_FILENO, &cr, 1);
8177
}
78+
write(STDERR_FILENO, &buffer[i], 1);
79+
stdio_out_prev = buffer[i];
80+
}
8281
#else
83-
for (int i = 0; i < size; i++) {
84-
serial_putc(&stdio_uart, buffer[i]);
85-
}
82+
write(STDERR_FILENO, buffer, size);
8683
#endif
87-
}
8884
core_util_critical_section_exit();
89-
#endif
85+
}
86+
87+
void mbed_error_vfprintf(const char *format, va_list arg)
88+
{
89+
mbed_error_vprintf(format, arg);
9090
}

platform/mbed_error.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ WEAK void error(const char *format, ...)
8989
#ifndef NDEBUG
9090
va_list arg;
9191
va_start(arg, format);
92-
mbed_error_vfprintf(format, arg);
92+
mbed_error_vprintf(format, arg);
9393
va_end(arg);
9494
#endif
9595
exit(1);

platform/mbed_error.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ extern "C" {
4242
#else //MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN
4343
#if MBED_CONF_PLATFORM_MAX_ERROR_FILENAME_LEN > 64
4444
//We have to limit this to 64 bytes since we use mbed_error_printf for error reporting
45-
//and mbed_error_vfprintf uses 128bytes internal buffer which may not be sufficient for anything
45+
//and mbed_error_vprintf uses 128bytes internal buffer which may not be sufficient for anything
4646
//longer that 64 bytes with the current implementation.
4747
#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."
4848
#endif

platform/mbed_interface.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <stdarg.h>
2828

29+
#include "mbed_toolchain.h"
2930
#include "device.h"
3031

3132
/* Mbed interface mac address
@@ -146,9 +147,15 @@ void mbed_error_printf(const char *format, ...);
146147
* @param arg Variable arguments list
147148
*
148149
*/
150+
void mbed_error_vprintf(const char *format, va_list arg);
151+
152+
/** @deprecated Renamed to mbed_error_vprintf to match functionality */
153+
MBED_DEPRECATED_SINCE("mbed-os-5.11",
154+
"Renamed to mbed_error_vprintf to match functionality.")
149155
void mbed_error_vfprintf(const char *format, va_list arg);
150156
/** @}*/
151157

158+
152159
#ifdef __cplusplus
153160
}
154161
#endif

platform/mbed_retarget.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,8 @@ extern "C" void exit(int return_code)
12501250
#if MBED_CONF_PLATFORM_STDIO_FLUSH_AT_EXIT
12511251
fflush(stdout);
12521252
fflush(stderr);
1253+
fsync(STDOUT_FILENO);
1254+
fsync(STDERR_FILENO);
12531255
#endif
12541256
#endif
12551257

rtos/TARGET_CORTEX/TARGET_CORTEX_M/mbed_rtx_fault_handler.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include "device.h"
1919
#include "platform/mbed_error.h"
2020
#include "platform/mbed_interface.h"
21-
#include "hal/serial_api.h"
2221

2322
#ifndef MBED_FAULT_HANDLER_DISABLED
2423
#include "mbed_rtx_fault_handler.h"

0 commit comments

Comments
 (0)