Skip to content

Commit

Permalink
Change behavior to:
Browse files Browse the repository at this point in the history
1. Printf will wait up to 120ms at boot.
2. If printf has timed out, it will immediately continue.
3. If a debugger is reattached, it will keep printing.
4. If a debugger is attached, it will wait up to 120ms. Then continue at full speed.
  • Loading branch information
cnlohr committed Nov 11, 2024
1 parent a2d7c23 commit f2790f9
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 17 deletions.
41 changes: 31 additions & 10 deletions ch32v003fun/ch32v003fun.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,9 +761,12 @@ extern uint32_t * _edata;
// If you don't override a specific handler, it will just spin forever.
void DefaultIRQHandler( void )
{
#if FUNCONF_DEBUG_HARDFAULT
// Wait indefinitely for a debugger to attach.
while( !DidDebuggerAttach() );
#if FUNCONF_DEBUG_HARDFAULT && ( FUNCONF_USE_DEBUGPRINTF || FUNCONF_USE_UARTPRINTF )
#if FUNCONF_USE_DEBUGPRINTF
// Wait indefinitely for a printf to become clear.
while( !DebugPrintfBufferFree() );

#endif
printf( "DEAD MSTATUS:%08x MTVAL:%08x MCAUSE:%08x MEPC:%08x\n", (int)__get_MSTATUS(), (int)__get_MTVAL(), (int)__get_MCAUSE(), (int)__get_MEPC() );
#endif
// Infinite Loop
Expand Down Expand Up @@ -1587,7 +1590,7 @@ static void internal_handle_input( volatile uint32_t * dmdata0 )
{
uint32_t dmd0 = *dmdata0;
int bytes = (dmd0 & 0x3f) - 4;
if( bytes > 0 )
if( bytes > 0 && bytes < 16 )
{
handle_debug_input( bytes, ((uint8_t*)dmdata0) + 1 );
}
Expand All @@ -1609,14 +1612,18 @@ void poll_input( void )
// MSB .... LSB
// DMDATA0: char3 char2 char1 [status word]
// where [status word] is:
// b7 = is a "printf" waiting?
// b0..b3 = # of bytes in printf (+4). (5 or higher indicates a print of some kind)
// bit 7 = is a "printf" waiting?
// bit 6 = printf has timed out.
// bit 0..bit 3 = # of bytes in printf (+4). (5 or higher indicates a print of some kind)
// note: if b7 is 0 in reply, but b0..b3 have >=4 then we received data from host.
// Special sentinel:
// status word = 0x80 = default at start
// status word = 0xcx = timed out.
// declare as weak to allow overriding.
WEAK int _write(int fd, const char *buf, int size)
{
(void)fd;
if( !DidDebuggerAttach() ) return;
if( ( *DMDATA0 & 0xc0 ) == 0xc0 ) return 0;

char buffer[4] = { 0 };
int place = 0;
Expand All @@ -1634,7 +1641,13 @@ WEAK int _write(int fd, const char *buf, int size)
if( tosend > 7 ) tosend = 7;

while( ( lastdmd = (*DMDATA0) ) & 0x80 )
if( timeout-- == 0 ) return place;
{
if( timeout-- == 0 )
{
*DMDATA0 |= 0xc0;
return 0;
}
}

if( lastdmd ) internal_handle_input( (uint32_t*)DMDATA0 );

Expand Down Expand Up @@ -1665,16 +1678,24 @@ WEAK int _write(int fd, const char *buf, int size)
// single to debug intf
WEAK int putchar(int c)
{
if( !DidDebuggerAttach() ) return;
if( ( *DMDATA0 & 0xc0 ) == 0xc0 ) return 0;

int timeout = FUNCONF_DEBUGPRINTF_TIMEOUT;
uint32_t lastdmd = 0;

while( ( lastdmd = (*DMDATA0) ) & 0x80 )
if( timeout-- == 0 ) return 0;
{
if( timeout-- == 0 )
{
*DMDATA0 |= 0xc0;
return 0;
}
}

// Simply seeking input.
if( lastdmd ) internal_handle_input( (uint32_t*)DMDATA0 );

// Write out character.
*DMDATA0 = 0x85 | ((const char)c<<8);
return 1;
}
Expand Down
13 changes: 7 additions & 6 deletions ch32v003fun/ch32v003fun.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@
8. Default debug behavior, when semihosting:
a. You get access to DidDebuggerAttach() - so you can see if a debugger has attached.
b. WaitForDebuggerToAttach( int timeout_ms ) - if timeout_ms == 0, will wait for forever.
c. If a debugger has attached, printf will wait 120ms (configurable) to make sure it
doesn't drop data. Otherwise, printf fast-path's to exit. It will still do the string
c. printf will wait 120ms (configurable) to make sure it doesn't drop data. Otherwise,
printf will fast-path to exit after the first timeout. It will still do the string
formatting, but will not wait on output. Timeout is configured with
FUNCONF_DEBUGPRINTF_TIMEOUT
FUNCONF_DEBUGPRINTF_TIMEOUT.
d. If you hard fault, it will wait indefinitely for a debugger to attach, once attached,
will printf the fault cause, and the memory address of the fault. Space can be saved
by setting FUNCONF_DEBUG_HARDFAULT to 0.
Expand Down Expand Up @@ -14007,9 +14007,10 @@ void SetupUART( int uartBRR );
int WaitForDebuggerToAttach( int timeout_ms );

// Returns 1 if a debugger has activated the debug module.
#if defined(__riscv) || defined(__riscv__)
inline static int DidDebuggerAttach() { return !*DMSTATUS_SENTINEL; }
#endif
#define DidDebuggerAttach() (!*DMSTATUS_SENTINEL)

// Returns 1 if a debugger has activated the debug module.
#define DebugPrintfBufferFree() (!(*DMDATA0 & 0x80))

// Just a definition to the internal _write function.
int _write(int fd, const char *buf, int size);
Expand Down
2 changes: 2 additions & 0 deletions examples/debugprintfdemo/debugprintfdemo.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ int main()
{
SystemInit();

while( !DebugPrintfBufferFree() );

// Enable GPIOs
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC;

Expand Down
2 changes: 1 addition & 1 deletion examples/debugprintfdemo/funconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

// Though this should be on by default we can extra force it on.
#define FUNCONF_USE_DEBUGPRINTF 1
#define FUNCONF_DEBUGPRINTF_TIMEOUT (1<<31) // Wait for a very very long time.
//#define FUNCONF_DEBUGPRINTF_TIMEOUT (1<<31) // Optionally, wait for a very very long time on every printf.

#define CH32V003 1

Expand Down

0 comments on commit f2790f9

Please sign in to comment.