From 5e9eb27ac291285543f59a145661ea048d3cb92d Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Mon, 12 Sep 2022 14:20:30 -0400 Subject: [PATCH] Implement whole-buffer write semihosting (#1013) * Implement whole-buffer write semihosting Each semihosting call is very slow, so doing it for each character does not provide an ideal developer experience. This change allows the entire buffer to be printed out in a single call. --- .../stdio_semihosting.c | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c b/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c index 4eb673f..18e90df 100644 --- a/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c +++ b/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c @@ -8,31 +8,33 @@ #include "pico/stdio_semihosting.h" #include "pico/binary_info.h" -//static void __attribute__((naked)) semihosting_puts(const char *s) { -// __asm ( -// -// "mov r1, r0\n" -// "mov r0, #4\n" -// "bkpt 0xab\n" -// "bx lr\n" -// ); -//} - -static void __attribute__((naked)) semihosting_putc(__unused const char *c) { - __asm ( - - "mov r1, r0\n" - "mov r0, #3\n" - "bkpt 0xab\n" - "bx lr\n" - ); -} - - static void stdio_semihosting_out_chars(const char *buf, int length) { - for (int i = 0; i < length; i++) { - semihosting_putc(&buf[i]); - } + // must be volatile or the buffer gets put in registers & optimized away + volatile struct { + // https://developer.arm.com/documentation/dui0375/g/What-is-Semihosting-/SYS-WRITE--0x05- + // arguments, in order: + // word 0 = file handle (1 = stdout) + // word 1 = pointer to buffer + // word 2 = length of buffer + size_t fd; + const char *buf; + size_t len; + } args; + + args.fd = 1; // 1 = stdout + args.buf = buf; + args.len = length; + + __asm ( + // r1 must contain a pointer to the arguments + "mov r1, %[args]\n" + // semihosting call number 0x05 = SYS_WRITE + "mov r0, #5\n" + // make the semihosting call: https://developer.arm.com/documentation/dui0375/g/What-is-Semihosting-/The-semihosting-interface + "bkpt 0xab\n" + : + : [args] "r" (&args) + : "r0", "r1"); } stdio_driver_t stdio_semihosting = {