Implement semihosting debug output redirection to usb-uart port.

This commit is contained in:
Anti Sullin 2018-03-26 20:53:06 +03:00 committed by Piotr Esden-Tempski
parent c7b54d2eaa
commit 3e9913e88b
11 changed files with 76 additions and 6 deletions

View File

@ -74,6 +74,8 @@ enum BMP_DEBUG {
# define DEBUG_PROBE(...) do {} while(0) # define DEBUG_PROBE(...) do {} while(0)
# define DEBUG_WIRE(...) do {} while(0) # define DEBUG_WIRE(...) do {} while(0)
# define DEBUG_GDB_WIRE(...) do {} while(0) # define DEBUG_GDB_WIRE(...) do {} while(0)
void usbuart_send_stdout(const uint8_t *data, uint32_t len);
#else #else
# include <stdarg.h> # include <stdarg.h>
extern int cl_debuglevel; extern int cl_debuglevel;
@ -171,4 +173,3 @@ static inline void DEBUG_WIRE(const char *format, ...)
#define MORSECNT ((SYSTICKHZ / 10) - 1) #define MORSECNT ((SYSTICKHZ / 10) - 1)
#endif #endif

View File

@ -31,6 +31,7 @@
#include <setjmp.h> #include <setjmp.h>
#define PLATFORM_HAS_USBUART
#define PLATFORM_HAS_TRACESWO #define PLATFORM_HAS_TRACESWO
#define PLATFORM_IDENT " (HydraBus))" #define PLATFORM_IDENT " (HydraBus))"

View File

@ -22,6 +22,7 @@
#include "timing.h" #include "timing.h"
#define PLATFORM_HAS_USBUART
#define PLATFORM_IDENT "(Launchpad ICDI) " #define PLATFORM_IDENT "(Launchpad ICDI) "
extern uint8_t running_status; extern uint8_t running_status;

View File

@ -30,6 +30,7 @@
#define PLATFORM_HAS_TRACESWO #define PLATFORM_HAS_TRACESWO
#define PLATFORM_HAS_POWER_SWITCH #define PLATFORM_HAS_POWER_SWITCH
#define PLATFORM_HAS_USBUART
#ifdef ENABLE_DEBUG #ifdef ENABLE_DEBUG
# define PLATFORM_HAS_DEBUG # define PLATFORM_HAS_DEBUG

View File

@ -39,6 +39,7 @@ extern bool debug_bmp;
int usbuart_debug_write(const char *buf, size_t len); int usbuart_debug_write(const char *buf, size_t len);
#endif #endif
#define PLATFORM_HAS_USBUART
#define PLATFORM_IDENT "(STLINK/V2) " #define PLATFORM_IDENT "(STLINK/V2) "
/* Hardware definitions... */ /* Hardware definitions... */

View File

@ -192,6 +192,20 @@ void usbuart_init(void)
usart_enable_rx_dma(USBUSART); usart_enable_rx_dma(USBUSART);
} }
void usbuart_send_stdout(const uint8_t *data, uint32_t len)
{
while (len) {
uint32_t cnt = CDCACM_PACKET_SIZE;
if (cnt > len)
cnt = len;
nvic_disable_irq(USB_IRQ);
cnt = usbd_ep_write_packet(usbdev, CDCACM_UART_ENDPOINT, data, cnt);
nvic_enable_irq(USB_IRQ);
data += cnt;
len -= cnt;
}
}
void usbuart_set_line_coding(struct usb_cdc_line_coding *coding) void usbuart_set_line_coding(struct usb_cdc_line_coding *coding)
{ {
usart_set_baudrate(USBUSART, coding->dwDTERate); usart_set_baudrate(USBUSART, coding->dwDTERate);

View File

@ -36,6 +36,7 @@ extern bool debug_bmp;
int usbuart_debug_write(const char *buf, size_t len); int usbuart_debug_write(const char *buf, size_t len);
#endif #endif
#define PLATFORM_HAS_USBUART
#define PLATFORM_IDENT "(SWLINK) " #define PLATFORM_IDENT "(SWLINK) "
/* Hardware definitions... */ /* Hardware definitions... */

View File

@ -73,6 +73,20 @@ void usbuart_init(void)
nvic_enable_irq(USBUART_IRQ); nvic_enable_irq(USBUART_IRQ);
} }
void usbuart_send_stdout(const uint8_t *data, uint32_t len)
{
while (len) {
uint32_t cnt = CDCACM_PACKET_SIZE;
if (cnt > len)
cnt = len;
nvic_disable_irq(USBUART_IRQ);
cnt = usbd_ep_write_packet(usbdev, CDCACM_UART_ENDPOINT, data, cnt);
nvic_enable_irq(USBUART_IRQ);
data += cnt;
len -= cnt;
}
}
void usbuart_set_line_coding(struct usb_cdc_line_coding *coding) void usbuart_set_line_coding(struct usb_cdc_line_coding *coding)
{ {
uart_set_baudrate(USBUART, coding->dwDTERate); uart_set_baudrate(USBUART, coding->dwDTERate);
@ -180,4 +194,3 @@ void USBUART_ISR(void)
buf_rx_out %= FIFO_SIZE; buf_rx_out %= FIFO_SIZE;
} }
} }

View File

@ -58,9 +58,15 @@
static const char cortexm_driver_str[] = "ARM Cortex-M"; static const char cortexm_driver_str[] = "ARM Cortex-M";
static bool cortexm_vector_catch(target *t, int argc, char *argv[]); static bool cortexm_vector_catch(target *t, int argc, char *argv[]);
#ifdef PLATFORM_HAS_USBUART
static bool cortexm_redirect_stdout(target *t, int argc, const char **argv);
#endif
const struct command_s cortexm_cmd_list[] = { const struct command_s cortexm_cmd_list[] = {
{"vector_catch", (cmd_handler)cortexm_vector_catch, "Catch exception vectors"}, {"vector_catch", (cmd_handler)cortexm_vector_catch, "Catch exception vectors"},
#ifdef PLATFORM_HAS_USBUART
{"redirect_stdout", (cmd_handler)cortexm_redirect_stdout, "Redirect semihosting stdout to USB UART"},
#endif
{NULL, NULL, NULL} {NULL, NULL, NULL}
}; };
@ -1207,6 +1213,17 @@ static bool cortexm_vector_catch(target *t, int argc, char *argv[])
#define SYS_WRITEC 0x03 #define SYS_WRITEC 0x03
#define SYS_WRITE0 0x04 #define SYS_WRITE0 0x04
#ifdef PLATFORM_HAS_USBUART
static bool cortexm_redirect_stdout(target *t, int argc, const char **argv)
{
if (argc == 1)
gdb_outf("Semihosting stdout redirection: %s\n", t->stdout_redirected ? "enabled" : "disabled");
else
t->stdout_redirected = !strncmp(argv[1], "enable", strlen(argv[1]));
return true;
}
#endif
#if PC_HOSTED == 0 #if PC_HOSTED == 0
/* probe memory access functions */ /* probe memory access functions */
static void probe_mem_read(target *t __attribute__((unused)), void *probe_dest, target_addr target_src, size_t len) static void probe_mem_read(target *t __attribute__((unused)), void *probe_dest, target_addr target_src, size_t len)
@ -1216,7 +1233,6 @@ static void probe_mem_read(target *t __attribute__((unused)), void *probe_dest,
DEBUG_INFO("probe_mem_read\n"); DEBUG_INFO("probe_mem_read\n");
while (len--) *dst++=*src++; while (len--) *dst++=*src++;
return;
} }
static void probe_mem_write(target *t __attribute__((unused)), target_addr target_dest, const void *probe_src, size_t len) static void probe_mem_write(target *t __attribute__((unused)), target_addr target_dest, const void *probe_src, size_t len)
@ -1226,7 +1242,6 @@ static void probe_mem_write(target *t __attribute__((unused)), target_addr targe
DEBUG_INFO("probe_mem_write\n"); DEBUG_INFO("probe_mem_write\n");
while (len--) *dst++=*src++; while (len--) *dst++=*src++;
return;
} }
#endif #endif

View File

@ -22,9 +22,12 @@
#include "target_internal.h" #include "target_internal.h"
#include <stdarg.h> #include <stdarg.h>
#include <unistd.h>
target *target_list = NULL; target *target_list = NULL;
#define STDOUT_READ_BUF_SIZE 64
static int target_flash_write_buffered(struct target_flash *f, static int target_flash_write_buffered(struct target_flash *f,
target_addr dest, const void *src, size_t len); target_addr dest, const void *src, size_t len);
static int target_flash_done_buffered(struct target_flash *f); static int target_flash_done_buffered(struct target_flash *f);
@ -630,6 +633,22 @@ int tc_read(target *t, int fd, target_addr buf, unsigned int count)
int tc_write(target *t, int fd, target_addr buf, unsigned int count) int tc_write(target *t, int fd, target_addr buf, unsigned int count)
{ {
#ifdef PLATFORM_HAS_USBUART
if (t->stdout_redirected && (fd == STDOUT_FILENO || fd == STDERR_FILENO)) {
while (count) {
uint8_t tmp[STDOUT_READ_BUF_SIZE];
unsigned int cnt = sizeof(tmp);
if (cnt > count)
cnt = count;
target_mem_read(t, tmp, buf, cnt);
usbuart_send_stdout(tmp, cnt);
count -= cnt;
buf += cnt;
}
return 0;
}
#endif
if (t->tc->write == NULL) if (t->tc->write == NULL)
return 0; return 0;
return t->tc->write(t->tc, fd, buf, count); return t->tc->write(t->tc, fd, buf, count);

View File

@ -129,6 +129,9 @@ struct target_s {
char cmdline[MAX_CMDLINE]; char cmdline[MAX_CMDLINE];
target_addr heapinfo[4]; target_addr heapinfo[4];
struct target_command_s *commands; struct target_command_s *commands;
#ifdef PLATFORM_HAS_USBUART
bool stdout_redirected;
#endif
struct target_s *next; struct target_s *next;