Wireless debugging STM32
I want to talk about the unusual use of ESP8266 as an intermediary between STM32 and openOCD. This method has quite a few shortcomings and its use can only be caused by the inability to use the usual (wired) debugging tool.
Plus, this method is one and it is obvious, so I’ll go straight to the shortcomings:
How it works. OpenOCD supports the SWD protocol, besides there is a driver called remote_bitbang. From the name it is clear that the logical levels are simply transmitted by the numbers 1 and 0 and then sent over the network.
The receiver (in our case, ESP8266) must, in accordance with these numbers, set the appropriate level on the outputs. Unfortunately, there is no SWD support in remote_bitbang, but adding it there is not at all difficult:
Next, we need to change the ESP8266 firmware so that it understands the commands coming from openOCD. For this purpose, I used the esp-open-rtos open SDK . I will not give all the firmware code - it is quite voluminous, I will give only its part concerning the processing of data received from openOCD.
Full source code can be found here.
I am using ESP-01. She has two free legs GPIO-0 and GPIO-2, and when turned on, the 2nd leg should have a high level, otherwise the controller will go into bootloader mode. Therefore, it is desirable to pull the leg to power through a 10k resistor.
As for the low speed of work. Yes, he walks along the steps rather sadly, but you can fill in the firmware, set an interrupt, or read the variable.
Theoretically, if you port openOCD to ESP8266, you can achieve a speed comparable to st-link, but I leave it to readers.
I hope someone could be useful.
Plus, this method is one and it is obvious, so I’ll go straight to the shortcomings:
- OpenOCD patch required
- Need to change firmware in ESP8266
- Low speed
How it works. OpenOCD supports the SWD protocol, besides there is a driver called remote_bitbang. From the name it is clear that the logical levels are simply transmitted by the numbers 1 and 0 and then sent over the network.
The receiver (in our case, ESP8266) must, in accordance with these numbers, set the appropriate level on the outputs. Unfortunately, there is no SWD support in remote_bitbang, but adding it there is not at all difficult:
Here is a small patch
--- remote_bitbang.c 2016-10-31 11:06:57.812267924 +0600+++ remote_bitbang.c 2016-10-31 12:33:57.921692808 +0600@@ -120,11 +120,25 @@
remote_bitbang_putc(c);
}
+static int remote_bitbang_swdio_read (void)+{+ remote_swd_putc ('R');+ return remote_bitbang_rread ();+}++static void remote_bitbang_swdio_drive (bool is_output)+{+ char c = is_output ? 'o' : 'i';+ remote_bitbang_putc (c);+}+
static struct bitbang_interface remote_bitbang_bitbang = {
.read = &remote_bitbang_read,
.write = &remote_bitbang_write,
.reset = &remote_bitbang_reset,
.blink = &remote_bitbang_blink,
+ .swdio_read = &remote_bitbang_swdio_read,+ .swdio_drive = &remote_bitbang_swdio_drive,
};
static int remote_bitbang_init_tcp(void)
@@ -271,10 +285,14 @@
COMMAND_REGISTRATION_DONE,
};
+static const char * const remote_bitbang_transport[] = { "jtag", "swd", NULL };+
struct jtag_interface remote_bitbang_interface = {
.name = "remote_bitbang",
+ .transports = remote_bitbang_transport,
.execute_queue = &bitbang_execute_queue,
.commands = remote_bitbang_command_handlers,
+ .swd = &bitbang_swd,
.init = &remote_bitbang_init,
.quit = &remote_bitbang_quit,
};
Next, we need to change the ESP8266 firmware so that it understands the commands coming from openOCD. For this purpose, I used the esp-open-rtos open SDK . I will not give all the firmware code - it is quite voluminous, I will give only its part concerning the processing of data received from openOCD.
Spoiler
#define SWCLK 0#define SWDIO 2IRAM voidopenocd_handler(void *pvParameters){
structnetconn *nc = (structnetconn *) pvParameters;structnetbuf *rbuf = NULL;char *rx_buf;
char d, r;
err_t err;
uint16_t len;
uint16_t i;
gpio_set_pullup (SWCLK, false, false);
gpio_set_pullup (SWDIO, false, false);
gpio_enable (SWCLK, GPIO_OUTPUT);
gpio_enable (SWDIO, GPIO_OUTPUT);
while (1)
{
if ((err = netconn_recv (nc, &rbuf)) != ERR_OK) {
printf ("R ERROR %d\n", err);
return;
}
netbuf_data (rbuf, (void **) &rx_buf, &len);
for (i = 0; i < len; i++)
{
switch (rx_buf [i])
{
case'Q': // Quit
netconn_disconnect (nc);
return;
case'0'...'7':
d = rx_buf [i] - '0';
gpio_write (SWDIO, (d & 0x1));
gpio_write (SWCLK, !!(d & 0x4));
break;
case'i':
gpio_enable (SWDIO, GPIO_INPUT);
break;
case'o':
gpio_enable (SWDIO, GPIO_OUTPUT);
break;
case'R': // Writeback
r = ((char) gpio_read (SWDIO)) + '0';
netconn_write (nc, &r, 1, NETCONN_COPY);
break;
}
}
netbuf_delete (rbuf);
}
}
Full source code can be found here.
I am using ESP-01. She has two free legs GPIO-0 and GPIO-2, and when turned on, the 2nd leg should have a high level, otherwise the controller will go into bootloader mode. Therefore, it is desirable to pull the leg to power through a 10k resistor.
As for the low speed of work. Yes, he walks along the steps rather sadly, but you can fill in the firmware, set an interrupt, or read the variable.
Theoretically, if you port openOCD to ESP8266, you can achieve a speed comparable to st-link, but I leave it to readers.
I hope someone could be useful.