Skip to content
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
5 changes: 5 additions & 0 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -3345,6 +3345,11 @@ ifeq ($(DEBUG_UART),1)
endif
endif

# Debug RTT
ifeq ($(DEBUG_RTT),1)
CFLAGS+=-DDEBUG_RTT
endif

# UART QSPI programmer (PolarFire SoC MPFS): receive binary over UART and
# write it directly to QSPI flash. Requires EXT_FLASH=1 and DEBUG_UART=1.
# Use tools/scripts/mpfs_qspi_prog.py on the host side.
Expand Down
13 changes: 13 additions & 0 deletions docs/compile.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,19 @@ To debug the bootloader, simply compile with `DEBUG=1`. The size of the bootload
consistently, so ensure that you have enough space at the beginning of the flash before
`WOLFBOOT_PARTITION_BOOT_ADDRESS`.

### Enable SEGGER RTT logging

With Make, set `DEBUG_RTT` to the root of a checkout of [SEGGER RTT](https://github.com/SEGGERMicro/RTT), not `1`.
Provide the RTT configuration as `SEGGER_RTT_Conf.h` and add its directory to the include path:

```sh
make DEBUG_RTT=/path/to/segger_rtt DEBUG_UART=0 \
CFLAGS_EXTRA=-I/path/to/rtt_config/
```

This automatically enables `PRINTF_ENABLED` and sends `wolfBoot_printf` output to RTT up-channel 0.
`DEBUG_UART=1` takes precedence over RTT, so disable it when using RTT. Read the output with an RTT-capable debugger or viewer.

### Disable interrupt vector relocation

On some platforms, it might be convenient to avoid the interrupt vector relocation before boot-up.
Expand Down
6 changes: 3 additions & 3 deletions include/printf.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@
# include "efi/efilib.h"
/* NOTE: %s arguments will not work as EFI uses widechar string */
# define wolfBoot_printf(_f_, ...) Print(L##_f_, ##__VA_ARGS__)
# elif defined(DEBUG_UART)
# elif defined(DEBUG_UART) || defined(DEBUG_RTT)
/* use minimal printf support in string.h */
void uart_printf(const char* fmt, ...);
# define wolfBoot_printf(_f_, ...) uart_printf(_f_, ##__VA_ARGS__)
void tiny_printf(const char* fmt, ...);
# define wolfBoot_printf(_f_, ...) tiny_printf(_f_, ##__VA_ARGS__)
Comment on lines +67 to +68
# elif defined(__CCRX__)
# define wolfBoot_printf printf
# elif defined(WOLFBOOT_LOG_PRINTF)
Expand Down
8 changes: 8 additions & 0 deletions options.mk
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,14 @@ ifeq ($(DEBUG_UART),1)
endif
endif
endif

ifneq ($(strip $(DEBUG_RTT)),)
CFLAGS+=-DDEBUG_RTT
CFLAGS+=-I$(DEBUG_RTT)
CFLAGS+=-DPRINTF_ENABLED
OBJS+=$(DEBUG_RTT)/RTT/SEGGER_RTT.o
endif

# Flash erase/write/read test at WOLFBOOT_PARTITION_UPDATE_ADDRESS.
ifeq ($(TEST_FLASH),1)
CFLAGS+=-DTEST_FLASH
Expand Down
92 changes: 50 additions & 42 deletions src/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
size_t strlen(const char *s); /* forward declaration */
#endif

#ifdef DEBUG_UART
#if defined(DEBUG_UART) || defined(DEBUG_RTT)
#include "printf.h"
#ifdef PRINTF_ENABLED
#include <stdarg.h>
Expand All @@ -67,7 +67,7 @@ size_t strlen(const char *s); /* forward declaration */
/* allow using built-in libc if WOLFBOOT_USE_STDLIBC is defined */
#ifndef WOLFBOOT_USE_STDLIBC
#if !(defined(BUILD_LOADER_STAGE1) && defined(ARCH_PPC)) || \
(defined(PRINTF_ENABLED) && defined(DEBUG_UART)) \
(defined(PRINTF_ENABLED) && (defined(DEBUG_UART) || defined(DEBUG_RTT))) \
|| defined(TARGET_same51)

int islower(int c)
Expand Down Expand Up @@ -268,9 +268,9 @@ void* memchr(void const *s, int c_in, size_t n)
}
return NULL;
}
#endif /* !BUILD_LOADER_STAGE1 || (PRINTF_ENABLED && DEBUG_UART) */
#endif /* !BUILD_LOADER_STAGE1 || (PRINTF_ENABLED && (DEBUG_UART || DEBUG_RTT)) */

#if !(defined(BUILD_LOADER_STAGE1) && defined(ARCH_PPC)) || defined(DEBUG_UART)
#if !(defined(BUILD_LOADER_STAGE1) && defined(ARCH_PPC)) || defined(DEBUG_UART) || defined(DEBUG_RTT)
size_t strlen(const char *s)
{
size_t i = 0;
Expand Down Expand Up @@ -411,26 +411,36 @@ void __aeabi_memclr8(void *dst, size_t n)
#endif /* __ARM_EABI__ && !IAR */
#endif /* WOLFBOOT_USE_STDLIBC */

#if defined(PRINTF_ENABLED) && defined(DEBUG_UART)
#ifdef PRINTF_ENABLED
# if defined(DEBUG_UART)
# define write_str(buf, sz) uart_write(buf, sz)
# elif defined(DEBUG_RTT)
# include "RTT/SEGGER_RTT.h"
# define write_str(buf, sz) SEGGER_RTT_Write(0, buf, sz)
# endif
/* fail build when neither uart or rtt are defined */
#endif

#if defined(PRINTF_ENABLED) && ( defined(DEBUG_UART) || defined(DEBUG_RTT) )
/* Shared digit table -- avoids duplicating the literal in each width's
* formatting loop. */
static const char uart_writenum_digits[] = "0123456789ABCDEF";
static const char write_num_digits[] = "0123456789ABCDEF";

/* Shared tail for both widths: applies zeropad spacing, slides the digit
* run into place, and emits to UART. Caller has filled digits at the
* tail of `buf` and counted them in `sz`; `i` is the prefix length
* (sign character only). */
static void uart_writenum_emit(char *buf, int bufsize, int i, int sz,
static void write_num_emit(char *buf, int bufsize, int i, int sz,
int zeropad, int maxdigits)
{
if (zeropad && sz < maxdigits) {
i += maxdigits - sz;
}
memmove(&buf[i], &buf[bufsize - sz], sz);
uart_write(buf, i + sz);
write_str(buf, i + sz);
}

void uart_writenum(int num, int base, int zeropad, int maxdigits,
void write_num(int num, int base, int zeropad, int maxdigits,
int is_signed)
{
int i = 0, sz = 0;
Expand All @@ -454,20 +464,19 @@ void uart_writenum(int num, int base, int zeropad, int maxdigits,
/* 32-bit divide: stays out of libgcc 64-bit helpers, which aren't
* linked into freestanding stage1 / Cortex-M builds. */
do {
buf[sizeof(buf) - sz - 1] =
uart_writenum_digits[(val % (unsigned)base)];
buf[sizeof(buf) - sz - 1] = write_num_digits[(val % (unsigned)base)];
sz++;
val /= (unsigned)base;
} while (val > 0U);
uart_writenum_emit(buf, sizeof(buf), i, sz, zeropad, maxdigits);
write_num_emit(buf, sizeof(buf), i, sz, zeropad, maxdigits);
}

#ifdef PRINTF_LONG_LONG
/* 64-bit core for %llu/%lld/%llx. Pulls in libgcc 64-bit divide
* (__udivmoddi4 / __aeabi_uldivmod) so it's only compiled when needed
* and only called from the long-long printf paths -- never from the
* 32-bit uart_writenum() fast path above. */
static void uart_writenum_ll(unsigned long long val, int is_negative,
* 32-bit write_num() fast path above. */
static void write_num_ll(unsigned long long val, int is_negative,
int base, int zeropad, int maxdigits)
{
int i = 0, sz = 0;
Expand All @@ -486,23 +495,22 @@ static void uart_writenum_ll(unsigned long long val, int is_negative,
memset(&buf[i], '0', maxdigits);
}
do {
buf[sizeof(buf) - sz - 1] =
uart_writenum_digits[(val % (unsigned)base)];
buf[sizeof(buf) - sz - 1] = write_num_digits[(val % (unsigned)base)];
sz++;
val /= (unsigned)base;
} while (val > 0ULL);
uart_writenum_emit(buf, sizeof(buf), i, sz, zeropad, maxdigits);
write_num_emit(buf, sizeof(buf), i, sz, zeropad, maxdigits);
}
#endif /* PRINTF_LONG_LONG */

void uart_vprintf(const char* fmt, va_list argp)
void tiny_vprintf(const char* fmt, va_list argp)
{
char* fmtp = (char*)fmt;
int zeropad, maxdigits, precision, leftjust, islong, iszl;
while (fmtp != NULL && *fmtp != '\0') {
/* print non formatting characters */
if (*fmtp != '%') {
uart_write(fmtp++, 1);
write_str(fmtp++, 1);
continue;
}
fmtp++; /* skip % */
Expand Down Expand Up @@ -565,7 +573,7 @@ void uart_vprintf(const char* fmt, va_list argp)

switch (*fmtp) {
case '%':
uart_write(fmtp, 1);
write_str(fmtp, 1);
break;
case 'u':
case 'i':
Expand All @@ -591,7 +599,7 @@ void uart_vprintf(const char* fmt, va_list argp)
else {
val = va_arg(argp, unsigned long long);
}
uart_writenum_ll(val, is_neg, 10, zeropad, maxdigits);
write_num_ll(val, is_neg, 10, zeropad, maxdigits);
}
else if (islong == 1 || iszl) {
/* %ld / %lu / %zd / %zu: long is 64-bit here */
Expand All @@ -611,25 +619,25 @@ void uart_vprintf(const char* fmt, va_list argp)
val = (unsigned long long)va_arg(argp,
unsigned long);
}
uart_writenum_ll(val, is_neg, 10, zeropad, maxdigits);
write_num_ll(val, is_neg, 10, zeropad, maxdigits);
}
else
#endif
{
int n;
if (*fmtp == 'u') {
n = (int)va_arg(argp, unsigned int);
uart_writenum(n, 10, zeropad, maxdigits, 0);
write_num(n, 10, zeropad, maxdigits, 0);
}
else {
n = (int)va_arg(argp, int);
uart_writenum(n, 10, zeropad, maxdigits, 1);
write_num(n, 10, zeropad, maxdigits, 1);
}
}
break;
}
case 'p':
uart_write("0x", 2);
write_str("0x", 2);
/* fall through */
case 'x':
case 'X':
Expand All @@ -639,7 +647,7 @@ void uart_vprintf(const char* fmt, va_list argp)
/* %llx: full 64-bit value */
unsigned long long val =
va_arg(argp, unsigned long long);
uart_writenum_ll(val, 0, 16, zeropad, maxdigits);
write_num_ll(val, 0, 16, zeropad, maxdigits);
}
else if (islong == 1 || iszl || *fmtp == 'p') {
/* %lx / %zx / %p: consume at the type's natural width
Expand All @@ -653,7 +661,7 @@ void uart_vprintf(const char* fmt, va_list argp)
val = (unsigned long long)va_arg(argp,
unsigned long);
}
uart_writenum_ll(val, 0, 16, zeropad, maxdigits);
write_num_ll(val, 0, 16, zeropad, maxdigits);
}
else
#endif
Expand All @@ -665,7 +673,7 @@ void uart_vprintf(const char* fmt, va_list argp)
else {
n = (int)va_arg(argp, int);
}
uart_writenum(n, 16, zeropad, maxdigits, 0);
write_num(n, 16, zeropad, maxdigits, 0);
}
break;
}
Expand All @@ -674,27 +682,27 @@ void uart_vprintf(const char* fmt, va_list argp)
char* str = (char*)va_arg(argp, char*);
int slen = (int)strlen(str);
if (leftjust) {
uart_write(str, slen);
write_str(str, slen);
while (slen < maxdigits) {
uart_write(" ", 1);
write_str(" ", 1);
slen++;
}
} else {
while (slen < maxdigits) {
uart_write(" ", 1);
write_str(" ", 1);
slen++;
}
uart_write(str, (uint32_t)strlen(str));
write_str(str, (uint32_t)strlen(str));
}
break;
}
case 'c':
{
char c = (char)va_arg(argp, int);
uart_write(&c, 1);
write_str(&c, 1);
break;
}
#ifdef UART_PRINTF_FLOAT
#ifdef PRINTF_FLOAT
case 'f':
case 'e':
case 'g':
Expand All @@ -706,43 +714,43 @@ void uart_vprintf(const char* fmt, va_list argp)

/* handle negative */
if (val < 0.0) {
uart_write("-", 1);
write_str("-", 1);
val = -val;
}

/* integer part */
ipart = (unsigned int)val;
uart_writenum((int)ipart, 10, 0, 0, 0);
write_num((int)ipart, 10, 0, 0, 0);

/* fractional part */
if (prec > 0) {
double frac = val - (double)ipart;
char c;
int i;
uart_write(".", 1);
write_str(".", 1);
for (i = 0; i < prec; i++) {
frac *= 10.0;
digit = (int)frac;
if (digit > 9) digit = 9;
c = '0' + digit;
uart_write(&c, 1);
write_str(&c, 1);
frac -= (double)digit;
}
}
break;
}
#endif /* UART_PRINTF_FLOAT */
#endif /* PRINTF_FLOAT */
default:
break;
}
fmtp++;
};
}
void uart_printf(const char* fmt, ...)
void tiny_printf(const char* fmt, ...)
{
va_list argp;
va_start(argp, fmt);
uart_vprintf(fmt, argp);
tiny_vprintf(fmt, argp);
va_end(argp);
}
#endif /* PRINTF_ENABLED && DEBUG_UART */
#endif /* PRINTF_ENABLED && ( DEBUG_UART || DEBUG_RTT ) */
8 changes: 6 additions & 2 deletions test-app/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,16 @@ endif
ifeq ($(WOLFCRYPT_BENCHMARK),1)
CFLAGS+=-DWOLFCRYPT_BENCHMARK
WOLFCRYPT_SUPPORT=1
UART_PRINTF_FLOAT?=1
PRINTF_FLOAT?=1
APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/benchmark/benchmark.o
endif

ifeq ($(UART_PRINTF_FLOAT),1)
CFLAGS+=-DUART_PRINTF_FLOAT
CFLAGS+=-DPRINTF_FLOAT
endif

ifeq ($(RTT_PRINTF_FLOAT),1)
CFLAGS+=-DPRINTF_FLOAT
endif

ifeq ($(WOLFCRYPT_SUPPORT),1)
Expand Down
4 changes: 2 additions & 2 deletions test-app/syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ static int ___vsnprintf(char *buf, unsigned int size, const char *fmt, va_list a
if (pos < (int)size - 1)
buf[pos++] = (char)va_arg(argp, int);
break;
#ifdef UART_PRINTF_FLOAT
#ifdef PRINTF_FLOAT
case 'f': case 'e': case 'g':
{
double val = va_arg(argp, double);
Expand Down Expand Up @@ -368,7 +368,7 @@ static int ___vsnprintf(char *buf, unsigned int size, const char *fmt, va_list a
}
break;
}
#endif /* UART_PRINTF_FLOAT */
#endif /* PRINTF_FLOAT */
default:
break;
}
Expand Down
Loading