13 Commits

Author SHA1 Message Date
eeeck d2d9d21f3d Add timeout to LED heartbeat thread flags 2026-07-30 00:14:33 +02:00
eeeck f53f49a94e Revert to previous blinking logic 2026-07-30 00:06:34 +02:00
eeeck dce176cc1e Update Debug profile settings 2026-07-29 23:56:02 +02:00
eeeck e351c762d3 Remove J1939 decoding comment
- The logger should be more universal, while the data parser should
  focus on the protocol specs
2026-07-29 23:55:42 +02:00
eeeck 89b5fe349c Clear CAN FIFO 0 overflow flag in RX callback 2026-07-29 23:51:30 +02:00
eeeck 2b445aac84 Validate CAN frame DLC before processing 2026-07-29 23:51:22 +02:00
eeeck 8b8c97316b Update LED heartbeat to use blocking delay 2026-07-29 23:50:52 +02:00
eeeck 714051c66d Specify that LICENSE is GPLv3-or-later 2026-07-13 15:22:28 +02:00
eeeck 89b3b6b876 Change title 2026-07-13 14:54:07 +02:00
eeeck e57188a51e Wait forever for next CAN message
- Avoid debug log spam
2026-07-07 14:46:38 +02:00
eeeck 3780497e8d Avoid ISR blocking and add overflow protection 2026-07-07 14:45:15 +02:00
eeeck 3e1bcd6195 Increase queue dimension for high bandwidth CAN buses 2026-07-07 14:38:37 +02:00
eeeck fcf36e4513 Stop sharing buffer among tasks
- Rename variables with clear ones
2026-07-07 14:37:05 +02:00
5 changed files with 52 additions and 51 deletions
+2 -2
View File
@@ -1,10 +1,10 @@
# Third-Party Notices # Copyright Notices
This project is built with open source components and includes third-party software: This project is built with open source components and includes third-party software:
## 1. Original Application Code ## 1. Original Application Code
- **Copyright (c) 2026 Erick Ahmed** - **Copyright (c) 2026 Erick Ahmed**
- **License:** [GNU General Public License v3.0](https://git.erickahmed.com/erickahmed/CANdigger/src/branch/main/LICENSE) - **License:** [GNU General Public License v3.0 or later](https://git.erickahmed.com/erickahmed/CANdigger/src/branch/main/LICENSE)
## 2. STM32F4 HAL Drivers ## 2. STM32F4 HAL Drivers
- **Copyright (c) 2016 STMicroelectronics** - **Copyright (c) 2016 STMicroelectronics**
+6 -7
View File
@@ -73,11 +73,15 @@ void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
osMessageQueueId_t queue; osMessageQueueId_t queue;
osThreadId_t led_task; osThreadId_t led_task;
// TODO: manage the case of FIFO overflow if (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0) != RESET) __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, data) != HAL_OK) return; if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, data) != HAL_OK) return;
if (rxHeader.DLC > 8) return;
if (rxHeader.IDE == CAN_ID_EXT) message.id = rxHeader.ExtId; if (rxHeader.IDE == CAN_ID_EXT) message.id = rxHeader.ExtId;
else message.id = rxHeader.StdId; else message.id = rxHeader.StdId;
message.dlc = rxHeader.DLC; message.dlc = rxHeader.DLC;
message.isExtended = (rxHeader.IDE == CAN_ID_EXT); message.isExtended = (rxHeader.IDE == CAN_ID_EXT);
message.source = (hcan->Instance == CAN1) ? 1 : 2; message.source = (hcan->Instance == CAN1) ? 1 : 2;
@@ -119,12 +123,7 @@ void vCANListener(void *argument)
for (;;) for (;;)
{ {
if (osMessageQueueGet(queue, &message, NULL, 1000) == osOK) if (osMessageQueueGet(queue, &message, NULL, 1000) == osOK) osMessageQueuePut(xUARTQueue, &message, 0U, 0U);
{
// J1939 decoding
osMessageQueuePut(xUARTQueue, &message, 0U, 0U);
}
} }
} }
/* END vCANListener */ /* END vCANListener */
+38 -36
View File
@@ -40,26 +40,28 @@ extern osSemaphoreId_t xUARTDMASemaphore;
*/ */
void uart_printf(const char *fmt, ...) void uart_printf(const char *fmt, ...)
{ {
static char buf[128]; if (__get_IPSR() != 0) return;
char buffer[128];
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
int len = vsnprintf(buf, sizeof(buf), fmt, args);
int len = vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args); va_end(args);
if (len > 0) if (len > 0)
{ {
if (osKernelGetState() == osKernelRunning && __get_IPSR() == 0) if (len >= sizeof(buffer)) len = sizeof(buffer) - 1;
if (osKernelGetState() == osKernelRunning)
{ {
if (osSemaphoreAcquire(xUARTDMASemaphore, 100U) == osOK) if (osSemaphoreAcquire(xUARTDMASemaphore, osWaitForever) == osOK)
{ {
HAL_UART_Transmit(&huart1, (uint8_t*)buf, len, HAL_MAX_DELAY); HAL_UART_Transmit(&huart1, (uint8_t*)buffer, len, HAL_MAX_DELAY);
osSemaphoreRelease(xUARTDMASemaphore); osSemaphoreRelease(xUARTDMASemaphore);
} }
} }
else else HAL_UART_Transmit(&huart1, (uint8_t*)buffer, len, HAL_MAX_DELAY);
{
HAL_UART_Transmit(&huart1, (uint8_t*)buf, len, HAL_MAX_DELAY);
}
} }
} }
/* END uart_printf */ /* END uart_printf */
@@ -70,49 +72,49 @@ void uart_printf(const char *fmt, ...)
* @param arguments: buffer, source, message * @param arguments: buffer, source, message
* @retval None * @retval None
*/ */
static int format_can_message(char *buf, uint8_t source, const CanMessage_t *message) static int format_can_message(char *buffer, uint8_t source, const CanMessage_t *message)
{ {
const char hex[] = "0123456789ABCDEF"; const char hex[] = "0123456789ABCDEF";
buf[0] = 'C'; buffer[0] = 'C';
buf[1] = (source == 1) ? '1' : '2'; buffer[1] = (source == 1) ? '1' : '2';
buf[2] = ':'; buffer[2] = ':';
buf[3] = hex[(message->id >> 28) & 0x0F]; buffer[3] = hex[(message->id >> 28) & 0x0F];
buf[4] = hex[(message->id >> 24) & 0x0F]; buffer[4] = hex[(message->id >> 24) & 0x0F];
buf[5] = hex[(message->id >> 20) & 0x0F]; buffer[5] = hex[(message->id >> 20) & 0x0F];
buf[6] = hex[(message->id >> 16) & 0x0F]; buffer[6] = hex[(message->id >> 16) & 0x0F];
buf[7] = hex[(message->id >> 12) & 0x0F]; buffer[7] = hex[(message->id >> 12) & 0x0F];
buf[8] = hex[(message->id >> 8) & 0x0F]; buffer[8] = hex[(message->id >> 8) & 0x0F];
buf[9] = hex[(message->id >> 4) & 0x0F]; buffer[9] = hex[(message->id >> 4) & 0x0F];
buf[10] = hex[message->id & 0x0F]; buffer[10] = hex[message->id & 0x0F];
buf[11] = ' '; buffer[11] = ' ';
buf[12] = hex[(message->dlc >> 4) & 0x0F]; buffer[12] = hex[(message->dlc >> 4) & 0x0F];
buf[13] = hex[message->dlc & 0x0F]; buffer[13] = hex[message->dlc & 0x0F];
buf[14] = ' '; buffer[14] = ' ';
int idx = 15; int index = 15;
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
if (i < message->dlc) if (i < message->dlc)
{ {
buf[idx++] = hex[(message->payload[i] >> 4) & 0x0F]; buffer[index++] = hex[(message->payload[i] >> 4) & 0x0F];
buf[idx++] = hex[message->payload[i] & 0x0F]; buffer[index++] = hex[message->payload[i] & 0x0F];
} }
else else
{ {
buf[idx++] = ' '; buffer[index++] = ' ';
buf[idx++] = ' '; buffer[index++] = ' ';
} }
if (i < 7) buf[idx++] = ' '; if (i < 7) buffer[index++] = ' ';
} }
buf[idx++] = '\r'; buffer[index++] = '\r';
buf[idx++] = '\n'; buffer[index++] = '\n';
buf[idx] = '\0'; buffer[index] = '\0';
return idx; return index;
} }
/* END format_can_message */ /* END format_can_message */
@@ -175,7 +177,7 @@ void vUARTLogger(void *argument)
for (;;) for (;;)
{ {
if (osMessageQueueGet(xUARTQueue, &message, NULL, 1000U) == osOK) if (osMessageQueueGet(xUARTQueue, &message, NULL, osWaitForever) == osOK)
{ {
if (osSemaphoreAcquire(xUARTDMASemaphore, 100U) == osOK) if (osSemaphoreAcquire(xUARTDMASemaphore, 100U) == osOK)
{ {
+3 -3
View File
@@ -183,9 +183,9 @@ int main(void)
/* USER CODE END RTOS_TIMERS */ /* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */ /* USER CODE BEGIN RTOS_QUEUES */
xCAN1RxQueue = osMessageQueueNew(64, sizeof(CanMessage_t), NULL); xCAN1RxQueue = osMessageQueueNew(2048, sizeof(CanMessage_t), NULL);
xCAN2RxQueue = osMessageQueueNew(64, sizeof(CanMessage_t), NULL); xCAN2RxQueue = osMessageQueueNew(2048, sizeof(CanMessage_t), NULL);
xUARTQueue = osMessageQueueNew(128, sizeof(CanMessage_t), NULL); xUARTQueue = osMessageQueueNew(4096, sizeof(CanMessage_t), NULL);
if (xCAN1RxQueue == NULL || xCAN2RxQueue == NULL || xUARTQueue == NULL) Error_Handler(); if (xCAN1RxQueue == NULL || xCAN2RxQueue == NULL || xUARTQueue == NULL) Error_Handler();
/* USER CODE END RTOS_QUEUES */ /* USER CODE END RTOS_QUEUES */
+3 -3
View File
@@ -15,7 +15,7 @@
<stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.ip_address_local" value="localhost"/> <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.ip_address_local" value="localhost"/>
<booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.limit_swo_clock.enabled" value="false"/> <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.limit_swo_clock.enabled" value="false"/>
<stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.limit_swo_clock.value" value=""/> <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.limit_swo_clock.value" value=""/>
<stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.loadList" value="{&quot;fItems&quot;:[{&quot;fIsFromMainTab&quot;:true,&quot;fPath&quot;:&quot;Debug/can-logger.elf&quot;,&quot;fProjectName&quot;:&quot;can-logger&quot;,&quot;fPerformBuild&quot;:true,&quot;fDownload&quot;:true,&quot;fLoadSymbols&quot;:true}]}"/> <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.loadList" value="{&quot;fItems&quot;:[{&quot;fIsFromMainTab&quot;:true,&quot;fPath&quot;:&quot;/Users/erickahmed/TESI/j1939-can-logger_NEW/can-logger/can-logger/Debug/can-logger.elf&quot;,&quot;fProjectName&quot;:&quot;can-logger&quot;,&quot;fPerformBuild&quot;:true,&quot;fDownload&quot;:true,&quot;fLoadSymbols&quot;:true}]}"/>
<intAttribute key="com.st.stm32cube.ide.mcu.debug.launch.mode" value="0"/> <intAttribute key="com.st.stm32cube.ide.mcu.debug.launch.mode" value="0"/>
<booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.multi_drop_enabled" value="false"/> <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.multi_drop_enabled" value="false"/>
<stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.override_start_address_mode" value="default"/> <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.override_start_address_mode" value="default"/>
@@ -74,9 +74,9 @@
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="remote"/> <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="remote"/>
<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/> <booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/> <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/can-logger.elf"/> <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="/Users/erickahmed/TESI/j1939-can-logger_NEW/can-logger/can-logger/Debug/can-logger.elf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="can-logger"/> <stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="can-logger"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/> <booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.642969664"/> <stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.642969664"/>
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/> <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">