add synchronous UART transmission and use it in exceptions

The default ISR (particularly the HardFault handler) print information,
but this information was not displayed on the console because the UART
IRQ is lower than some default blocking IRQ.
Allowing to set synchronous transfer corrects this.

The underlying Atmel exception library had to be modified to use the
synchronous output.

Making UART_PutChar always synchronous when called from an ISR is not
desired because we use TRACE_ macros is some ISR. The synchronous
output must be set explicitly.

Change-Id: I1b4ace5185cf2dc32684934ed12bf6a8682e9bad
This commit is contained in:
Kévin Redon
2018-08-02 15:02:05 +02:00
parent dd36d9b010
commit 1836ac0761
6 changed files with 108 additions and 9 deletions

View File

@@ -2,6 +2,7 @@
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2008, Atmel Corporation
* Copyright (c) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
*
* All rights reserved.
*
@@ -435,6 +436,32 @@ signed int vfprintf(FILE *pStream, const char *pFormat, va_list ap)
return fputs(pStr, pStream);
}
//------------------------------------------------------------------------------
/// Outputs a formatted string on the given stream. Format arguments are given
/// in a va_list instance.
/// \note This function is synchronous (i.e. blocks until the print completes)
/// \param pStream Output stream.
/// \param pFormat Format string
/// \param ap Argument list.
//------------------------------------------------------------------------------
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
signed int vfprintf_sync(FILE *pStream, const char *pFormat, va_list ap)
{
char pStr[MAX_STRING_SIZE];
char pError[] = "stdio.c: increase MAX_STRING_SIZE\n\r";
// Write formatted string in buffer
if (vsprintf(pStr, pFormat, ap) >= MAX_STRING_SIZE) {
fputs_sync(pError, stderr);
}
// Display string
return fputs_sync(pStr, pStream);
}
#pragma GCC diagnostic pop
//------------------------------------------------------------------------------
/// Outputs a formatted string on the DBGU stream. Format arguments are given
/// in a va_list instance.
@@ -446,6 +473,18 @@ signed int vprintf(const char *pFormat, va_list ap)
return vfprintf(stdout, pFormat, ap);
}
//------------------------------------------------------------------------------
/// Outputs a formatted string on the DBGU stream. Format arguments are given
/// in a va_list instance.
/// \note This function is synchronous (i.e. blocks until the print completes)
/// \param pFormat Format string
/// \param ap Argument list.
//------------------------------------------------------------------------------
signed int vprintf_sync(const char *pFormat, va_list ap)
{
return vfprintf_sync(stdout, pFormat, ap);
}
//------------------------------------------------------------------------------
/// Outputs a formatted string on the given stream, using a variable number of
/// arguments.
@@ -483,6 +522,25 @@ signed int printf(const char *pFormat, ...)
return result;
}
//------------------------------------------------------------------------------
/// Outputs a formatted string on the DBGU stream, using a variable number of
/// arguments.
/// \note This function is synchronous (i.e. blocks until the print completes)
/// \param pFormat Format string.
//------------------------------------------------------------------------------
signed int printf_sync(const char *pFormat, ...)
{
va_list ap;
signed int result;
// Forward call to vprintf
va_start(ap, pFormat);
result = vprintf_sync(pFormat, ap);
va_end(ap);
return result;
}
//------------------------------------------------------------------------------
/// Writes a formatted string inside another string.
/// \param pStr Storage string.