Implement semihosting debug output redirection to usb-uart port.
This commit is contained in:
parent
c7b54d2eaa
commit
3e9913e88b
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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))"
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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... */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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... */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue