Browse Source

serial console mostly working, but still losing some bytes when transmitting lots.

Thomas Buck 10 months ago
parent
commit
46f9c9a5da
13 changed files with 98 additions and 32 deletions
  1. 2
    1
      README.md
  2. 5
    2
      debug_swd.sh
  3. 3
    1
      flash_swd.sh
  4. 1
    1
      include/console.h
  5. 1
    1
      include/log.h
  6. 3
    0
      include/ring.h
  7. 1
    0
      include/serial.h
  8. 5
    2
      src/console.c
  9. 3
    1
      src/log.c
  10. 2
    0
      src/main.c
  11. 16
    0
      src/ring.c
  12. 54
    21
      src/serial.c
  13. 2
    2
      src/usb_cdc.c

+ 2
- 1
README.md View File

@@ -101,7 +101,8 @@ And also start a GDB debugging session.
101 101
     continue # start program
102 102
 
103 103
 These commands have also been put in the `flash_swd.sh` and `debug_swd.sh` scripts, respectively.
104
-Call them from the `build_debug` folder where you checked out and built OpenOCD.
104
+They require the `build_debug` folder where you checked out and built OpenOCD.
105
+Here are some [general GDB tips](https://beej.us/guide/bggdb/).
105 106
 
106 107
 ## License
107 108
 

+ 5
- 2
debug_swd.sh View File

@@ -1,8 +1,11 @@
1 1
 #!/bin/bash
2 2
 set -euo pipefail
3 3
 
4
+cd "$(dirname "$0")"
5
+
4 6
 echo Starting OpenOCD in background
5
-./openocd/src/openocd -s openocd/tcl -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "cmsis_dap_vid_pid 0x2e8a 0x000c" &
7
+echo "\n\nstarting new openocd" >> openocd.log
8
+./build_debug/openocd/src/openocd -s build_debug/openocd/tcl -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "cmsis_dap_vid_pid 0x2e8a 0x000c" >> openocd.log 2>&1 &
6 9
 OPENOCD_PID=$!
7 10
 
8 11
 # give OpenOCD some time to output stuff
@@ -19,7 +22,7 @@ arm-none-eabi-gdb \
19 22
 -ex "set history save" \
20 23
 -ex "show print pretty" \
21 24
 -ex "target extended-remote localhost:3333" \
22
--ex "tui new-layout default asm 1 src 2 status 0 cmd 1" \
25
+-ex "tui new-layout default src 1 status 1 cmd 2" \
23 26
 -ex "tui layout default" \
24 27
 -ex "tui enable" \
25 28
 $1

+ 3
- 1
flash_swd.sh View File

@@ -1,4 +1,6 @@
1 1
 #!/bin/bash
2 2
 set -euo pipefail
3 3
 
4
-./openocd/src/openocd -s openocd/tcl -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "cmsis_dap_vid_pid 0x2e8a 0x000c" -c "program $1 verify reset exit"
4
+cd "$(dirname "$0")"
5
+
6
+./build_debug/openocd/src/openocd -s build_debug/openocd/tcl -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "cmsis_dap_vid_pid 0x2e8a 0x000c" -c "program $1 verify reset exit"

+ 1
- 1
include/console.h View File

@@ -21,6 +21,6 @@
21 21
 
22 22
 void cnsl_init(void);
23 23
 void cnsl_run(void);
24
-void cnsl_handle_input(const char *buf, uint32_t len);
24
+void cnsl_handle_input(const uint8_t *buf, size_t len);
25 25
 
26 26
 #endif // __CONSOLE_H__

+ 1
- 1
include/log.h View File

@@ -43,6 +43,6 @@ void log_dump_to_usb(void);
43 43
 void log_dump_to_uart(void);
44 44
 void log_dump_to_disk(void);
45 45
 
46
-void debug_handle_input(char *buff, uint32_t len);
46
+void debug_handle_input(const uint8_t *buff, size_t len);
47 47
 
48 48
 #endif // __LOG_H__

+ 3
- 0
include/ring.h View File

@@ -32,9 +32,12 @@ struct ring_buffer {
32 32
 #define RB_INIT(b, s) { .buffer = b, .size = s, .head = 0, .tail = 0, .full = false }
33 33
 
34 34
 void rb_add(struct ring_buffer *rb, const uint8_t *data, size_t length);
35
+#define rb_push(rb, v) rb_add(rb, &v, 1)
35 36
 size_t rb_len(struct ring_buffer *rb);
36 37
 #define rb_space(rb) ((rb)->size - rb_len(rb))
37 38
 void rb_dump(struct ring_buffer *rb, void (*write)(const uint8_t *, size_t));
39
+void rb_move(struct ring_buffer *rb, void (*write)(const uint8_t *, size_t));
40
+uint8_t rb_peek(struct ring_buffer *rb);
38 41
 uint8_t rb_pop(struct ring_buffer *rb);
39 42
 
40 43
 #endif // __RING_BUFFER_H__

+ 1
- 0
include/serial.h View File

@@ -26,5 +26,6 @@
26 26
 void serial_init(void);
27 27
 void serial_write(const uint8_t *buf, size_t count);
28 28
 void serial_set_reroute(bool reroute);
29
+void serial_run(void);
29 30
 
30 31
 #endif // __SERIAL_H__

+ 5
- 2
src/console.c View File

@@ -35,6 +35,7 @@
35 35
 #include "lcd.h"
36 36
 #include "image.h"
37 37
 #include "volcano.h"
38
+#include "serial.h"
38 39
 
39 40
 #define CNSL_BUFF_SIZE 1024
40 41
 #define CNSL_REPEAT_MS 500
@@ -303,7 +304,7 @@ void cnsl_run(void) {
303 304
     }
304 305
 }
305 306
 
306
-void cnsl_handle_input(const char *buf, uint32_t len) {
307
+void cnsl_handle_input(const uint8_t *buf, size_t len) {
307 308
     if ((cnsl_buff_pos + len) > CNSL_BUFF_SIZE) {
308 309
         debug("error: console input buffer overflow! %lu > %u", cnsl_buff_pos + len, CNSL_BUFF_SIZE);
309 310
         cnsl_init();
@@ -312,7 +313,7 @@ void cnsl_handle_input(const char *buf, uint32_t len) {
312 313
     memcpy(cnsl_line_buff + cnsl_buff_pos, buf, len);
313 314
     cnsl_buff_pos += len;
314 315
 
315
-    // handle backspace
316
+    // handle backspace and local echo
316 317
     for (ssize_t i = cnsl_buff_pos - len; i < (ssize_t)cnsl_buff_pos; i++) {
317 318
         if ((cnsl_line_buff[i] == '\b') || (cnsl_line_buff[i] == 0x7F)) {
318 319
             if (i > 0) {
@@ -330,11 +331,13 @@ void cnsl_handle_input(const char *buf, uint32_t len) {
330 331
             }
331 332
 
332 333
             usb_cdc_write((const uint8_t *)"\b \b", 3);
334
+            serial_write((const uint8_t *)"\b \b", 3);
333 335
 
334 336
             // check for another backspace in this space
335 337
             i--;
336 338
         } else {
337 339
             usb_cdc_write((const uint8_t *)(cnsl_line_buff + i), 1);
340
+            serial_write((const uint8_t *)(cnsl_line_buff + i), 1);
338 341
         }
339 342
     }
340 343
 

+ 3
- 1
src/log.c View File

@@ -100,6 +100,7 @@ void debug_log_va(bool log, const char *format, va_list args) {
100 100
     }
101 101
     if ((l > 0) && (l <= (int)sizeof(line_buff))) {
102 102
         usb_cdc_write(line_buff, l);
103
+        serial_write(line_buff, l);
103 104
 
104 105
         if (log) {
105 106
             add_to_log(line_buff, l);
@@ -114,7 +115,7 @@ void debug_log(bool log, const char* format, ...) {
114 115
     va_end(args);
115 116
 }
116 117
 
117
-void debug_handle_input(char *buff, uint32_t len) {
118
+void debug_handle_input(const uint8_t *buff, size_t len) {
118 119
     (void)buff;
119 120
 
120 121
     if (len > 0) {
@@ -135,6 +136,7 @@ void debug_wait_input(const char *format, ...) {
135 136
     while (!got_input) {
136 137
         watchdog_update();
137 138
         usb_run();
139
+        serial_run();
138 140
     }
139 141
 
140 142
     usb_cdc_set_reroute(false);

+ 2
- 0
src/main.c View File

@@ -95,7 +95,9 @@ int main(void) {
95 95
 
96 96
         heartbeat_run();
97 97
         buttons_run();
98
+
98 99
         usb_run();
100
+        serial_run();
99 101
         cnsl_run();
100 102
 
101 103
         battery_run();

+ 16
- 0
src/ring.c View File

@@ -62,6 +62,22 @@ void rb_dump(struct ring_buffer *rb, void (*write)(const uint8_t *, size_t)) {
62 62
     }
63 63
 }
64 64
 
65
+void rb_move(struct ring_buffer *rb, void (*write)(const uint8_t *, size_t)) {
66
+    rb_dump(rb, write);
67
+    rb->head = 0;
68
+    rb->tail = 0;
69
+    rb->full = false;
70
+}
71
+
72
+uint8_t rb_peek(struct ring_buffer *rb) {
73
+    if (rb_len(rb) == 0) {
74
+        return 0;
75
+    }
76
+
77
+    uint8_t v = rb->buffer[rb->tail];
78
+    return v;
79
+}
80
+
65 81
 uint8_t rb_pop(struct ring_buffer *rb) {
66 82
     if (rb_len(rb) == 0) {
67 83
         return 0;

+ 54
- 21
src/serial.c View File

@@ -1,6 +1,9 @@
1 1
 /*
2 2
  * serial.c
3 3
  *
4
+ * https://github.com/raspberrypi/pico-examples/blob/master/uart/uart_advanced/uart_advanced.c
5
+ * https://forums.raspberrypi.com/viewtopic.php?t=343110
6
+ *
4 7
  * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5 8
  *
6 9
  * This program is free software: you can redistribute it and/or modify
@@ -28,7 +31,7 @@
28 31
 #define PARITY UART_PARITY_NONE
29 32
 #define STOP_BITS 1
30 33
 
31
-#define UART_HW_FIFO_LEN 32
34
+#define UART_RX_BUFF_LEN 64
32 35
 #define UART_TX_BUFF_LEN 128
33 36
 
34 37
 #include "hardware/uart.h"
@@ -41,37 +44,33 @@
41 44
 #include "ring.h"
42 45
 #include "serial.h"
43 46
 
47
+static uint8_t rx_buff[UART_RX_BUFF_LEN] = {0};
48
+static struct ring_buffer rx = RB_INIT(rx_buff, sizeof(rx_buff));
49
+
44 50
 static uint8_t tx_buff[UART_TX_BUFF_LEN] = {0};
45 51
 static struct ring_buffer tx = RB_INIT(tx_buff, sizeof(tx_buff));
52
+
46 53
 static bool reroute_serial_debug = false;
54
+static bool tx_irq_state = false;
47 55
 
48 56
 static void serial_irq(void) {
49
-    uint8_t buf[UART_HW_FIFO_LEN];
50
-    uint16_t count = 0;
51
-
52 57
     // Rx - read from UART FIFO to local buffer
53
-    while (uart_is_readable(UART_ID)) {
58
+    while (uart_is_readable(UART_ID) && (rb_space(&rx) > 0)) {
54 59
         uint8_t ch = uart_getc(UART_ID);
55
-        buf[count++] = ch;
60
+        rb_push(&rx, ch);
61
+    }
56 62
 
57
-        if (count >= UART_HW_FIFO_LEN) {
63
+    // Tx - write to UART FIFO if needed
64
+    while (uart_is_writable(UART_ID)) {
65
+        if (rb_len(&tx) > 0) {
66
+            uart_putc_raw(UART_ID, rb_pop(&tx));
67
+        } else {
68
+            uart_set_irq_enables(UART_ID, true, false);
69
+            tx_irq_state = false;
58 70
             break;
59 71
         }
60 72
     }
61 73
 
62
-    // Rx - pass local buffer to further processing
63
-    if ((count >= 1) && (buf[0] == ENTER_BOOTLOADER_MAGIC)) {
64
-        reset_to_bootloader();
65
-    } else if (reroute_serial_debug) {
66
-        debug_handle_input((char *)buf, count);
67
-    } else {
68
-        cnsl_handle_input((char *)buf, count);
69
-    }
70
-
71
-    // Tx - write to UART FIFO if needed
72
-    while (uart_is_writable(UART_ID) && (rb_len(&tx) > 0)) {
73
-        uart_putc_raw(UART_ID, rb_pop(&tx));
74
-    }
75 74
 }
76 75
 
77 76
 void serial_init(void) {
@@ -87,11 +86,22 @@ void serial_init(void) {
87 86
     irq_set_exclusive_handler(UART_IRQ, serial_irq);
88 87
     irq_set_enabled(UART_IRQ, true);
89 88
 
90
-    uart_set_irq_enables(UART_ID, true, true);
89
+    uart_set_irq_enables(UART_ID, true, false);
90
+    tx_irq_state = false;
91 91
 }
92 92
 
93 93
 void serial_write(const uint8_t *buf, size_t count) {
94 94
     uart_set_irq_enables(UART_ID, true, false);
95
+    tx_irq_state = false;
96
+
97
+    while ((rb_len(&tx) == 0) && uart_is_writable(UART_ID) && (count > 0)) {
98
+        uart_putc_raw(UART_ID, *buf++);
99
+        count--;
100
+    }
101
+
102
+    if (count == 0) {
103
+        return;
104
+    }
95 105
 
96 106
     size_t off = 0;
97 107
 
@@ -103,16 +113,39 @@ void serial_write(const uint8_t *buf, size_t count) {
103 113
         off += space;
104 114
 
105 115
         uart_set_irq_enables(UART_ID, true, true);
116
+        tx_irq_state = true;
117
+
106 118
         sleep_ms(1);
119
+
107 120
         uart_set_irq_enables(UART_ID, true, false);
121
+        tx_irq_state = false;
108 122
     }
123
+
109 124
 #endif // SERIAL_WRITES_BLOCK_WHEN_BUFFER_FULL
110 125
 
111 126
     rb_add(&tx, buf + off, count);
112 127
 
113 128
     uart_set_irq_enables(UART_ID, true, true);
129
+    tx_irq_state = true;
114 130
 }
115 131
 
116 132
 void serial_set_reroute(bool reroute) {
117 133
     reroute_serial_debug = reroute;
118 134
 }
135
+
136
+void serial_run(void) {
137
+    uart_set_irq_enables(UART_ID, false, tx_irq_state);
138
+
139
+    // Rx - pass local buffer to further processing
140
+    if (rb_len(&rx) >= 1) {
141
+        if (rb_peek(&rx) == ENTER_BOOTLOADER_MAGIC) {
142
+            reset_to_bootloader();
143
+        } else if (reroute_serial_debug) {
144
+            rb_move(&rx, debug_handle_input);
145
+        } else {
146
+            rb_move(&rx, cnsl_handle_input);
147
+        }
148
+    }
149
+
150
+    uart_set_irq_enables(UART_ID, true, tx_irq_state);
151
+}

+ 2
- 2
src/usb_cdc.c View File

@@ -79,9 +79,9 @@ static void cdc_task(void) {
79 79
         if ((count >= 1) && (buf[0] == ENTER_BOOTLOADER_MAGIC)) {
80 80
             reset_to_bootloader();
81 81
         } else if (reroute_cdc_debug) {
82
-            debug_handle_input(buf, count);
82
+            debug_handle_input((const uint8_t *)buf, count);
83 83
         } else {
84
-            cnsl_handle_input(buf, count);
84
+            cnsl_handle_input((const uint8_t *)buf, count);
85 85
         }
86 86
     }
87 87
 }

Loading…
Cancel
Save