From 44706c75a12908f1f2925063a6d4ed6bc2ca4a63 Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Fri, 10 May 2024 15:01:22 -0700 Subject: [PATCH] add serial handler, move network init to network.h --- CMakeLists.txt | 1 + main.c | 47 +++++++++++++++++++------------------- network.h | 28 +++++++++++++++++++++++ pico_lib.h | 2 ++ serial_handler.h | 58 ++++++++++++++++++++++++++--------------------- template.secret.h | 6 ++--- 6 files changed, 90 insertions(+), 52 deletions(-) create mode 100644 network.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ff4b342..6f00ba8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ target_include_directories(${PROGRAM_NAME} PRIVATE target_link_libraries(${PROGRAM_NAME} pico_cyw43_arch_lwip_threadsafe_background pico_stdlib + pico_multicore hardware_adc ) pico_enable_stdio_usb(${PROGRAM_NAME} TRUE) diff --git a/main.c b/main.c index a09d348..bf60ccd 100644 --- a/main.c +++ b/main.c @@ -6,18 +6,11 @@ #include "secret.h" #include "pico_lib.h" +#include "network.h" #include "bmc_handler.h" #include "http_serv.h" #include "serial_handler.h" -void set_host_name(const char * hostname) { - cyw43_arch_lwip_begin(); - struct netif * n = &cyw43_state.netif[CYW43_ITF_STA]; - netif_set_hostname(n, hostname); - netif_set_up(n); - cyw43_arch_lwip_end(); -} - int main() { stdio_init_all(); @@ -25,34 +18,42 @@ int main() { DEBUG_printf("[INIT] [ERR] Failed to initialise cyw43\n"); return 1; } - - serial_handler_init(); - cyw43_arch_enable_sta_mode(); - set_host_name(BMC_HOSTNAME); - DEBUG_printf("[INIT] [OK ] Set hostname to %s\n", BMC_HOSTNAME); - - if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASS, CYW43_AUTH_WPA2_AES_PSK, 30000)){ - DEBUG_printf("[INIT] [ERR] Wi-Fi failed to connect\n"); - return -1; - } - DEBUG_printf("[INIT] [OK ] Wi-Fi connected successfully\n"); + network_init(BMC_HOSTNAME, WIFI_SSID, WIFI_PASS); http_serv_init(); - - // init bmc handler bmc_handler_init(); + serial_handler_init(); // set LED to on to indicate it has connected and initialized cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1); + char command [BUF_SIZE]; while (!http_serv_state->complete) { - sleep_ms(1000); + printf("> "); + serial_get_line(command, BUF_SIZE); + + if (strcmp(command, "help") == 0) { + printf("PICO BMC Shell\n\nhelp\tshow this help message\ninfo\tshow network name, hostname, ip address, and http server port\nclear\tclears the screen\n"); + } + else if (strcmp(command, "info") == 0) { + printf("Network: %s\nHostname: %s\nAddress: %s\nHTTP Port: %i\n", WIFI_SSID, BMC_HOSTNAME, ip_ntoa(netif_ip4_addr(&cyw43_state.netif[CYW43_ITF_STA])), HTTP_PORT); + } + else if (strcmp(command, "clear") == 0) { + printf("\033[2J\033[H"); + } + else if (strcmp(command, "") == 0) { + continue; + } + else { + printf("Unknown command: %s\n", command); + } } + serial_handler_deinit(); bmc_handler_deinit(); http_serv_deinit(); - serial_handler_deinit(); + network_deinit(); cyw43_arch_deinit(); return 0; } \ No newline at end of file diff --git a/network.h b/network.h new file mode 100644 index 0000000..09f62ca --- /dev/null +++ b/network.h @@ -0,0 +1,28 @@ +#ifndef NETWORK_H +#define NETWORK_H + +void set_host_name(const char * hostname) { + cyw43_arch_lwip_begin(); + struct netif * n = &cyw43_state.netif[CYW43_ITF_STA]; + netif_set_hostname(n, hostname); + netif_set_up(n); + cyw43_arch_lwip_end(); +} + +int network_init (char * hostname, char * wifi_ssid, char * wifi_pass) { + set_host_name(hostname); + DEBUG_printf("[INIT] [OK ] Set hostname to %s\n", BMC_HOSTNAME); + + if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASS, CYW43_AUTH_WPA2_AES_PSK, 30000)){ + DEBUG_printf("[INIT] [ERR] Wi-Fi failed to connect\n"); + return -1; + } + else { + DEBUG_printf("[INIT] [OK ] Wi-Fi connected successfully\n"); + return 0; + } +} + +int network_deinit () {} + +#endif \ No newline at end of file diff --git a/pico_lib.h b/pico_lib.h index 75bcb4e..24fe157 100644 --- a/pico_lib.h +++ b/pico_lib.h @@ -3,6 +3,8 @@ #include "pico/cyw43_arch.h" #include "pico/stdlib.h" +#include "pico/multicore.h" +#include "pico/mutex.h" #include "hardware/adc.h" #endif \ No newline at end of file diff --git a/serial_handler.h b/serial_handler.h index cd3a9f3..c342012 100644 --- a/serial_handler.h +++ b/serial_handler.h @@ -1,13 +1,18 @@ #ifndef SERIAL_HANDLER_H #define SERIAL_HANDLER_H -#define INPUT_BUFFER_SIZE 1024 +#define BUF_SIZE 1024 -char * input_buffer; +char * input_buffer_0; +char * input_buffer_1; +char * input_buffers [2] = {NULL, NULL}; +bool active_write_input_buffer; int write_offset; +semaphore_t sem_line; -bool inc_write_offset () { - if (write_offset < INPUT_BUFFER_SIZE - 1) { +int append_char (char c) { + if (write_offset < BUF_SIZE - 1) { + input_buffers[active_write_input_buffer][write_offset] = c; write_offset++; return true; } @@ -17,9 +22,10 @@ bool inc_write_offset () { } } -bool dec_write_offset () { +int delete_char () { if (write_offset > 0) { write_offset--; + input_buffers[active_write_input_buffer][write_offset] = 0; return true; } else { @@ -28,20 +34,13 @@ bool dec_write_offset () { } } -void rst_write_offset () { +void reset_input () { write_offset = 0; } -void handle_return () { - if (strcmp(input_buffer, "") == 0) { - return; - } - else if (strcmp(input_buffer, "info") == 0) { - printf("Network: %s\nHostname: %s\nAddress: %s\nHTTP Port: %i\n", WIFI_SSID, BMC_HOSTNAME, ip_ntoa(netif_ip4_addr(&cyw43_state.netif[CYW43_ITF_STA])), HTTP_PORT); - } - else { - printf("Unknown command: %s\n", input_buffer); - } +void serial_get_line (char * buf, int len) { + sem_acquire_blocking(&sem_line); + memcpy(buf, input_buffers[!active_write_input_buffer], BUF_SIZE > len ? BUF_SIZE : len); } // interrupt code adapted from: https://github.com/raspberrypi/pico-examples/blob/eca13acf57916a0bd5961028314006983894fc84/pico_w/wifi/iperf/picow_iperf.c @@ -53,21 +52,20 @@ void key_pressed_worker_func(async_context_t * context, async_when_pending_worke int key; while ((key = getchar_timeout_us(0)) > 0) { if (key == 0x08 || key == 0x7F) { // backspace & delete - if (dec_write_offset()) { + if (delete_char()) { printf("\b \b"); - input_buffer[write_offset] = 0; } } else if (key == '\r' || key == '\n') { // return printf("\n"); - input_buffer[write_offset] = 0; - handle_return(); - rst_write_offset(); + append_char(0); // ensure there is a null terminator + active_write_input_buffer = !active_write_input_buffer; // flip the active buffer + reset_input(); // reset write pointer to 0 + sem_release(&sem_line); // release sem to allow serial_get_line to resume } else if (32 <= key && key <= 126) { // printable characters printf("%c", key); - input_buffer[write_offset] = key; - inc_write_offset(); + append_char(key); } else if (key == 27) { // escape & escape codes while (getchar_timeout_us(0) > 0) {} @@ -90,14 +88,22 @@ void key_pressed_func(void * param) { // init serial handler void serial_handler_init () { - input_buffer = malloc(INPUT_BUFFER_SIZE * sizeof(char)); + input_buffer_0 = malloc(BUF_SIZE * sizeof(char)); + input_buffer_1 = malloc(BUF_SIZE * sizeof(char)); + input_buffers[0] = input_buffer_0; + input_buffers[1] = input_buffer_1; + sem_init(&sem_line, 0, 1); async_context_add_when_pending_worker(cyw43_arch_async_context(), &key_pressed_worker); stdio_set_chars_available_callback(key_pressed_func, cyw43_arch_async_context()); } void serial_handler_deinit () { - free(input_buffer); - input_buffer = NULL; + free(input_buffer_0); + free(input_buffer_1); + input_buffer_0 = NULL; + input_buffer_1 = NULL; + input_buffers[0] = NULL; + input_buffers[1] = NULL; } #endif \ No newline at end of file diff --git a/template.secret.h b/template.secret.h index 0d1df2f..4548bb3 100644 --- a/template.secret.h +++ b/template.secret.h @@ -1,8 +1,8 @@ #ifndef SECRET_H #define SECRET_H -const char BMC_HOSTNAME[] = "pico_bmc"; -const char WIFI_SSID[] = "ssid"; -const char WIFI_PASS[] = "pass"; +const char BMC_HOSTNAME [] = "pico_bmc"; +const char WIFI_SSID [] = "ssid"; +const char WIFI_PASS [] = "pass"; #endif \ No newline at end of file