From af05b403c81be622fa35f72fc5755bce75376fb0 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Mon, 3 May 2021 22:27:58 +0200 Subject: [PATCH 1/2] Improved WiFi debugging. --- src/omv/ports/stm32/main.c | 33 +++- src/omv/ports/stm32/wifidbg.c | 342 ++++++++++++++++++---------------- src/omv/ports/stm32/wifidbg.h | 6 +- 3 files changed, 205 insertions(+), 176 deletions(-) diff --git a/src/omv/ports/stm32/main.c b/src/omv/ports/stm32/main.c index 5c95d0e5a..1c3f7052e 100644 --- a/src/omv/ports/stm32/main.c +++ b/src/omv/ports/stm32/main.c @@ -365,7 +365,7 @@ int ini_handler_callback(void *user, const char *section, const char *name, cons #undef MATCH } -FRESULT exec_boot_script(const char *path, bool selftest, bool interruptible) +FRESULT exec_boot_script(const char *path, bool selftest, bool interruptible, bool wifidbg_enabled) { nlr_buf_t nlr; bool interrupted = false; @@ -377,6 +377,9 @@ FRESULT exec_boot_script(const char *path, bool selftest, bool interruptible) if (interruptible) { usbdbg_set_irq_enabled(true); usbdbg_set_script_running(true); + #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 + wifidbg_set_irq_enabled(wifidbg_enabled); + #endif } // Parse, compile and execute the script. @@ -390,6 +393,9 @@ FRESULT exec_boot_script(const char *path, bool selftest, bool interruptible) // Disable IDE interrupts usbdbg_set_irq_enabled(false); usbdbg_set_script_running(false); + #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 + wifidbg_set_irq_enabled(false); + #endif if (interrupted) { if (selftest) { @@ -654,8 +660,9 @@ soft_reset: // Parse OpenMV configuration file. openmv_config_t openmv_config; memset(&openmv_config, 0, sizeof(openmv_config)); - // Parse config, and init wifi if enabled. ini_parse(&vfs_fat->fatfs, "/openmv.config", ini_handler_callback, &openmv_config); + + // Init wifi debugging if enabled and on first soft-reset only. #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 if (openmv_config.wifidbg == true && wifidbg_init(&openmv_config.wifidbg_config) != 0) { @@ -669,11 +676,11 @@ soft_reset: if (first_soft_reset) { // Execute the boot.py script before initializing the USB dev to // override the USB mode if required, otherwise VCP+MSC is used. - exec_boot_script("/boot.py", false, false); + exec_boot_script("/boot.py", false, false, false); #if (OMV_ENABLE_SELFTEST == 1) // Execute the selftests.py script before the filesystem is mounted // to avoid corrupting the filesystem when selftests.py is removed. - exec_boot_script("/selftest.py", true, false); + exec_boot_script("/selftest.py", true, false, false); #endif } @@ -696,18 +703,20 @@ soft_reset: led_state(LED_GREEN, 0); led_state(LED_BLUE, 0); - if (openmv_config.wifidbg == true) { - timer_tim5_init(100); - } - // Run main script if it exists. if (first_soft_reset) { - exec_boot_script("/main.py", false, true); + exec_boot_script("/main.py", false, true, openmv_config.wifidbg); } do { usbdbg_init(); + if (openmv_config.wifidbg == true) { + // Need to reinit imlib in WiFi debug mode. + imlib_deinit_all(); + imlib_init_all(); + } + // If there's no script ready, just re-exec REPL while (!usbdbg_script_ready()) { nlr_buf_t nlr; @@ -715,6 +724,9 @@ soft_reset: if (nlr_push(&nlr) == 0) { // enable IDE interrupt usbdbg_set_irq_enabled(true); + #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 + wifidbg_set_irq_enabled(openmv_config.wifidbg); + #endif // run REPL if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { @@ -736,6 +748,9 @@ soft_reset: if (nlr_push(&nlr) == 0) { // Enable IDE interrupt usbdbg_set_irq_enabled(true); + #if OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 + wifidbg_set_irq_enabled(openmv_config.wifidbg); + #endif // Execute the script. pyexec_str(usbdbg_get_script()); diff --git a/src/omv/ports/stm32/wifidbg.c b/src/omv/ports/stm32/wifidbg.c index c8cd12f46..7db75557d 100644 --- a/src/omv/ports/stm32/wifidbg.c +++ b/src/omv/ports/stm32/wifidbg.c @@ -15,15 +15,10 @@ #include #include #include -#include "py/nlr.h" #include "py/mphal.h" -#include "py/obj.h" -#include "py/lexer.h" -#include "py/parse.h" -#include "py/compile.h" -#include "py/runtime.h" -#include "py/stackctrl.h" -#include "irq.h" +#include "pendsv.h" +#include "systick.h" +#include "usb.h" #include "winc.h" #include "socket/include/socket.h" @@ -32,63 +27,181 @@ #include "cambus.h" #include "sensor.h" #include "framebuffer.h" -#include "omv_boardconfig.h" -#include "lib/utils/pyexec.h" #include "wifidbg.h" -#include "led.h" #include STM32_HAL_H -#ifndef MIN -#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#ifndef WIFIDBG_MIN +#define WIFIDBG_MIN(x, y) ((x) < (y) ? (x) : (y)) #endif -#define OPENMVCAM_BROADCAST_ADDR ((uint8_t [5]){255, 255, 255, 255}) -#define OPENMVCAM_BROADCAST_PORT (0xABD1) -#define SERVER_ADDR ((uint8_t [5]){192, 168, 1, 1}) -#define SERVER_PORT (9000) -#define BUFFER_SIZE (512) +#define WIFIDBG_BCAST_ADDR ((uint8_t [4]){255, 255, 255, 255}) +#define WIFIDBG_BCAST_PORT (0xABD1) +#define WIFIDBG_SERVER_ADDR ((uint8_t [4]){192, 168, 1, 1}) +#define WIFIDBG_SERVER_PORT (9000) +#define WIFIDBG_BUFFER_SIZE (SOCKET_BUFFER_MAX_LENGTH) -#define UDPCAST_STRING "%d.%d.%d.%d:%d:%s" -#define UDPCAST_STRING_SIZE 4+4+4+4+6+WINC_MAX_BOARD_NAME_LEN+1 +#define WIFIDBG_BCAST_STRING "%d.%d.%d.%d:%d:%s" +#define WIFIDBG_BCAST_STRING_SIZE 4+4+4+4+6+WINC_MAX_BOARD_NAME_LEN+1 +#define WIFIDBG_BCAST_INTERVAL_MS (1000) +#define WIFIDBG_POLL_INTERVAL_MS (10) -#define close_all_sockets() \ - do { \ - winc_socket_close(client_fd); \ - winc_socket_close(server_fd); \ - winc_socket_close(udpbcast_fd); \ - client_fd = -1; \ - server_fd = -1; \ - udpbcast_fd = -1; \ - } while (0) +#define WIFIDBG_SOCKET_TIMEOUT(x) (x == -ETIMEDOUT || x == SOCK_ERR_TIMEOUT) -#define close_server_socket() \ - do { \ - winc_socket_close(server_fd); \ - server_fd = -1; \ - } while (0) +typedef struct wifidbg { + int client_fd; + int server_fd; + int bcast_fd; + uint32_t last_bcast; + uint32_t last_dispatch; + uint8_t ipaddr[WINC_IPV4_ADDR_LEN]; + char bcast_packet[WIFIDBG_BCAST_STRING_SIZE]; + winc_socket_buf_t sockbuf; +} wifidbg_t; -#define close_udpbcast_socket() \ - do { \ - winc_socket_close(udpbcast_fd); \ - udpbcast_fd = -1; \ - } while (0) +static wifidbg_t wifidbg; -#define TIMEDOUT(x) (x == -ETIMEDOUT || x == SOCK_ERR_TIMEOUT) +void wifidbg_close_sockets(wifidbg_t *wifidbg) +{ + winc_socket_close(wifidbg->client_fd); + winc_socket_close(wifidbg->server_fd); + winc_socket_close(wifidbg->bcast_fd); + wifidbg->client_fd = -1; + wifidbg->server_fd = -1; + wifidbg->bcast_fd = -1; +} -static int client_fd = -1; -static int server_fd = -1; -static int udpbcast_fd = -1; -static int udpbcast_time = 0; -static uint8_t ip_addr[WINC_IPV4_ADDR_LEN] = {}; -static char udpbcast_string[UDPCAST_STRING_SIZE] = {}; -static winc_socket_buf_t sockbuf; +int wifidbg_broadcast(wifidbg_t *wifidbg) +{ + if ((systick_current_millis() - wifidbg->last_bcast) > WIFIDBG_BCAST_INTERVAL_MS) { + MAKE_SOCKADDR(bcast_sockaddr, WIFIDBG_BCAST_ADDR, WIFIDBG_BCAST_PORT); + if (winc_socket_sendto(wifidbg->bcast_fd, (uint8_t *) wifidbg->bcast_packet, + strlen(wifidbg->bcast_packet) + 1, &bcast_sockaddr, 10) < 0) { + return -1; + } + wifidbg->last_bcast = systick_current_millis(); + } + return 0; +} + +void wifidbg_pendsv_callback(void) +{ + int ret = 0; + uint32_t request = 0; + uint8_t buf[WIFIDBG_BUFFER_SIZE]; + + // Disable systick dispatch + wifidbg_set_irq_enabled(false); + + if (wifidbg.bcast_fd < 0) { + // Create broadcast socket. + MAKE_SOCKADDR(bcast_sockaddr, WIFIDBG_BCAST_ADDR, WIFIDBG_BCAST_PORT); + + if ((wifidbg.bcast_fd = winc_socket_socket(SOCK_DGRAM)) < 0) { + goto exit_dispatch_error; + } + + if ((ret = winc_socket_bind(wifidbg.bcast_fd, &bcast_sockaddr)) < 0) { + goto exit_dispatch_error; + } + } + + if (wifidbg.server_fd < 0) { + // Create server socket + MAKE_SOCKADDR(server_sockaddr, wifidbg.ipaddr, WIFIDBG_SERVER_PORT); + + if ((wifidbg.server_fd = winc_socket_socket(SOCK_STREAM)) < 0) { + goto exit_dispatch_error; + } + + if ((ret = winc_socket_bind(wifidbg.server_fd, &server_sockaddr)) < 0) { + goto exit_dispatch_error; + } + + if ((ret = winc_socket_listen(wifidbg.server_fd, 1)) < 0) { + goto exit_dispatch_error; + } + } + + if (wifidbg.client_fd < 0) { + wifidbg.sockbuf.idx = 0; + wifidbg.sockbuf.size = 0; + sockaddr client_sockaddr; + // Try to connect to a client + ret = winc_socket_accept(wifidbg.server_fd, &client_sockaddr, &wifidbg.client_fd, 10); + if (WIFIDBG_SOCKET_TIMEOUT(ret)) { + // Timeout, broadcast another message to the IDE. + wifidbg.client_fd = -1; + ret = wifidbg_broadcast(&wifidbg); + } + if (ret < 0) { + // Error on server socket, close sockets and exit. + goto exit_dispatch_error; + } + goto exit_dispatch; + } + + uint8_t cmdbuf[6]; + // We have a connected client + ret = winc_socket_recv(wifidbg.client_fd, cmdbuf, 6, &wifidbg.sockbuf, 5); + if (WIFIDBG_SOCKET_TIMEOUT(ret)) { + goto exit_dispatch; + } else if (ret < 0 || ret != 6 || cmdbuf[0] != 0x30) { + goto exit_dispatch_error; + } + + // Process the request command. + request = cmdbuf[1]; + uint32_t xfer_length = *((uint32_t*)(cmdbuf+2)); + usbdbg_control(NULL, request, xfer_length); + + while (xfer_length) { + if (request & 0x80) { + // Device-to-host data phase + int bytes = WIFIDBG_MIN(xfer_length, WIFIDBG_BUFFER_SIZE); + xfer_length -= bytes; + usbdbg_data_in(buf, bytes); + if ((ret = winc_socket_send(wifidbg.client_fd, buf, bytes, 500)) < 0) { + goto exit_dispatch_error; + } + } else { + // Host-to-device data phase + int bytes = WIFIDBG_MIN(xfer_length, WIFIDBG_BUFFER_SIZE); + if ((ret = winc_socket_recv(wifidbg.client_fd, buf, bytes, &wifidbg.sockbuf, 500)) < 0) { + goto exit_dispatch_error; + } + xfer_length -= ret; + usbdbg_data_out(buf, ret); + } + } + + goto exit_dispatch; +exit_dispatch_error: + wifidbg_close_sockets(&wifidbg); +exit_dispatch: + if (usbdbg_get_irq_enabled()) { + // Re-enable Systick dispatch if IDE interrupts are still enabled. + wifidbg_set_irq_enabled(true); + } + return; +} + +void wifidbg_systick_callback(uint32_t ticks_ms) +{ + if (usb_cdc_debug_mode_enabled() == false && + (ticks_ms - wifidbg.last_dispatch) > WIFIDBG_POLL_INTERVAL_MS) { + pendsv_schedule_dispatch(PENDSV_DISPATCH_WINC, wifidbg_pendsv_callback); + wifidbg.last_dispatch = systick_current_millis(); + } +} int wifidbg_init(wifidbg_config_t *config) { - client_fd = -1; - server_fd = -1; - udpbcast_fd = -1; + memset(&wifidbg, 0, sizeof(wifidbg_t)); + + wifidbg.client_fd = -1; + wifidbg.server_fd = -1; + wifidbg.bcast_fd = -1; if(!config->mode) { // STA Mode @@ -111,7 +224,7 @@ int wifidbg_init(wifidbg_config_t *config) return -3; } - memcpy(ip_addr, ifconfig.ip_addr, WINC_IPV4_ADDR_LEN); + memcpy(wifidbg.ipaddr, ifconfig.ip_addr, WINC_IPV4_ADDR_LEN); } else { // AP Mode @@ -128,127 +241,26 @@ int wifidbg_init(wifidbg_config_t *config) return -2; } - memcpy(ip_addr, SERVER_ADDR, WINC_IPV4_ADDR_LEN); + memcpy(wifidbg.ipaddr, WIFIDBG_SERVER_ADDR, WINC_IPV4_ADDR_LEN); } - snprintf(udpbcast_string, UDPCAST_STRING_SIZE, UDPCAST_STRING, - ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], - SERVER_PORT, config->board_name); + snprintf(wifidbg.bcast_packet, WIFIDBG_BCAST_STRING_SIZE, WIFIDBG_BCAST_STRING, + wifidbg.ipaddr[0], wifidbg.ipaddr[1], wifidbg.ipaddr[2], wifidbg.ipaddr[3], + WIFIDBG_SERVER_PORT, config->board_name); return 0; } -void wifidbg_dispatch() +void wifidbg_set_irq_enabled(bool enable) { - int ret; - uint8_t buf[BUFFER_SIZE]; - sockaddr client_sockaddr; - - if (client_fd < 0 && udpbcast_fd < 0) { - // Create broadcast socket. - MAKE_SOCKADDR(udpbcast_sockaddr, OPENMVCAM_BROADCAST_ADDR, OPENMVCAM_BROADCAST_PORT) - - if ((udpbcast_fd = winc_socket_socket(SOCK_DGRAM)) < 0) { - return; - } - - if ((ret = winc_socket_bind(udpbcast_fd, &udpbcast_sockaddr)) < 0) { - close_udpbcast_socket(); - return; - } - - return; - } - - if (client_fd < 0 && (udpbcast_fd >= 0) && (!(udpbcast_time++ % 100))) { - // Broadcast message to the IDE. - MAKE_SOCKADDR(udpbcast_sockaddr, OPENMVCAM_BROADCAST_ADDR, OPENMVCAM_BROADCAST_PORT) - - if ((ret = winc_socket_sendto(udpbcast_fd, (uint8_t *) udpbcast_string, - strlen(udpbcast_string) + 1, &udpbcast_sockaddr, 500)) < 0) { - close_udpbcast_socket(); - return; - } - - return; - } - - if (server_fd < 0) { - // Create server socket - MAKE_SOCKADDR(server_sockaddr, ip_addr, SERVER_PORT) - - if ((server_fd = winc_socket_socket(SOCK_STREAM)) < 0) { - return; - } - - if ((ret = winc_socket_bind(server_fd, &server_sockaddr)) < 0) { - close_all_sockets(); - return; - } - - if ((ret = winc_socket_listen(server_fd, 1)) < 0) { - close_all_sockets(); - return; - } - - return; - } - - if (client_fd < 0) { - sockbuf.size = sockbuf.idx = 0; - // Call accept. - if ((ret = winc_socket_accept(server_fd, - &client_sockaddr, &client_fd, 10)) < 0) { - if (TIMEDOUT(ret)) { - client_fd = -1; - } else { - close_all_sockets(); - } - return; - } - - return; - } - - if ((ret = winc_socket_recv(client_fd, buf, 6, &sockbuf, 10)) < 0) { - if (TIMEDOUT(ret)) { - return; - } else { - close_all_sockets(); - return; - } - } - - if (ret != 6 || buf[0] != 0x30) { - return; - } - - uint8_t request = buf[1]; - uint32_t xfer_length = *((uint32_t*)(buf+2)); - usbdbg_control(buf+6, request, xfer_length); - - while (xfer_length) { - if (request & 0x80) { - // Device-to-host data phase - int bytes = MIN(xfer_length, BUFFER_SIZE); - xfer_length -= bytes; - usbdbg_data_in(buf, bytes); - if ((ret = winc_socket_send(client_fd, buf, bytes, 500)) < 0) { - close_all_sockets(); - return; - } - } else { - // Host-to-device data phase - int bytes = MIN(xfer_length, BUFFER_SIZE); - if ((ret = winc_socket_recv(client_fd, buf, bytes, &sockbuf, 500)) < 0) { - close_all_sockets(); - return; - } - xfer_length -= ret; - usbdbg_data_out(buf, ret); - } + if (enable) { + // Re-enable Systick dispatch. + systick_enable_dispatch(SYSTICK_DISPATCH_WINC, wifidbg_systick_callback); + } else { + systick_disable_dispatch(SYSTICK_DISPATCH_WINC); } } -#else -void wifidbg_dispatch(){}; #endif // OMV_ENABLE_WIFIDBG && MICROPY_PY_WINC1500 + +// Old timer dispatch, will be removed. +void wifidbg_dispatch() {} diff --git a/src/omv/ports/stm32/wifidbg.h b/src/omv/ports/stm32/wifidbg.h index 66ecdc79e..b87010e99 100644 --- a/src/omv/ports/stm32/wifidbg.h +++ b/src/omv/ports/stm32/wifidbg.h @@ -21,7 +21,9 @@ typedef struct wifidbg_config { char board_name[WINC_MAX_BOARD_NAME_LEN + 1]; } wifidbg_config_t; -int wifidbg_init(wifidbg_config_t *config); void wifidbg_dispatch(); - +void wifidbg_pendsv_callback(void); +void wifidbg_systick_callback(uint32_t ticks_ms); +int wifidbg_init(wifidbg_config_t *config); +void wifidbg_set_irq_enabled(bool enable); #endif /* __WIFIDBG_H__ */ From d8e600259f1c15d8bba8c83a17e2621f40a7663c Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Mon, 10 May 2021 00:08:09 +0200 Subject: [PATCH 2/2] Remove WiFi debug timer. * Not used anymore, reserve TIM5 for servo. --- src/micropython | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/micropython b/src/micropython index 9b4d6808c..fb2cbcd6c 160000 --- a/src/micropython +++ b/src/micropython @@ -1 +1 @@ -Subproject commit 9b4d6808cbc12603bcc972efcf5ee82a650b5720 +Subproject commit fb2cbcd6ce2d4e6d9e89ecf93ad74b0ce89b34b4