81 Commits

Author SHA1 Message Date
eeeck b737c27b49 Merge pull request 'Remove complex timer based toggling and switch to RTOS task with semaphore based delay' (#18) from dev-rtos-semaphore into main
Reviewed-on: erickahmed/j1939_logger#18
2026-06-15 14:33:38 +02:00
eeeck 2c14d095f7 Better way to avoid race condition, only notification lives in CAN task
- Runs only once
- Only critical notification is inside task
- CAN message during boot will not be lost, instead put inside FIFO0
2026-06-15 14:30:35 +02:00
eeeck 975acb8c3e Indentation fixes 2026-06-15 14:27:05 +02:00
eeeck b1744ce941 Fix double semaphore release 2026-06-15 14:17:12 +02:00
eeeck c1d2e65e20 Move to RTOS_THREADS
- ops...
2026-06-15 14:12:47 +02:00
eeeck ce85e473b3 Move before starting scheduler to avoid race condition
- If a CAN message arrives during boot time ISR will fire and try to put
  data into xCAN1RxQueue. At that time queue is NULL: calling RTOS APIs
  on NULL handles will cause a HardFault
2026-06-15 14:11:11 +02:00
eeeck 8c8fe93d5b Release CANrx semaphore in ISR 2026-06-15 14:09:51 +02:00
eeeck ab8b68313b Transition from timer based to task based LED signal
- Remove RTOS timers
- Create LED task
- Avoid polling, instead wait for semaphore
2026-06-15 14:06:51 +02:00
eeeck 70cead28d7 Re-add newlib lock glue to Src 2026-06-15 10:37:01 +02:00
eeeck 31bf55fed4 Merge pull request 'Implement CAN read RTOS' (#14) from j1939 into main 2026-06-15 10:32:33 +02:00
eeeck ac212c4a0a Merge pull request 'Change headers with better copyright comments' (#13)
from code-licensing into j1939

Reviewed-on: erickahmed/j1939_logger#13
2026-06-14 21:36:45 +02:00
eeeck 9fc2f0b73b Remove files that were misteriously duplicated... 2026-06-14 21:33:13 +02:00
eeeck 3c66a39a5d Fix variable name mismatch 2026-06-14 21:27:10 +02:00
eeeck 19eefc288b Fix scope error by moving declaration 2026-06-14 20:48:11 +02:00
eeeck 17febf569a Use a more generic name as semaphore will be used by other tasks 2026-06-14 18:31:54 +02:00
eeeck 5a3223af29 Merge pull request 'Use semaphores and one shot RTOS timers to better manage LEDs for incoming CAN message on FIFO buffer' (#8) from led-semaphore into j1939
Reviewed-on: erickahmed/j1939_logger#8
2026-06-14 16:49:17 +02:00
eeeck 53772ccb7d Remove error handling as it would cause crash on full queue 2026-06-14 16:45:02 +02:00
eeeck 9d4d807cfb Fix race condition that could cause a hard fault 2026-06-14 16:21:55 +02:00
eeeck 5ec806ffea Add CMSIS include 2026-06-14 16:17:01 +02:00
eeeck 8777f742ac Move typedef to header 2026-06-14 16:15:33 +02:00
eeeck 4aafa81009 Change CODE BEGIN N value 2026-06-14 16:14:20 +02:00
eeeck ac16f8150e Use a more sensible number of semaphores 2026-06-14 16:10:18 +02:00
eeeck f0d2990b8d Move below timer setup 2026-06-14 16:10:00 +02:00
eeeck 72ffb2644e Use more clear variable names 2026-06-14 16:09:45 +02:00
eeeck 2a3d5d17b3 Remove unnecessary declarations 2026-06-14 16:08:43 +02:00
eeeck 151bac7a13 Fix typo 2026-06-14 16:08:21 +02:00
eeeck 75efc4840d Use new context structure instead of direct pass 2026-06-14 15:17:03 +02:00
eeeck a75d42faeb Create context structure for timer callback
Strucure is made of
-  LED (port, pin)
- Semaphore
- Timer handle
2026-06-14 15:16:23 +02:00
eeeck 5b500d72ff Avoid having to declare additional variable 2026-06-14 14:56:32 +02:00
eeeck 5f1695dc0d Start timer once for automatic rearming with semaphore release 2026-06-14 14:51:46 +02:00
eeeck de6dc24dd3 Acquire semaphore and restart timer if new message incoming 2026-06-14 14:51:33 +02:00
eeeck 1b38c0f29a Release semaphore on incoming message
- Discard previous solution with timer only
2026-06-14 14:50:49 +02:00
eeeck 7ece650f72 Move declaration on top 2026-06-14 14:49:54 +02:00
eeeck ebbd1816fa Write LOW status on LED when timer triggers 2026-06-14 14:19:44 +02:00
eeeck 2e2150ebd2 Write HIGH status on LED on incoming CAN message and start 25ms timer 2026-06-14 14:19:30 +02:00
eeeck d6ea04e33e Change variable name 2026-06-14 14:18:40 +02:00
eeeck 7c7d774522 Create semaphores for signalling new message in FIFO buffer 2026-06-14 14:18:28 +02:00
eeeck c65341c662 Change periodic timers to one shot timers 2026-06-14 14:18:07 +02:00
eeeck d42e5fce46 Read CAN messages from FIFO buffer 2026-06-14 13:55:05 +02:00
eeeck 8ef0980510 Handle ISR for CANrx by saving message in FIFO buffer 2026-06-14 13:53:40 +02:00
eeeck dc3688d3d7 Change error check structure 2026-06-14 12:25:31 +02:00
eeeck 34553af0a7 Create message queues for saving CAN frames 2026-06-14 11:11:34 +02:00
eeeck 2cce753716 Remove duplicate declaration 2026-06-14 10:47:12 +02:00
eeeck 19eaee2674 Enable interrupt when CAN frame received and stored in FIFO buffer 2026-06-14 10:42:26 +02:00
eeeck 8e37c44eae Refactor naming conventions following FREERTOS guidelines 2026-06-14 10:04:16 +02:00
eeeck c101c77ba4 Refactor: move RTOS task definition back to main.c
- Private functions remain on canlog.c
- Better consistency for when regenerating with CubeMX
2026-06-14 00:36:41 +02:00
eeeck ce995602e4 Merge branch 'rtos-timers' into j1939 2026-06-13 23:02:22 +02:00
eeeck 0e4b41647f Change headers with better copyright comments
- Add SPDX License Identifier and copyright notice
- Add NOTICE.md

Minor: remove unused freertos.c
2026-06-13 20:07:32 +02:00
eeeck 7b913c8ab9 Simplify CAN error code handler 2026-06-13 20:03:24 +02:00
eeeck de7c817471 Reset LEDs in error handler 2026-06-10 14:27:39 +02:00
eeeck 59a58d1f1f Implement LED heartbeat with RTOS timers instead of threads
- Less memory overhead (no stack allocation)
- Better timing accuracy (less jitter)
- CAN bus still has higher priority than timers
2026-06-10 14:14:17 +02:00
eeeck 0c3c93040b Simplify CAN error code handler 2026-06-10 13:16:19 +02:00
eeeck d641c8b915 Simplify CAN error code handler 2026-06-10 13:15:01 +02:00
eeeck b38d4d5403 Remove static declare 2026-06-10 13:07:24 +02:00
eeeck d32c03c8f0 Update function prototype names 2026-06-10 13:07:15 +02:00
eeeck 0b05331fff Fix error handling for CAN bus 2026-06-10 13:01:43 +02:00
eeeck 0f6011d05b Use CMSIS-RTOS2 instead of FreeRTOS for consistency 2026-06-10 11:38:30 +02:00
eeeck 6c4a1368be Use more clear names for RTOS function prototypes 2026-06-10 11:28:42 +02:00
eeeck e2b6d13364 Clarify function prototype description 2026-06-10 11:25:31 +02:00
eeeck b14cdfaccb Lower priority for LED heartbeat 2026-06-10 11:25:01 +02:00
eeeck 7bb401762a Add headers for better code regeneration compatibility with STM32CubeMX 2026-06-10 11:24:43 +02:00
eeeck 87e8ffc6fa Adapt error handler to log CAN errors and toggle error LED 2026-06-09 10:43:32 +02:00
eeeck 91385d00cf Configure filter banks and start CAN 2026-06-09 10:42:40 +02:00
eeeck 30b7538e26 Use HAL WritePin func instead of TogglePin
- Better reliability in blinking LED
- Slightly more efficiency (fewer CPU clocks)
2026-06-09 10:05:25 +02:00
eeeck c891681b94 Minor comment clarifications 2026-06-09 09:51:10 +02:00
eeeck 770e97ccd9 Move include declaration to private includes 2026-06-09 09:50:00 +02:00
eeeck 5d3c8c0ec0 Refactor task function name 2026-06-09 09:12:11 +02:00
eeeck 495c9cb377 Enable auto wake up on CAN traffic for future sleep mode 2026-06-09 00:33:14 +02:00
eeeck c274be6907 Minor clarification on existing comment 2026-06-09 00:27:17 +02:00
eeeck b92b26b026 Remove trailing newlines 2026-06-09 00:24:41 +02:00
eeeck bbdb278338 Minor changes on comments
- Clarifications on existing comments
- Add TODO
2026-06-09 00:17:06 +02:00
eeeck a236377784 Add simple GPIO toggling in RT 2026-06-09 00:08:24 +02:00
eeeck 9f3d681134 Remove explicit cast 2026-06-09 00:00:42 +02:00
eeeck 41084eb4d2 Move thread creation inside comment block
- Avoid overwrites from STM32CubeMX
2026-06-09 00:00:17 +02:00
eeeck 714ca43d45 Pass LED pin to thread arguments
- Create typedef for LED (port:pin)
- Define two LED as private variables
- Pass them to threads
2026-06-08 23:50:14 +02:00
eeeck 29284ceb87 Move thread handles and attributes to related file
- Better separation of concerns
2026-06-08 23:38:38 +02:00
eeeck a82734cef0 Use correct thread arguments for CANrx threads 2026-06-08 23:28:54 +02:00
eeeck e24f57e77f Move CAN prototypes to relative include file 2026-06-08 23:19:27 +02:00
eeeck 13de1b6c47 Initialize CAN related tasks for logging and signaling
Initialize tasks for:
- CAN log incoming frames
- CAN blink on CANrx
2026-06-08 23:18:00 +02:00
eeeck f9c94efca5 Update drivers and middleware
- Generated from STM32CubeMX
2026-06-08 22:49:16 +02:00
eeeck 3c6e44821c Add extern declaration for CAN handles 2026-06-03 23:59:21 +02:00
7 changed files with 700 additions and 587 deletions
+3 -1
View File
@@ -8,4 +8,6 @@
.metadata .metadata
Core/Src/Backup/ Core/Src/Backup/
Core/Inc/Backup/ Core/Inc/Backup/
Debug .bak
.gitignore
can_logger Debug.launch
+48
View File
@@ -1,7 +1,52 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : canlog.h
* @brief : Header for canlog.c file.
* This file contains the defines related to SAE J1939 CAN.
******************************************************************************
* @attention
*
* Copyright (c) 2026 Erick Ahmed.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef CANLOG_H #ifndef CANLOG_H
#define CANLOG_H #define CANLOG_H
#include "main.h" #include "main.h"
#include "cmsis_os.h"
extern osMessageQueueId_t xCAN1RxQueue;
extern osMessageQueueId_t xCAN2RxQueue;
extern osSemaphoreId_t xSemaphoreCAN1;
extern osSemaphoreId_t xSemaphoreCAN2;
/* USER CODE BEGIN PTD */
typedef struct {
GPIO_TypeDef* port;
uint16_t pin;
} LED_Config;
typedef struct {
uint32_t id;
uint8_t payload[8];
uint8_t dlc;
uint8_t isExtended;
//uint32_t timestamp; //Enable TIM2: 42 MHz / (41+1) = 1 MHz → 1 µs tick; 32bit autoreload freerunning
// this is for getting timestamps on can messages
} CanMessage_t;
typedef struct {
LED_Config *led;
osSemaphoreId_t semaphore;
} LEDContext;
/* USER CODE END PTD */
/** /**
* @brief Initializes the CAN logger modules, OS threads, queues, and hardware. * @brief Initializes the CAN logger modules, OS threads, queues, and hardware.
@@ -9,5 +54,8 @@
* @param hcan2 Pointer to the CAN2 handle * @param hcan2 Pointer to the CAN2 handle
*/ */
void CAN_Logger_Init(CAN_HandleTypeDef *hcan1, CAN_HandleTypeDef *hcan2); void CAN_Logger_Init(CAN_HandleTypeDef *hcan1, CAN_HandleTypeDef *hcan2);
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
void vCANLoggerListen(void *argument);
void vLEDHeartbeat(void *argument);
#endif /* CANLOG_H */ #endif /* CANLOG_H */
+3 -4
View File
@@ -8,11 +8,9 @@
* @attention * @attention
* *
* Copyright (c) 2026 STMicroelectronics. * Copyright (c) 2026 STMicroelectronics.
* All rights reserved. * Copyright (c) 2026 Erick Ahmed.
* *
* This software is licensed under terms that can be found in the LICENSE file * SPDX-License-Identifier: GPL-3.0-or-later
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
* *
****************************************************************************** ******************************************************************************
*/ */
@@ -28,6 +26,7 @@ extern "C" {
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
#include "canlog.h"
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
+122 -25
View File
@@ -1,40 +1,137 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : canlog.c
* @brief : SAE J1939 CAN Real Time listening and decoding
******************************************************************************
* @attention
*
* Copyright (c) 2026 Erick Ahmed.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "canlog.h" #include "canlog.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "cmsis_os.h" #include "cmsis_os.h"
#include <string.h> #include <string.h>
/* USER CODE END Includes */
/* Definitions for canBus1Listen */ extern CAN_HandleTypeDef hcan1;
osThreadId_t canBus1ListenHandle; extern CAN_HandleTypeDef hcan2;
const osThreadAttr_t canBus1Listen_attributes = {
.name = "canBus1Listen",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityRealtime1,
};
/* Definitions for canBus2Listen */
osThreadId_t canBus2ListenHandle;
const osThreadAttr_t canBus2Listen_attributes = {
.name = "canBus2Listen",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityRealtime,
};
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
void CAN_Logger_Init(CAN_HandleTypeDef *hcan1, CAN_HandleTypeDef *hcan2){} /* USER CODE BEGIN FunctionPrototypes */
static void CAN_Listen(void *argument){} /* BEGIN CAN_Logger_Init */
/* BEGIN Header_CAN_Listen */
/** /**
* @brief Function implementing the canBus0Listen thread. * @brief Initialize CAN bus logger.
* @param argument: hcan1, hcan2
* @retval None
*/
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;
filter.FilterBank = 0;
if (HAL_CAN_ConfigFilter(hcan1, &filter) != HAL_OK) Error_Handler();
if (HAL_CAN_Start(hcan1) != HAL_OK) Error_Handler();
filter.FilterBank = 14;
if (HAL_CAN_ConfigFilter(hcan2, &filter) != HAL_OK) Error_Handler();
if (HAL_CAN_Start(hcan2) != HAL_OK) Error_Handler();
}
/* END CAN_Logger_Init */
/* BEGIN HAL_CAN_RxFifo0MsgPendingCallback */
/**
* @brief ISR for CAN message pending in FIFO0
* @param argument: Can handle hcan (hcan1 or hcan2)
* @retval None
*/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
/* CODE BEGIN */
CanMessage_t message;
CAN_RxHeaderTypeDef rxHeader;
uint8_t data[8];
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, data) != HAL_OK) Error_Handler();
message.id = rxHeader.ExtId;
message.dlc = rxHeader.DLC;
message.isExtended = (rxHeader.IDE == CAN_ID_EXT);
memcpy(message.payload, data, rxHeader.DLC);
osMessageQueueId_t queue = (hcan->Instance == CAN1) ? xCAN1RxQueue : xCAN2RxQueue;
if (osMessageQueuePut(queue, &message, 0U, 0U) != osOK)
{
// TODO: better handling: flash error_led on osTimeout, call Error_Handler() when other errors
// send errors like queue full via UART
}
osSemaphoreId_t semaphore = (hcan->Instance == CAN1) ? xSemaphoreCAN1 : xSemaphoreCAN2;
osSemaphoreRelease(semaphore);
/* CODE END */
}
/* END HAL_CAN_RxFifo0MsgPendingCallback */
/* BEGIN vCANLoggerListen */
/**
* @brief Log incoming CAN bus traffic in FIFO buffer
* @param argument: Not used * @param argument: Not used
* @retval None * @retval None
*/ */
/* END Header_CAN_Listen */ void vCANLoggerListen(void *argument)
void CAN_Listen(void *argument)
{ {
/* CODE BEGIN */ /* CODE BEGIN */
/* Infinite loop */ CAN_HandleTypeDef *hcan = (CAN_HandleTypeDef*)argument;
for(;;) osMessageQueueId_t queue = (hcan->Instance == CAN1) ? xCAN1RxQueue : xCAN2RxQueue;
CanMessage_t message;
HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
for (;;)
{ {
osDelay(1); if (osMessageQueueGet(queue, &message, NULL, osWaitForever) == osOK)
{
//
}
} }
/* CODE END */ /* CODE END */
} }
/* END vCANLoggerListen */
/* BEGIN vLEDHeartbeat */
/**
* @brief Blink a LED in heartbeat mode when CAN traffic is detected
* @param argument: LED GPIO (port and pin)
* @retval None
*/
void vLEDHeartbeat(void *argument)
{
/* CODE BEGIN */
LEDContext *context = (LEDContext*)argument;
for (;;)
{
if (osSemaphoreAcquire(context->semaphore, 25U) == osOK) HAL_GPIO_WritePin(context->led->port, context->led->pin, GPIO_PIN_SET);
else HAL_GPIO_WritePin(context->led->port, context->led->pin, GPIO_PIN_RESET);
}
/* CODE END */
}
/* END vLEDHeartbeat */
/* USER CODE END FunctionPrototypes */
-59
View File
@@ -1,59 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : freertos.c
* Description : Code for freertos applications
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */
+88 -24
View File
@@ -5,30 +5,25 @@
* @brief : Main program body * @brief : Main program body
****************************************************************************** ******************************************************************************
* @attention * @attention
*
* Copyright (c) 2026 STMicroelectronics. * Copyright (c) 2026 STMicroelectronics.
* All rights reserved. * Copyright (c) 2026 Erick Ahmed.
* *
* This software is licensed under terms that can be found in the LICENSE file * SPDX-License-Identifier: GPL-3.0-or-later
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
* *
****************************************************************************** ******************************************************************************
*/ */
/* USER CODE END Header */ /* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "main.h" #include "main.h"
#include "canlog.h"
#include "cmsis_os.h" #include "cmsis_os.h"
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
#include "canlog.h"
/* USER CODE END Includes */ /* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */ /* USER CODE BEGIN PTD */
/* USER CODE END PTD */ /* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/
@@ -50,7 +45,18 @@ DMA_HandleTypeDef hdma_sdio_rx;
DMA_HandleTypeDef hdma_sdio_tx; DMA_HandleTypeDef hdma_sdio_tx;
/* USER CODE BEGIN PV */ /* USER CODE BEGIN PV */
LED_Config led_can1 = {GPIOB, GPIO_PIN_2};
LED_Config led_can2 = {GPIOB, GPIO_PIN_5};
LED_Config led_error = {GPIOB, GPIO_PIN_3};
LEDContext ledContextCAN1;
LEDContext ledContextCAN2;
osSemaphoreId_t xSemaphoreCAN1;
osSemaphoreId_t xSemaphoreCAN2;
osMessageQueueId_t xCAN1RxQueue;
osMessageQueueId_t xCAN2RxQueue;
/* USER CODE END PV */ /* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
@@ -62,7 +68,6 @@ static void MX_CAN2_Init(void);
static void MX_SDIO_SD_Init(void); static void MX_SDIO_SD_Init(void);
/* USER CODE BEGIN PFP */ /* USER CODE BEGIN PFP */
/* USER CODE END PFP */ /* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/ /* Private user code ---------------------------------------------------------*/
@@ -103,40 +108,85 @@ int main(void)
MX_CAN1_Init(); MX_CAN1_Init();
MX_CAN2_Init(); MX_CAN2_Init();
MX_SDIO_SD_Init(); MX_SDIO_SD_Init();
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
// Initialize CAN1 and CAN2
CAN_Logger_Init(&hcan1, &hcan2); CAN_Logger_Init(&hcan1, &hcan2);
/* USER CODE END 2 */ /* USER CODE END 2 */
/* Init scheduler */ /* Init scheduler */
osKernelInitialize(); osKernelInitialize();
/* USER CODE BEGIN RTOS_TASKS */
osThreadId_t xCAN1rx;
const osThreadAttr_t CAN1rxAttributes = {
.name = "CAN1rx",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityRealtime1,
};
osThreadId_t xCAN2rx;
const osThreadAttr_t CAN2rxAttributes = {
.name = "CAN2rx",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityRealtime,
};
osThreadId_t xLEDHeartbeatCAN1;
const osThreadAttr_t LEDHeartbeatCAN1Attributes = {
.name = "LED_HB_CAN1",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityVeryLow1,
};
osThreadId_t xLEDHeartbeatCAN2;
const osThreadAttr_t LEDHeartbeatCAN2Attributes = {
.name = "LED_HB_CAN2",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityVeryLow,
};
/* USER END RTOS_TASKS */
/* USER CODE BEGIN RTOS_MUTEX */ /* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */ /* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */ /* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */ /* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */ xSemaphoreCAN1 = osSemaphoreNew(32, 0, NULL);
xSemaphoreCAN2 = osSemaphoreNew(32, 0, NULL);
if (xSemaphoreCAN1 == NULL || xSemaphoreCAN2 == NULL) Error_Handler();
ledContextCAN1.led = &led_can1;
ledContextCAN1.semaphore = xSemaphoreCAN1;
ledContextCAN2.led = &led_can2;
ledContextCAN2.semaphore = xSemaphoreCAN2;
/* USER CODE END RTOS_SEMAPHORES */ /* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */ /* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */ /* add timers, ... */
/* USER CODE END RTOS_TIMERS */ /* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */ /* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */ xCAN1RxQueue = osMessageQueueNew(32, sizeof(CanMessage_t), NULL);
xCAN2RxQueue = osMessageQueueNew(32, sizeof(CanMessage_t), NULL);
if (xCAN1RxQueue == NULL || xCAN2RxQueue == NULL) Error_Handler();
/* USER CODE END RTOS_QUEUES */ /* USER CODE END RTOS_QUEUES */
/* USER CODE BEGIN RTOS_THREADS */ /* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */ xCAN1rx = osThreadNew(vCANLoggerListen, &hcan1, &CAN1rxAttributes);
xCAN2rx = osThreadNew(vCANLoggerListen, &hcan2, &CAN2rxAttributes);
xLEDHeartbeatCAN1 = osThreadNew(vLEDHeartbeat, &ledContextCAN1, &LEDHeartbeatCAN1Attributes);
xLEDHeartbeatCAN2 = osThreadNew(vLEDHeartbeat, &ledContextCAN2, &LEDHeartbeatCAN2Attributes);
/* USER CODE END RTOS_THREADS */ /* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */ /* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */ /* add events, ... */
/* USER CODE END RTOS_EVENTS */ /* USER CODE END RTOS_EVENTS */
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
/* Start scheduler */ /* Start scheduler */
osKernelStart(); osKernelStart();
@@ -148,9 +198,9 @@ int main(void)
{ {
/* USER CODE END WHILE */ /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */ /* USER CODE BEGIN 4 */
} }
/* USER CODE END 3 */ /* USER CODE END 4 */
} }
/** /**
@@ -222,7 +272,7 @@ static void MX_CAN1_Init(void)
hcan1.Init.TimeSeg2 = CAN_BS2_4TQ; hcan1.Init.TimeSeg2 = CAN_BS2_4TQ;
hcan1.Init.TimeTriggeredMode = DISABLE; hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE; hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE; hcan1.Init.AutoWakeUp = ENABLE;
hcan1.Init.AutoRetransmission = DISABLE; hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE; hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE; hcan1.Init.TransmitFifoPriority = DISABLE;
@@ -259,7 +309,7 @@ static void MX_CAN2_Init(void)
hcan2.Init.TimeSeg2 = CAN_BS2_4TQ; hcan2.Init.TimeSeg2 = CAN_BS2_4TQ;
hcan2.Init.TimeTriggeredMode = DISABLE; hcan2.Init.TimeTriggeredMode = DISABLE;
hcan2.Init.AutoBusOff = DISABLE; hcan2.Init.AutoBusOff = DISABLE;
hcan2.Init.AutoWakeUp = DISABLE; hcan2.Init.AutoWakeUp = ENABLE;
hcan2.Init.AutoRetransmission = DISABLE; hcan2.Init.AutoRetransmission = DISABLE;
hcan2.Init.ReceiveFifoLocked = DISABLE; hcan2.Init.ReceiveFifoLocked = DISABLE;
hcan2.Init.TransmitFifoPriority = DISABLE; hcan2.Init.TransmitFifoPriority = DISABLE;
@@ -400,11 +450,9 @@ static void MX_GPIO_Init(void)
/* USER CODE END MX_GPIO_Init_2 */ /* USER CODE END MX_GPIO_Init_2 */
} }
/* USER CODE BEGIN 4 */ /* USER CODE BEGIN 5 */
/* USER CODE END 4 */
/* USER CODE END 5 */
/** /**
* @brief Period elapsed callback in non blocking mode * @brief Period elapsed callback in non blocking mode
@@ -437,8 +485,24 @@ void Error_Handler(void)
/* USER CODE BEGIN Error_Handler_Debug */ /* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */ /* User can add his own implementation to report the HAL error return state */
__disable_irq(); __disable_irq();
//TODO: check if it is necessary to stop FreeRTOS
uint32_t error_code_can1;
uint32_t error_code_can2;
if (HAL_CAN_GetState(&hcan1) != HAL_CAN_STATE_READY) error_code_can1 = HAL_CAN_GetError(&hcan1);
if (HAL_CAN_GetState(&hcan2) != HAL_CAN_STATE_READY) error_code_can2 = HAL_CAN_GetError(&hcan2);
// TODO: write error to SD and/or serial
HAL_GPIO_WritePin(led_can1.port, led_can1.pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(led_can2.port, led_can2.pin, GPIO_PIN_RESET);
while (1) while (1)
{ {
HAL_GPIO_TogglePin(led_error.port, led_error.pin);
HAL_Delay(250);
} }
/* USER CODE END Error_Handler_Debug */ /* USER CODE END Error_Handler_Debug */
} }
-38
View File
@@ -1,38 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.