From 0ba8ecda645f10c2301ba0c969cf5f24abd376fc Mon Sep 17 00:00:00 2001 From: Erick Ahmed Date: Wed, 24 Jun 2026 12:58:29 +0200 Subject: [PATCH] Implement UART debugging by reusing DEBUG_PRINT when ITW not active --- Core/Inc/main.h | 9 +++-- Core/Src/canlog.c | 87 +++++++++++++++++++++++----------------------- Core/Src/cansend.c | 69 +++++++++++++++++++++++++----------- Core/Src/main.c | 26 ++++++++++++-- 4 files changed, 122 insertions(+), 69 deletions(-) diff --git a/Core/Inc/main.h b/Core/Inc/main.h index 4f23e18..09b7dc3 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -45,15 +45,18 @@ extern "C" { /* Exported macro ------------------------------------------------------------*/ /* USER CODE BEGIN EM */ -//#define DEBUG_ITM +//#define DEBUG_ITW //#define DEBUG_DUMMY_FRAME -#ifdef DEBUG_ITM +#ifdef DEBUG_ITW #include #define DEBUG_PRINT(...) printf(__VA_ARGS__) #else -#define DEBUG_PRINT(...) +#include +void uart_debug_print(const char *fmt, ...); +#define DEBUG_PRINT(...) uart_debug_print(__VA_ARGS__) #endif + /* USER CODE END EM */ /* Exported functions prototypes ---------------------------------------------*/ diff --git a/Core/Src/canlog.c b/Core/Src/canlog.c index 3442156..578395a 100644 --- a/Core/Src/canlog.c +++ b/Core/Src/canlog.c @@ -28,6 +28,9 @@ extern CAN_HandleTypeDef hcan2; extern osThreadId_t xCAN1LedTask; extern osThreadId_t xCAN2LedTask; +volatile uint32_t can1_rx_isr_count = 0; +volatile uint32_t can2_rx_isr_count = 0; + /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN FunctionPrototypes */ /** @@ -38,22 +41,21 @@ extern osThreadId_t xCAN2LedTask; */ void CAN_Logger_Init(CAN_HandleTypeDef *hcan1, CAN_HandleTypeDef *hcan2) { - CAN_FilterTypeDef filter = {0}; - filter.FilterMode = CAN_FILTERMODE_IDMASK; - filter.FilterScale = CAN_FILTERSCALE_32BIT; - filter.FilterIdHigh = 0x0000; - filter.FilterMaskIdHigh = 0x0000; - filter.FilterIdLow = 0x0000; - filter.FilterMaskIdLow = 0x0000; - filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; - filter.FilterActivation = ENABLE; - filter.SlaveStartFilterBank = 14; + CAN_FilterTypeDef filter = {0}; + filter.FilterMode = CAN_FILTERMODE_IDMASK; + filter.FilterScale = CAN_FILTERSCALE_32BIT; + filter.FilterIdHigh = 0x0000; + filter.FilterMaskIdHigh = 0x0000; + filter.FilterIdLow = 0x0000; + filter.FilterMaskIdLow = 0x0000; + filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; + filter.FilterActivation = ENABLE; + filter.SlaveStartFilterBank = 14; - filter.FilterBank = 0; - if (HAL_CAN_ConfigFilter(hcan1, &filter) != HAL_OK) Error_Handler(); - - filter.FilterBank = 14; - if (HAL_CAN_ConfigFilter(hcan2, &filter) != HAL_OK) Error_Handler(); + filter.FilterBank = 0; + if (HAL_CAN_ConfigFilter(hcan1, &filter) != HAL_OK) Error_Handler(); + filter.FilterBank = 14; + if (HAL_CAN_ConfigFilter(hcan2, &filter) != HAL_OK) Error_Handler(); } /* END CAN_Logger_Init */ @@ -65,38 +67,38 @@ void CAN_Logger_Init(CAN_HandleTypeDef *hcan1, CAN_HandleTypeDef *hcan2) */ void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { - CanMessage_t message; - CAN_RxHeaderTypeDef rxHeader; - uint8_t data[8]; + if (hcan->Instance == CAN1) can1_rx_isr_count++; + else can2_rx_isr_count++; - osMessageQueueId_t queue; - osThreadId_t led_task; + CanMessage_t message; + CAN_RxHeaderTypeDef rxHeader; + uint8_t data[8]; - // TODO: manage the case of FIFO overflow - if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, data) != HAL_OK) return; + osMessageQueueId_t queue; + osThreadId_t led_task; - if (rxHeader.IDE == CAN_ID_EXT) message.id = rxHeader.ExtId; - else message.id = rxHeader.StdId; - message.dlc = rxHeader.DLC; - message.isExtended = (rxHeader.IDE == CAN_ID_EXT); - message.source = (hcan->Instance == CAN1) ? 1 : 2; - memcpy(message.payload, data, rxHeader.DLC); + // TODO: manage the case of FIFO overflow + if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, data) != HAL_OK) return; - if (hcan->Instance == CAN1) - { - queue = xCAN1RxQueue; - led_task = xCAN1LedTask; - } - else - { - queue = xCAN2RxQueue; - led_task = xCAN2LedTask; - } + if (rxHeader.IDE == CAN_ID_EXT) message.id = rxHeader.ExtId; + else message.id = rxHeader.StdId; + message.dlc = rxHeader.DLC; + message.isExtended = (rxHeader.IDE == CAN_ID_EXT); + message.source = (hcan->Instance == CAN1) ? 1 : 2; + memcpy(message.payload, data, rxHeader.DLC); - if (osMessageQueuePut(queue, &message, 0U, 0U) == osOK) - { - osThreadFlagsSet(led_task, 0x01); - } + if (hcan->Instance == CAN1) + { + queue = xCAN1RxQueue; + led_task = xCAN1LedTask; + } + else + { + queue = xCAN2RxQueue; + led_task = xCAN2LedTask; + } + + if (osMessageQueuePut(queue, &message, 0U, 0U) == osOK) osThreadFlagsSet(led_task, 0x01); } /* END HAL_CAN_RxFifo0MsgPendingCallback */ @@ -128,7 +130,6 @@ void vCANListener(void *argument) osMessageQueuePut(xUARTQueue, &message, 0U, 0U); } else DEBUG_PRINT("No CAN yet!\r\n"); - } } /* END vCANListener */ diff --git a/Core/Src/cansend.c b/Core/Src/cansend.c index eb2e567..62c8a2a 100644 --- a/Core/Src/cansend.c +++ b/Core/Src/cansend.c @@ -20,11 +20,17 @@ #include "main.h" #include "cmsis_os.h" #include "canlog.h" +#include +#include /* USER CODE END Includes */ extern UART_HandleTypeDef huart1; extern osSemaphoreId_t xUARTDMASemaphore; extern osMessageQueueId_t xUARTQueue; +extern volatile uint32_t can1_rx_isr_count; +extern volatile uint32_t can2_rx_isr_count; +extern CAN_HandleTypeDef hcan1; +extern CAN_HandleTypeDef hcan2; /* BEGIN format_can_message */ /** @@ -86,10 +92,7 @@ static int format_can_message(char *buf, uint8_t source, const CanMessage_t *mes */ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { - if (huart->Instance == USART1) - { - osSemaphoreRelease(xUARTDMASemaphore); - } + if (huart->Instance == USART1) osSemaphoreRelease(xUARTDMASemaphore); } /* END HAL_UART_TxCpltCallback */ @@ -102,7 +105,9 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) void vUARTLogger(void *argument) { CanMessage_t message; - char tx_buffer[45]; + + static char tx_buffer[45]; + static char diag_buf[128]; #ifdef DEBUG_DUMMY_FRAME CanMessage_t dummy_frame = { @@ -116,30 +121,27 @@ void vUARTLogger(void *argument) for (;;) { - DEBUG_PRINT("Waiting for CAN traffic...\r\n"); - - #ifdef DEBUG_DUMMY_FRAME uint32_t queue_timeout = 1000U; - #else - uint32_t queue_timeout = osWaitForever; - #endif + + //ALT: uint32_t queue_timeout = osWaitForever; #ifdef DEBUG_DUMMY_FRAME osMessageQueuePut(xUARTQueue, &dummy_frame, 0U, 0U); osDelay(1000); #endif - if (osMessageQueueGet(xUARTQueue, &message, NULL, queue_timeout) == osOK) - { + if (osMessageQueueGet(xUARTQueue, &message, NULL, queue_timeout) == osOK) + { + if (huart1.gState != HAL_UART_STATE_READY) + { + HAL_UART_Abort(&huart1); + HAL_UART_Init(&huart1); + } + if (osSemaphoreAcquire(xUARTDMASemaphore, queue_timeout) == osOK) { int len = format_can_message(tx_buffer, message.source, &message); - - if (HAL_UART_Transmit_DMA(&huart1, (uint8_t*)tx_buffer, len) == HAL_OK) - { - DEBUG_PRINT("CAN frame sent via UART\r\n"); - } - else + if (HAL_UART_Transmit_DMA(&huart1, (uint8_t*)tx_buffer, len) != HAL_OK) { osSemaphoreRelease(xUARTDMASemaphore); DEBUG_PRINT("HAL error, CAN frame NOT sent!\r\n"); @@ -148,8 +150,35 @@ void vUARTLogger(void *argument) else { DEBUG_PRINT("ERROR: Semaphore timeout! UART might be stuck in BUSY state.\r\n"); + HAL_UART_Abort(&huart1); + HAL_UART_Init(&huart1); + osSemaphoreRelease(xUARTDMASemaphore); } - } + } + else + { + if (osSemaphoreAcquire(xUARTDMASemaphore, queue_timeout) == osOK) + { + int len = snprintf(diag_buf, sizeof(diag_buf), + "[D] ISR1:%lu ISR2:%lu | ST1:%lu ST2:%lu | ER1:0x%lX ER2:0x%lX\r\n", + (unsigned long)can1_rx_isr_count, (unsigned long)can2_rx_isr_count, + (unsigned long)HAL_CAN_GetState(&hcan1), (unsigned long)HAL_CAN_GetState(&hcan2), + (unsigned long)HAL_CAN_GetError(&hcan1), (unsigned long)HAL_CAN_GetError(&hcan2)); + + if (len > 0) + { + if (HAL_UART_Transmit_DMA(&huart1, (uint8_t*)diag_buf, len) != HAL_OK) osSemaphoreRelease(xUARTDMASemaphore); + } + else osSemaphoreRelease(xUARTDMASemaphore); + } + else + { + HAL_UART_Abort(&huart1); + HAL_UART_Init(&huart1); + osSemaphoreRelease(xUARTDMASemaphore); + DEBUG_PRINT("ERROR: Semaphore timeout! UART might be stuck in BUSY state.\r\n"); + } + } } } /* END vUARTLoggerListen */ diff --git a/Core/Src/main.c b/Core/Src/main.c index b5d83e9..0cbcd62 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -21,6 +21,8 @@ /* USER CODE BEGIN Includes */ #include "canlog.h" #include "cansend.h" +#include +#include /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -64,7 +66,6 @@ osMessageQueueId_t xUARTQueue; osSemaphoreId_t xUARTDMASemaphore; osThreadId_t xUartTask; - /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ @@ -75,14 +76,33 @@ static void MX_CAN1_Init(void); static void MX_CAN2_Init(void); static void MX_SDIO_SD_Init(void); static void MX_USART1_UART_Init(void); +/* USER CODE END PFP */ -/* USER CODE BEGIN PFP */ +/* USER CODE BEGIN PF */ int _write(int file, char *ptr, int len) { for (int i = 0; i < len; i++) ITM_SendChar((*ptr++)); return len; } -/* USER CODE END PFP */ + +#ifndef DEBUG_ITM +void uart_debug_print(const char *fmt, ...) +{ + char buf[128]; + va_list args; + + va_start(args, fmt); + int len = vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + if (len > 0) + { + while (HAL_UART_GetState(&huart1) & HAL_UART_STATE_BUSY_TX); + HAL_UART_Transmit(&huart1, (uint8_t*)buf, len, 100); + } +} +#endif +/* USER CODE END PF */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */