mbed_error_puts: Prime STDERR_FILENO before writing

Prime the console outside the critical section, improving the chances of
nice initialisation.
pull/10358/head
Kevin Bracey 2019-04-09 16:07:51 +03:00
parent f2a13a85a1
commit aa0e86475c
2 changed files with 35 additions and 3 deletions

View File

@ -74,6 +74,28 @@ void mbed_error_vprintf(const char *format, va_list arg)
void mbed_error_puts(const char *str) void mbed_error_puts(const char *str)
{ {
// Writing the string to the console in a critical section is
// potentially beneficial - for example in UARTSerial it
// forces the "unbuffered" mode that makes sure all characters
// go out now. If we made the call not in a critical section,
// it would go to the software buffer and we would be reliant
// on platform.stdio-flush-at-exit forcing a fsync before
// entering mbed_die().
//
// But this may be the very first write to the console, and hence
// require it to be initialized - doing this in a critical
// section could be problematic. So we prime it outside the
// critical section with a zero-length write - this forces
// the initialization.
//
// It's still possible that we were in a critical section
// or interrupt on entry anyway (eg if this is an error coming
// from inside RTX), so in other areas of the system we suppress
// things like mutex creation asserts and RTX traps while
// an error is in progress, so that console initialization
// may work.
write(STDERR_FILENO, str, 0);
core_util_critical_section_enter(); core_util_critical_section_enter();
#if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES || MBED_CONF_PLATFORM_STDIO_CONVERT_TTY_NEWLINES #if MBED_CONF_PLATFORM_STDIO_CONVERT_NEWLINES || MBED_CONF_PLATFORM_STDIO_CONVERT_TTY_NEWLINES
char stdio_out_prev = '\0'; char stdio_out_prev = '\0';

View File

@ -127,7 +127,9 @@ MBED_NORETURN void mbed_die(void);
/** Print out an error message. This is typically called when /** Print out an error message. This is typically called when
* handling a crash. * handling a crash.
* *
* @note Synchronization level: Interrupt safe * @note Synchronization level: Interrupt safe, as long as the
* FileHandle::write of the stderr device is. See mbed_error_puts
* for more information.
* @note This uses an internal 128-byte buffer to format the string, * @note This uses an internal 128-byte buffer to format the string,
* so the output may be truncated. If you need to write a potentially * so the output may be truncated. If you need to write a potentially
* long string, use mbed_error_puts. * long string, use mbed_error_puts.
@ -145,7 +147,9 @@ void mbed_error_printf(const char *format, ...) MBED_PRINTF(1, 2);
/** Print out an error message. Similar to mbed_error_printf /** Print out an error message. Similar to mbed_error_printf
* but uses a va_list. * but uses a va_list.
* *
* @note Synchronization level: Interrupt safe * @note Synchronization level: Interrupt safe, as long as the
* FileHandle::write of the stderr device is. See mbed_error_puts
* for more information.
* *
* @param format C string that contains data stream to be printed. * @param format C string that contains data stream to be printed.
* @param arg Variable arguments list * @param arg Variable arguments list
@ -160,7 +164,13 @@ void mbed_error_vprintf(const char *format, va_list arg) MBED_PRINTF(1, 0);
* length. Unlike standard puts, but like standard fputs, this does not * length. Unlike standard puts, but like standard fputs, this does not
* append a '\n' character. * append a '\n' character.
* *
* @note Synchronization level: Interrupt safe * @note Synchronization level: Interrupt safe, as long as the
* FileHandle::write of the stderr device is. The default
* serial console is safe, either buffered or not. If the
* console has not previously been initialized, an attempt
* to use this from interrupt may during console initialization.
* Special handling of `mbed_error` relaxes various system traps
* to increase the chance of initialization working.
* *
* @param str C string that contains data stream to be printed. * @param str C string that contains data stream to be printed.
* *