From f127df72f15f6112dd4fa48de25cdeb2c8eb661a Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 26 Oct 2019 14:28:06 -0400 Subject: [PATCH] Add stack_size vars, reduce stack usage --- Firmware/Board/v3/Inc/freertos_vars.h | 2 ++ Firmware/Board/v3/Src/freertos.c | 6 ++++-- Firmware/MotorControl/axis.cpp | 4 ++-- Firmware/MotorControl/axis.hpp | 1 + Firmware/MotorControl/low_level.cpp | 2 +- Firmware/MotorControl/main.cpp | 11 +++++++++++ Firmware/MotorControl/odrive_main.h | 9 +++++++++ Firmware/communication/communication.cpp | 11 ++++++++++- Firmware/communication/communication.h | 1 + Firmware/communication/interface_can.cpp | 2 +- Firmware/communication/interface_can.hpp | 1 + Firmware/communication/interface_uart.cpp | 3 ++- Firmware/communication/interface_uart.h | 1 + Firmware/communication/interface_usb.cpp | 3 ++- Firmware/communication/interface_usb.h | 1 + 15 files changed, 49 insertions(+), 9 deletions(-) diff --git a/Firmware/Board/v3/Inc/freertos_vars.h b/Firmware/Board/v3/Inc/freertos_vars.h index 6e4c0696..7e86c971 100644 --- a/Firmware/Board/v3/Inc/freertos_vars.h +++ b/Firmware/Board/v3/Inc/freertos_vars.h @@ -11,5 +11,7 @@ extern osSemaphoreId sem_can; extern osThreadId defaultTaskHandle; extern osThreadId usb_irq_thread; +extern const uint32_t stack_size_usb_irq_thread; +extern const uint32_t stack_size_default_task; #endif /* __FREERTOS_H */ \ No newline at end of file diff --git a/Firmware/Board/v3/Src/freertos.c b/Firmware/Board/v3/Src/freertos.c index 5edfd079..42ff9751 100644 --- a/Firmware/Board/v3/Src/freertos.c +++ b/Firmware/Board/v3/Src/freertos.c @@ -89,12 +89,14 @@ osSemaphoreId sem_usb_tx; osSemaphoreId sem_can; osThreadId usb_irq_thread; +const uint32_t stack_size_usb_irq_thread = 1024; // Bytes // Place FreeRTOS heap in core coupled memory for better performance __attribute__((section(".ccmram"))) uint8_t ucHeap[configTOTAL_HEAP_SIZE]; /* USER CODE END Variables */ osThreadId defaultTaskHandle; +const uint32_t stack_size_default_task = 1024; // Bytes /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN FunctionPrototypes */ @@ -150,7 +152,7 @@ void usb_deferred_interrupt_thread(void * ctx) { void init_deferred_interrupts(void) { // Start USB interrupt handler thread - osThreadDef(task_usb_pump, usb_deferred_interrupt_thread, osPriorityAboveNormal, 0, 512); + osThreadDef(task_usb_pump, usb_deferred_interrupt_thread, osPriorityAboveNormal, 0, stack_size_usb_irq_thread / sizeof(StackType_t)); usb_irq_thread = osThreadCreate(osThread(task_usb_pump), NULL); } @@ -206,7 +208,7 @@ void MX_FREERTOS_Init(void) { /* Create the thread(s) */ /* definition and creation of defaultTask */ - osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 256); + osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, stack_size_default_task / sizeof(StackType_t)); defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL); /* USER CODE BEGIN RTOS_THREADS */ diff --git a/Firmware/MotorControl/axis.cpp b/Firmware/MotorControl/axis.cpp index a72b05e2..f9406558 100644 --- a/Firmware/MotorControl/axis.cpp +++ b/Firmware/MotorControl/axis.cpp @@ -86,8 +86,8 @@ static void run_state_machine_loop_wrapper(void* ctx) { // @brief Starts run_state_machine_loop in a new thread void Axis::start_thread() { - osThreadDef(thread_def, run_state_machine_loop_wrapper, hw_config_.thread_priority, 0, 4 * 512); - thread_id_ = osThreadCreate(osThread(thread_def), this); + osThreadDef(thread_def, run_state_machine_loop_wrapper, hw_config_.thread_priority, 0, stack_size_ / sizeof(StackType_t)); + thread_id_ = osThreadCreate(osThread(thread_def), this); thread_id_valid_ = true; } diff --git a/Firmware/MotorControl/axis.hpp b/Firmware/MotorControl/axis.hpp index 25d53d5d..18d76eee 100644 --- a/Firmware/MotorControl/axis.hpp +++ b/Firmware/MotorControl/axis.hpp @@ -234,6 +234,7 @@ public: Endstop& max_endstop_; osThreadId thread_id_; + const uint32_t stack_size_ = 1024; // Bytes volatile bool thread_id_valid_ = false; // variables exposed on protocol diff --git a/Firmware/MotorControl/low_level.cpp b/Firmware/MotorControl/low_level.cpp index 1cd17134..8b4a16f5 100644 --- a/Firmware/MotorControl/low_level.cpp +++ b/Firmware/MotorControl/low_level.cpp @@ -757,7 +757,7 @@ static void analog_polling_thread(void *) } void start_analog_thread() { - osThreadDef(thread_def, analog_polling_thread, osPriorityLow, 0, 128); + osThreadDef(thread_def, analog_polling_thread, osPriorityLow, 0, 512 / sizeof(StackType_t)); osThreadCreate(osThread(thread_def), NULL); } diff --git a/Firmware/MotorControl/main.cpp b/Firmware/MotorControl/main.cpp index b2055b38..93af6cc4 100644 --- a/Firmware/MotorControl/main.cpp +++ b/Firmware/MotorControl/main.cpp @@ -193,6 +193,17 @@ void vApplicationIdleHook(void) { system_stats_.min_stack_space_uart = uxTaskGetStackHighWaterMark(uart_thread) * sizeof(StackType_t); system_stats_.min_stack_space_usb_irq = uxTaskGetStackHighWaterMark(usb_irq_thread) * sizeof(StackType_t); system_stats_.min_stack_space_startup = uxTaskGetStackHighWaterMark(defaultTaskHandle) * sizeof(StackType_t); + system_stats_.min_stack_space_can = uxTaskGetStackHighWaterMark(odCAN->thread_id_) * sizeof(StackType_t); + + // Actual usage, in bytes, so we don't have to math + system_stats_.stack_usage_axis0 = axes[0]->stack_size_ - system_stats_.min_stack_space_axis0; + system_stats_.stack_usage_axis1 = axes[1]->stack_size_ - system_stats_.min_stack_space_axis1; + system_stats_.stack_usage_comms = stack_size_comm_thread - system_stats_.min_stack_space_comms; + system_stats_.stack_usage_usb = stack_size_usb_thread - system_stats_.min_stack_space_usb; + system_stats_.stack_usage_uart = stack_size_uart_thread - system_stats_.min_stack_space_uart; + system_stats_.stack_usage_usb_irq = stack_size_usb_irq_thread - system_stats_.min_stack_space_usb_irq; + system_stats_.stack_usage_startup = stack_size_default_task - system_stats_.min_stack_space_startup; + system_stats_.stack_usage_can = odCAN->stack_size_ - system_stats_.min_stack_space_can; } } } diff --git a/Firmware/MotorControl/odrive_main.h b/Firmware/MotorControl/odrive_main.h index 88d7b902..022871ba 100644 --- a/Firmware/MotorControl/odrive_main.h +++ b/Firmware/MotorControl/odrive_main.h @@ -55,6 +55,15 @@ typedef struct { uint32_t min_stack_space_usb_irq; uint32_t min_stack_space_startup; uint32_t min_stack_space_can; + + uint32_t stack_usage_axis0; + uint32_t stack_usage_axis1; + uint32_t stack_usage_comms; + uint32_t stack_usage_usb; + uint32_t stack_usage_uart; + uint32_t stack_usage_usb_irq; + uint32_t stack_usage_startup; + uint32_t stack_usage_can; } SystemStats_t; extern SystemStats_t system_stats_; diff --git a/Firmware/communication/communication.cpp b/Firmware/communication/communication.cpp index 6d96689d..9a436c1b 100644 --- a/Firmware/communication/communication.cpp +++ b/Firmware/communication/communication.cpp @@ -64,6 +64,7 @@ const uint8_t fw_version_revision = FW_VERSION_REVISION; const uint8_t fw_version_unreleased = FW_VERSION_UNRELEASED; // 0 for official releases, 1 otherwise osThreadId comm_thread; +const uint32_t stack_size_comm_thread = 2048; // Bytes volatile bool endpoint_list_valid = false; static uint32_t test_property = 0; @@ -84,7 +85,7 @@ void init_communication(void) { printf("hi!\r\n"); // Start command handling thread - osThreadDef(task_cmd_parse, communication_task, osPriorityNormal, 0, 8000 /* in 32-bit words */); // TODO: fix stack issues + osThreadDef(task_cmd_parse, communication_task, osPriorityNormal, 0, stack_size_comm_thread / sizeof(StackType_t)); comm_thread = osThreadCreate(osThread(task_cmd_parse), NULL); while (!endpoint_list_valid) @@ -135,6 +136,14 @@ static inline auto make_obj_tree() { make_protocol_ro_property("min_stack_space_can", &system_stats_.min_stack_space_can), make_protocol_ro_property("min_stack_space_usb_irq", &system_stats_.min_stack_space_usb_irq), make_protocol_ro_property("min_stack_space_startup", &system_stats_.min_stack_space_startup), + make_protocol_ro_property("stack_usage_axis0", &system_stats_.stack_usage_axis0), + make_protocol_ro_property("stack_usage_axis1", &system_stats_.stack_usage_axis1), + make_protocol_ro_property("stack_usage_comms", &system_stats_.stack_usage_comms), + make_protocol_ro_property("stack_usage_usb", &system_stats_.stack_usage_usb), + make_protocol_ro_property("stack_usage_uart", &system_stats_.stack_usage_uart), + make_protocol_ro_property("stack_usage_usb_irq", &system_stats_.stack_usage_usb_irq), + make_protocol_ro_property("stack_usage_startup", &system_stats_.stack_usage_startup), + make_protocol_ro_property("stack_usage_can", &system_stats_.stack_usage_can), make_protocol_object("usb", make_protocol_ro_property("rx_cnt", &usb_stats_.rx_cnt), make_protocol_ro_property("tx_cnt", &usb_stats_.tx_cnt), diff --git a/Firmware/communication/communication.h b/Firmware/communication/communication.h index b4bab74b..85519b39 100644 --- a/Firmware/communication/communication.h +++ b/Firmware/communication/communication.h @@ -15,6 +15,7 @@ extern "C" { #include extern osThreadId comm_thread; +extern const uint32_t stack_size_comm_thread; extern const uint8_t hw_version_major; extern const uint8_t hw_version_minor; diff --git a/Firmware/communication/interface_can.cpp b/Firmware/communication/interface_can.cpp index 251dec43..00637597 100644 --- a/Firmware/communication/interface_can.cpp +++ b/Firmware/communication/interface_can.cpp @@ -78,7 +78,7 @@ bool ODriveCAN::start_can_server() { if (status == HAL_OK) status = HAL_CAN_ActivateNotification(handle_, CAN_IT_RX_FIFO0_MSG_PENDING); - osThreadDef(can_server_thread_def, can_server_thread_wrapper, osPriorityNormal, 0, 512); + osThreadDef(can_server_thread_def, can_server_thread_wrapper, osPriorityNormal, 0, stack_size_ / sizeof(StackType_t)); thread_id_ = osThreadCreate(osThread(can_server_thread_def), this); thread_id_valid_ = true; diff --git a/Firmware/communication/interface_can.hpp b/Firmware/communication/interface_can.hpp index dcd06232..7a1e9c9a 100644 --- a/Firmware/communication/interface_can.hpp +++ b/Firmware/communication/interface_can.hpp @@ -54,6 +54,7 @@ class ODriveCAN { // Thread Relevant Data osThreadId thread_id_; + const uint32_t stack_size_ = 1024; // Bytes Error_t error_ = ERROR_NONE; volatile bool thread_id_valid_ = false; diff --git a/Firmware/communication/interface_uart.cpp b/Firmware/communication/interface_uart.cpp index b3141138..dc8a4ce6 100644 --- a/Firmware/communication/interface_uart.cpp +++ b/Firmware/communication/interface_uart.cpp @@ -22,6 +22,7 @@ static uint32_t dma_last_rcv_idx; // static thread_local uint32_t deadline_ms = 0; osThreadId uart_thread; +const uint32_t stack_size_uart_thread = 2048; // Bytes class UART4Sender : public StreamSink { @@ -98,7 +99,7 @@ void start_uart_server() { dma_last_rcv_idx = UART_RX_BUFFER_SIZE - huart4.hdmarx->Instance->NDTR; // Start UART communication thread - osThreadDef(uart_server_thread_def, uart_server_thread, osPriorityNormal, 0, 1024 /* the ascii protocol needs considerable stack space */); + osThreadDef(uart_server_thread_def, uart_server_thread, osPriorityNormal, 0, stack_size_uart_thread / sizeof(StackType_t) /* the ascii protocol needs considerable stack space */); uart_thread = osThreadCreate(osThread(uart_server_thread_def), NULL); } diff --git a/Firmware/communication/interface_uart.h b/Firmware/communication/interface_uart.h index 8ef39ec4..65033a6f 100644 --- a/Firmware/communication/interface_uart.h +++ b/Firmware/communication/interface_uart.h @@ -11,6 +11,7 @@ extern "C" { #include extern osThreadId uart_thread; +extern const uint32_t stack_size_uart_thread; void start_uart_server(void); diff --git a/Firmware/communication/interface_usb.cpp b/Firmware/communication/interface_usb.cpp index 036a8203..7f49c0b5 100644 --- a/Firmware/communication/interface_usb.cpp +++ b/Firmware/communication/interface_usb.cpp @@ -14,6 +14,7 @@ #include osThreadId usb_thread; +const uint32_t stack_size_usb_thread = 2048; // Bytes USBStats_t usb_stats_ = {0}; class USBSender : public PacketSink { @@ -177,6 +178,6 @@ void usb_rx_process_packet(uint8_t *buf, uint32_t len, uint8_t endpoint_pair) { void start_usb_server() { // Start USB communication thread - osThreadDef(usb_server_thread_def, usb_server_thread, osPriorityNormal, 0, 1024); + osThreadDef(usb_server_thread_def, usb_server_thread, osPriorityNormal, 0, stack_size_usb_thread / sizeof(StackType_t)); usb_thread = osThreadCreate(osThread(usb_server_thread_def), NULL); } diff --git a/Firmware/communication/interface_usb.h b/Firmware/communication/interface_usb.h index 0a5b94ff..c78ecc5d 100644 --- a/Firmware/communication/interface_usb.h +++ b/Firmware/communication/interface_usb.h @@ -12,6 +12,7 @@ extern "C" { #include extern osThreadId usb_thread; +extern const uint32_t stack_size_usb_thread; typedef struct { uint32_t rx_cnt;