Compare commits
13 Commits
a6daf6c172
...
dev_debug
| Author | SHA1 | Date | |
|---|---|---|---|
| 4afa6702fb | |||
| 907c0b170d | |||
| 60849ebb78 | |||
| aeb553994c | |||
| 5e28758a5e | |||
| 9980dafb5c | |||
| 1d70a35f95 | |||
| 5c8961efa7 | |||
| 17c500e39a | |||
| 91218e782e | |||
| 63e3e81986 | |||
| 84ea393dd6 | |||
| d69cb0231b |
+9
-3
@@ -26,11 +26,11 @@ 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 */
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "canlog.h"
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
/* Exported types ------------------------------------------------------------*/
|
||||||
@@ -45,7 +45,13 @@ extern "C" {
|
|||||||
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN EM */
|
/* USER CODE BEGIN EM */
|
||||||
|
#define DEBUG
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#define DEBUG_PRINT(...) printf(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_PRINT(...)
|
||||||
|
#endif
|
||||||
/* USER CODE END EM */
|
/* USER CODE END EM */
|
||||||
|
|
||||||
/* Exported functions prototypes ---------------------------------------------*/
|
/* Exported functions prototypes ---------------------------------------------*/
|
||||||
|
|||||||
@@ -1,435 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file newlib_lock_glue.c
|
|
||||||
* @author STMicroelectronics
|
|
||||||
* @brief Implementation of newlib lock interface
|
|
||||||
*
|
|
||||||
* @details This file implements locking glue necessary to protect C library
|
|
||||||
* functions and initialization of local static objects in C++.
|
|
||||||
* Lock strategies are defined in stm32_lock.h that implements
|
|
||||||
* different level of thread-safety.
|
|
||||||
*
|
|
||||||
* For more information about which C functions need which of these
|
|
||||||
* low level functions, please consult the newlib libc manual,
|
|
||||||
* see https://sourceware.org/newlib/libc.html
|
|
||||||
*
|
|
||||||
* For more information about the one-time construction API for C++,
|
|
||||||
* see https://itanium-cxx-abi.github.io/cxx-abi/abi.html#once-ctor
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
* @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.
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined (__GNUC__) || defined (__CC_ARM)
|
|
||||||
#error "newlib_lock_glue.c" should be used with GNU Compilers only
|
|
||||||
#endif /* !defined (__GNUC__) || defined (__CC_ARM) */
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include <cmsis_compiler.h>
|
|
||||||
|
|
||||||
/* Private functions prototypes ----------------------------------------------*/
|
|
||||||
__WEAK void Error_Handler(void);
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Global Error_Handler
|
|
||||||
*/
|
|
||||||
__WEAK void Error_Handler(void)
|
|
||||||
{
|
|
||||||
/* Not used if it exists in project */
|
|
||||||
while (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __SINGLE_THREAD__
|
|
||||||
#warning C library is in single-threaded mode. Please take care when using C library functions in threaded contexts
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include <newlib.h>
|
|
||||||
#include <stdatomic.h>
|
|
||||||
#include "stm32_lock.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup _newlib_lock_functions newlib library locks
|
|
||||||
* @see https://sourceware.org/newlib/libc.html
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if __NEWLIB__ >= 3 && defined (_RETARGETABLE_LOCKING)
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/lock.h>
|
|
||||||
|
|
||||||
/* Private macros ------------------------------------------------------------*/
|
|
||||||
/** See struct __lock definition */
|
|
||||||
#define STM32_LOCK_PARAMETER(lock) (&(lock)->lock_data)
|
|
||||||
|
|
||||||
/* shared variables for bare metal allow lock ------------------------------------------------------*/
|
|
||||||
#if defined(STM32_THREAD_SAFE_BAREMETAL_ALLOW_LOCKS) && (STM32_THREAD_SAFE_BAREMETAL_ALLOW_LOCKS != 0)
|
|
||||||
uint32_t gflag = 0;
|
|
||||||
uint32_t call_counter = 0;
|
|
||||||
#endif /* defined(STM32_THREAD_SAFE_BAREMETAL_ALLOW_LOCKS) && (STM32_THREAD_SAFE_BAREMETAL_ALLOW_LOCKS != 0) */
|
|
||||||
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
|
||||||
struct __lock
|
|
||||||
{
|
|
||||||
LockingData_t lock_data; /**< The STM32 lock instance */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Implementing mutex from <a href="https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/libc/misc/lock.c">newlib/libc/misc/lock.c</a> */
|
|
||||||
struct __lock __lock___sinit_recursive_mutex = { LOCKING_DATA_INIT };
|
|
||||||
|
|
||||||
/** Implementing mutex from <a href="https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/libc/misc/lock.c">newlib/libc/misc/lock.c</a> */
|
|
||||||
struct __lock __lock___sfp_recursive_mutex = { LOCKING_DATA_INIT };
|
|
||||||
|
|
||||||
/** Implementing mutex from <a href="https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/libc/misc/lock.c">newlib/libc/misc/lock.c</a> */
|
|
||||||
struct __lock __lock___atexit_recursive_mutex = { LOCKING_DATA_INIT };
|
|
||||||
|
|
||||||
/** Implementing mutex from <a href="https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/libc/misc/lock.c">newlib/libc/misc/lock.c</a> */
|
|
||||||
struct __lock __lock___at_quick_exit_mutex = { LOCKING_DATA_INIT };
|
|
||||||
|
|
||||||
/** Implementing mutex from <a href="https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/libc/misc/lock.c">newlib/libc/misc/lock.c</a> */
|
|
||||||
struct __lock __lock___malloc_recursive_mutex = { LOCKING_DATA_INIT };
|
|
||||||
|
|
||||||
/** Implementing mutex from <a href="https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/libc/misc/lock.c">newlib/libc/misc/lock.c</a> */
|
|
||||||
struct __lock __lock___env_recursive_mutex = { LOCKING_DATA_INIT };
|
|
||||||
|
|
||||||
/** Implementing mutex from <a href="https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/libc/misc/lock.c">newlib/libc/misc/lock.c</a> */
|
|
||||||
struct __lock __lock___tz_mutex = { LOCKING_DATA_INIT };
|
|
||||||
|
|
||||||
/** Implementing mutex from <a href="https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/libc/misc/lock.c">newlib/libc/misc/lock.c</a> */
|
|
||||||
struct __lock __lock___dd_hash_mutex = { LOCKING_DATA_INIT };
|
|
||||||
|
|
||||||
/** Implementing mutex from <a href="https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/libc/misc/lock.c">newlib/libc/misc/lock.c</a> */
|
|
||||||
struct __lock __lock___arc4random_mutex = { LOCKING_DATA_INIT };
|
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize lock
|
|
||||||
* @param lock The lock
|
|
||||||
*/
|
|
||||||
void __retarget_lock_init(_LOCK_T *lock)
|
|
||||||
{
|
|
||||||
__retarget_lock_init_recursive(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize recursive lock
|
|
||||||
* @param lock The lock
|
|
||||||
*/
|
|
||||||
void __retarget_lock_init_recursive(_LOCK_T *lock)
|
|
||||||
{
|
|
||||||
if (lock == NULL)
|
|
||||||
{
|
|
||||||
errno = EINVAL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*lock = (_LOCK_T)malloc(sizeof(struct __lock));
|
|
||||||
if (*lock != NULL)
|
|
||||||
{
|
|
||||||
stm32_lock_init(STM32_LOCK_PARAMETER(*lock));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unable to allocate memory */
|
|
||||||
STM32_LOCK_BLOCK();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Close lock
|
|
||||||
* @param lock The lock
|
|
||||||
*/
|
|
||||||
void __retarget_lock_close(_LOCK_T lock)
|
|
||||||
{
|
|
||||||
__retarget_lock_close_recursive(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Close recursive lock
|
|
||||||
* @param lock The lock
|
|
||||||
*/
|
|
||||||
void __retarget_lock_close_recursive(_LOCK_T lock)
|
|
||||||
{
|
|
||||||
free(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Acquire lock
|
|
||||||
* @param lock The lock
|
|
||||||
*/
|
|
||||||
void __retarget_lock_acquire(_LOCK_T lock)
|
|
||||||
{
|
|
||||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
|
||||||
stm32_lock_acquire(STM32_LOCK_PARAMETER(lock));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Acquire recursive lock
|
|
||||||
* @param lock The lock
|
|
||||||
*/
|
|
||||||
void __retarget_lock_acquire_recursive(_LOCK_T lock)
|
|
||||||
{
|
|
||||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
|
||||||
stm32_lock_acquire(STM32_LOCK_PARAMETER(lock));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Try acquire lock
|
|
||||||
* @param lock The lock
|
|
||||||
* @return 0 always
|
|
||||||
*/
|
|
||||||
int __retarget_lock_try_acquire(_LOCK_T lock)
|
|
||||||
{
|
|
||||||
__retarget_lock_acquire(lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Try acquire recursive lock
|
|
||||||
* @param lock The lock
|
|
||||||
* @return 0 always
|
|
||||||
*/
|
|
||||||
int __retarget_lock_try_acquire_recursive(_LOCK_T lock)
|
|
||||||
{
|
|
||||||
__retarget_lock_acquire_recursive(lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Release lock
|
|
||||||
* @param lock The lock
|
|
||||||
*/
|
|
||||||
void __retarget_lock_release(_LOCK_T lock)
|
|
||||||
{
|
|
||||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
|
||||||
stm32_lock_release(STM32_LOCK_PARAMETER(lock));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Release recursive lock
|
|
||||||
* @param lock The lock
|
|
||||||
*/
|
|
||||||
void __retarget_lock_release_recursive(_LOCK_T lock)
|
|
||||||
{
|
|
||||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
|
||||||
stm32_lock_release(STM32_LOCK_PARAMETER(lock));
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
#warning This makes malloc, env, and TZ calls thread-safe, not the entire newlib
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include <reent.h>
|
|
||||||
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
|
||||||
/** Mutex used in __malloc_lock and __malloc_unlock */
|
|
||||||
static LockingData_t __lock___malloc_recursive_mutex = LOCKING_DATA_INIT;
|
|
||||||
|
|
||||||
/** Mutex used in __env_lock and __env_unlock */
|
|
||||||
static LockingData_t __lock___env_recursive_mutex = LOCKING_DATA_INIT;
|
|
||||||
|
|
||||||
/** Mutex used in __tz_lock and __tz_unlock */
|
|
||||||
static LockingData_t __lock___tz_mutex = LOCKING_DATA_INIT;
|
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if __STD_C
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Acquire malloc lock
|
|
||||||
* @param reent The reentrance struct
|
|
||||||
*/
|
|
||||||
void __malloc_lock(struct _reent *reent)
|
|
||||||
{
|
|
||||||
STM32_LOCK_UNUSED(reent);
|
|
||||||
stm32_lock_acquire(&__lock___malloc_recursive_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Release malloc lock
|
|
||||||
* @param reent The reentrance struct
|
|
||||||
*/
|
|
||||||
void __malloc_unlock(struct _reent *reent)
|
|
||||||
{
|
|
||||||
STM32_LOCK_UNUSED(reent);
|
|
||||||
stm32_lock_release(&__lock___malloc_recursive_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Acquire malloc lock
|
|
||||||
*/
|
|
||||||
void __malloc_lock()
|
|
||||||
{
|
|
||||||
stm32_lock_acquire(&__lock___malloc_recursive_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Release malloc lock
|
|
||||||
*/
|
|
||||||
void __malloc_unlock()
|
|
||||||
{
|
|
||||||
stm32_lock_release(&__lock___malloc_recursive_mutex);
|
|
||||||
}
|
|
||||||
#endif /* __STD_C */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Acquire env lock
|
|
||||||
* @param reent The reentrance struct
|
|
||||||
*/
|
|
||||||
void __env_lock(struct _reent *reent)
|
|
||||||
{
|
|
||||||
STM32_LOCK_UNUSED(reent);
|
|
||||||
stm32_lock_acquire(&__lock___env_recursive_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Release env lock
|
|
||||||
* @param reent The reentrance struct
|
|
||||||
*/
|
|
||||||
void __env_unlock(struct _reent *reent)
|
|
||||||
{
|
|
||||||
STM32_LOCK_UNUSED(reent);
|
|
||||||
stm32_lock_release(&__lock___env_recursive_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Acquire tz lock
|
|
||||||
*/
|
|
||||||
void __tz_lock()
|
|
||||||
{
|
|
||||||
stm32_lock_acquire(&__lock___tz_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Release tz lock
|
|
||||||
*/
|
|
||||||
void __tz_unlock()
|
|
||||||
{
|
|
||||||
stm32_lock_release(&__lock___tz_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __NEWLIB__ >= 3 && defined (_RETARGETABLE_LOCKING) */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup __cxa_guard_ GNU C++ one-time construction API
|
|
||||||
* @see https://itanium-cxx-abi.github.io/cxx-abi/abi.html#once-ctor
|
|
||||||
*
|
|
||||||
* When building for C++, please make sure that <tt>-fno-threadsafe-statics</tt> is not passed to the compiler
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
|
||||||
/** The guard object is created by the C++ compiler and is 32 bit for ARM EABI. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
atomic_uchar initialized; /**< Indicate if object is initialized */
|
|
||||||
uint8_t acquired; /**< Ensure non-recursive lock */
|
|
||||||
uint16_t unused; /**< Padding */
|
|
||||||
} __attribute__((packed)) CxaGuardObject_t;
|
|
||||||
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
|
||||||
/** Mutex used in __cxa_guard_acquire, __cxa_guard_release and __cxa_guard_abort */
|
|
||||||
static LockingData_t __cxa_guard_mutex = LOCKING_DATA_INIT;
|
|
||||||
|
|
||||||
/* Private functions prototype ---------------------------------------------------------*/
|
|
||||||
int __cxa_guard_acquire(CxaGuardObject_t *guard_object);
|
|
||||||
void __cxa_guard_abort(CxaGuardObject_t *guard_object);
|
|
||||||
void __cxa_guard_release(CxaGuardObject_t *guard_object);
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Acquire __cxa_guard mutex
|
|
||||||
* @param guard_object Guard object
|
|
||||||
* @return 0 if object is initialized, else initialization of object required
|
|
||||||
*/
|
|
||||||
int __cxa_guard_acquire(CxaGuardObject_t *guard_object)
|
|
||||||
{
|
|
||||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(guard_object);
|
|
||||||
|
|
||||||
if (atomic_load(&guard_object->initialized) == 0)
|
|
||||||
{
|
|
||||||
/* Object needs initialization, lock threading context */
|
|
||||||
stm32_lock_acquire(&__cxa_guard_mutex);
|
|
||||||
if (atomic_load(&guard_object->initialized) == 0)
|
|
||||||
{
|
|
||||||
/* Object needs initialization */
|
|
||||||
if (guard_object->acquired)
|
|
||||||
{
|
|
||||||
/* Object initialization already in progress */
|
|
||||||
STM32_LOCK_BLOCK();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lock acquired */
|
|
||||||
guard_object->acquired = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Object initialized in another thread */
|
|
||||||
stm32_lock_release(&__cxa_guard_mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Object already initialized */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Abort __cxa_guard mutex
|
|
||||||
* @param guard_object Guard object
|
|
||||||
*/
|
|
||||||
void __cxa_guard_abort(CxaGuardObject_t *guard_object)
|
|
||||||
{
|
|
||||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(guard_object);
|
|
||||||
|
|
||||||
if (guard_object->acquired)
|
|
||||||
{
|
|
||||||
/* Release lock */
|
|
||||||
guard_object->acquired = 0;
|
|
||||||
stm32_lock_release(&__cxa_guard_mutex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Trying to release non-acquired lock */
|
|
||||||
STM32_LOCK_BLOCK();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Release __cxa_guard mutex
|
|
||||||
* @param guard_object Guard object
|
|
||||||
*/
|
|
||||||
void __cxa_guard_release(CxaGuardObject_t *guard_object)
|
|
||||||
{
|
|
||||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(guard_object);
|
|
||||||
|
|
||||||
/* Object initialized */
|
|
||||||
atomic_store(&guard_object->initialized, 1);
|
|
||||||
|
|
||||||
/* Release lock */
|
|
||||||
__cxa_guard_abort(guard_object);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* __SINGLE_THREAD__ */
|
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
/* USER CODE END Header */
|
/* USER CODE END Header */
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "canlog.h"
|
#include "canlog.h"
|
||||||
|
#include "main.h"
|
||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
|
|||||||
+9
-3
@@ -32,7 +32,7 @@ extern osMessageQueueId_t xUARTQueue;
|
|||||||
* @param arguments: buffer, source, message
|
* @param arguments: buffer, source, message
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
static void format_can_message(char *buf, uint8_t source, const CanMessage_t *message)
|
static int format_can_message(char *buf, uint8_t source, const CanMessage_t *message)
|
||||||
{
|
{
|
||||||
const char hex[] = "0123456789ABCDEF";
|
const char hex[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
@@ -72,6 +72,9 @@ static void format_can_message(char *buf, uint8_t source, const CanMessage_t *me
|
|||||||
|
|
||||||
buf[idx++] = '\r';
|
buf[idx++] = '\r';
|
||||||
buf[idx++] = '\n';
|
buf[idx++] = '\n';
|
||||||
|
buf[idx] = '\0';
|
||||||
|
|
||||||
|
return idx;
|
||||||
}
|
}
|
||||||
/* END format_can_message */
|
/* END format_can_message */
|
||||||
|
|
||||||
@@ -103,11 +106,14 @@ void vUARTLogger(void *argument)
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
DEBUG_PRINT("Waiting for CAN traffic...\r\n");
|
||||||
if (osMessageQueueGet(xUARTQueue, &message, NULL, osWaitForever) == osOK)
|
if (osMessageQueueGet(xUARTQueue, &message, NULL, osWaitForever) == osOK)
|
||||||
{
|
{
|
||||||
format_can_message(tx_buffer, message.source, &message); // Assuming you add 'source' to the struct
|
DEBUG_PRINT("CAN frame detected\r\n");
|
||||||
HAL_UART_Transmit_DMA(&huart1, (uint8_t*)tx_buffer, 44);
|
format_can_message(tx_buffer, message.source, &message);
|
||||||
|
HAL_UART_Transmit_DMA(&huart1, (uint8_t*)tx_buffer, len);
|
||||||
osSemaphoreAcquire(xUARTDMASemaphore, osWaitForever);
|
osSemaphoreAcquire(xUARTDMASemaphore, osWaitForever);
|
||||||
|
DEBUG_PRINT("CAN frame sent via UART\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+48
-29
@@ -48,9 +48,9 @@ DMA_HandleTypeDef hdma_sdio_tx;
|
|||||||
UART_HandleTypeDef huart1;
|
UART_HandleTypeDef huart1;
|
||||||
|
|
||||||
/* USER CODE BEGIN PV */
|
/* USER CODE BEGIN PV */
|
||||||
LED_Config led_can1 = {GPIOB, GPIO_PIN_2};
|
LED_Config led_can1 = {GPIOB, GPIO_PIN_5};
|
||||||
LED_Config led_can2 = {GPIOB, GPIO_PIN_5};
|
LED_Config led_can2 = {GPIOB, GPIO_PIN_6};
|
||||||
LED_Config led_error = {GPIOB, GPIO_PIN_3};
|
LED_Config led_error = {GPIOB, GPIO_PIN_7};
|
||||||
|
|
||||||
osThreadId_t xCAN1rxTask;
|
osThreadId_t xCAN1rxTask;
|
||||||
osThreadId_t xCAN2rxTask;
|
osThreadId_t xCAN2rxTask;
|
||||||
@@ -76,6 +76,12 @@ static void MX_SDIO_SD_Init(void);
|
|||||||
static void MX_USART1_UART_Init(void);
|
static void MX_USART1_UART_Init(void);
|
||||||
|
|
||||||
/* USER CODE BEGIN PFP */
|
/* USER CODE BEGIN PFP */
|
||||||
|
int _write(int file, char *ptr, int len) {
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
ITM_SendChar((*ptr++));
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
/* USER CODE END PFP */
|
/* USER CODE END PFP */
|
||||||
|
|
||||||
/* Private user code ---------------------------------------------------------*/
|
/* Private user code ---------------------------------------------------------*/
|
||||||
@@ -91,7 +97,11 @@ int main(void)
|
|||||||
{
|
{
|
||||||
|
|
||||||
/* USER CODE BEGIN 1 */
|
/* USER CODE BEGIN 1 */
|
||||||
|
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||||
|
ITM->LAR = 0xC5ACCE55;
|
||||||
|
ITM->TER = 1 << 0;
|
||||||
|
ITM->TCR = ITM_TCR_ITMENA_Msk | ITM_TCR_SYNCENA_Msk | ITM_TCR_SWOENA_Msk;
|
||||||
|
DEBUG_PRINT("Booting system\r\n");
|
||||||
/* USER CODE END 1 */
|
/* USER CODE END 1 */
|
||||||
|
|
||||||
/* MCU Configuration--------------------------------------------------------*/
|
/* MCU Configuration--------------------------------------------------------*/
|
||||||
@@ -100,6 +110,7 @@ int main(void)
|
|||||||
HAL_Init();
|
HAL_Init();
|
||||||
|
|
||||||
/* USER CODE BEGIN Init */
|
/* USER CODE BEGIN Init */
|
||||||
|
DEBUG_PRINT("Configuring system clock\r\n");
|
||||||
|
|
||||||
/* USER CODE END Init */
|
/* USER CODE END Init */
|
||||||
|
|
||||||
@@ -107,7 +118,7 @@ int main(void)
|
|||||||
SystemClock_Config();
|
SystemClock_Config();
|
||||||
|
|
||||||
/* USER CODE BEGIN SysInit */
|
/* USER CODE BEGIN SysInit */
|
||||||
|
DEBUG_PRINT("Initializing configured peripherals...\r\n");
|
||||||
/* USER CODE END SysInit */
|
/* USER CODE END SysInit */
|
||||||
|
|
||||||
/* Initialize all configured peripherals */
|
/* Initialize all configured peripherals */
|
||||||
@@ -118,12 +129,15 @@ int main(void)
|
|||||||
MX_SDIO_SD_Init();
|
MX_SDIO_SD_Init();
|
||||||
MX_USART1_UART_Init();
|
MX_USART1_UART_Init();
|
||||||
/* USER CODE BEGIN 2 */
|
/* USER CODE BEGIN 2 */
|
||||||
|
DEBUG_PRINT("Initializing CAN bus logger\r\n");
|
||||||
CAN_Logger_Init(&hcan1, &hcan2);
|
CAN_Logger_Init(&hcan1, &hcan2);
|
||||||
/* USER CODE END 2 */
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
/* Init scheduler */
|
/* Init scheduler */
|
||||||
osKernelInitialize();
|
osKernelInitialize();
|
||||||
|
|
||||||
|
DEBUG_PRINT("Creating RTOS entities\r\n");
|
||||||
|
|
||||||
/* USER CODE BEGIN RTOS_TASKS */
|
/* USER CODE BEGIN RTOS_TASKS */
|
||||||
const osThreadAttr_t CAN1rxAttributes = {
|
const osThreadAttr_t CAN1rxAttributes = {
|
||||||
.name = "CAN1rx",
|
.name = "CAN1rx",
|
||||||
@@ -183,6 +197,7 @@ int main(void)
|
|||||||
/* USER CODE END RTOS_EVENTS */
|
/* USER CODE END RTOS_EVENTS */
|
||||||
|
|
||||||
/* Start scheduler */
|
/* Start scheduler */
|
||||||
|
DEBUG_PRINT("Starting RTOS init scheduler\r\n");
|
||||||
osKernelStart();
|
osKernelStart();
|
||||||
|
|
||||||
/* We should never get here as control is now taken by the scheduler */
|
/* We should never get here as control is now taken by the scheduler */
|
||||||
@@ -194,6 +209,7 @@ int main(void)
|
|||||||
/* USER CODE END WHILE */
|
/* USER CODE END WHILE */
|
||||||
|
|
||||||
/* USER CODE BEGIN 3 */
|
/* USER CODE BEGIN 3 */
|
||||||
|
DEBUG_PRINT("ERROR: RTOS scheduler crashed!\r\n");
|
||||||
/* USER CODE END 3 */
|
/* USER CODE END 3 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -276,7 +292,7 @@ static void MX_CAN1_Init(void)
|
|||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
/* USER CODE BEGIN CAN1_Init 2 */
|
/* USER CODE BEGIN CAN1_Init 2 */
|
||||||
|
DEBUG_PRINT("CAN1 initialized!\r\n");
|
||||||
/* USER CODE END CAN1_Init 2 */
|
/* USER CODE END CAN1_Init 2 */
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -313,7 +329,7 @@ static void MX_CAN2_Init(void)
|
|||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
/* USER CODE BEGIN CAN2_Init 2 */
|
/* USER CODE BEGIN CAN2_Init 2 */
|
||||||
|
DEBUG_PRINT("CAN2 initialized!\r\n");
|
||||||
/* USER CODE END CAN2_Init 2 */
|
/* USER CODE END CAN2_Init 2 */
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -340,16 +356,16 @@ static void MX_SDIO_SD_Init(void)
|
|||||||
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
|
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
|
||||||
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
|
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
|
||||||
hsd.Init.ClockDiv = 0;
|
hsd.Init.ClockDiv = 0;
|
||||||
if (HAL_SD_Init(&hsd) != HAL_OK)
|
//if (HAL_SD_Init(&hsd) != HAL_OK)
|
||||||
{
|
//{
|
||||||
Error_Handler();
|
// Error_Handler();
|
||||||
}
|
//}
|
||||||
if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
|
//if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
|
||||||
{
|
//{
|
||||||
Error_Handler();
|
// Error_Handler();
|
||||||
}
|
//}
|
||||||
/* USER CODE BEGIN SDIO_Init 2 */
|
/* USER CODE BEGIN SDIO_Init 2 */
|
||||||
|
//DEBUG_PRINT("SDIO initialized!\r\n");
|
||||||
/* USER CODE END SDIO_Init 2 */
|
/* USER CODE END SDIO_Init 2 */
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -382,7 +398,7 @@ static void MX_USART1_UART_Init(void)
|
|||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
/* USER CODE BEGIN USART1_Init 2 */
|
/* USER CODE BEGIN USART1_Init 2 */
|
||||||
|
DEBUG_PRINT("USART1 initialized!\r\n");
|
||||||
/* USER CODE END USART1_Init 2 */
|
/* USER CODE END USART1_Init 2 */
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -404,6 +420,9 @@ static void MX_DMA_Init(void)
|
|||||||
HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 5, 0);
|
HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 5, 0);
|
||||||
HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
|
HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN MX_DMA_Init 1 */
|
||||||
|
DEBUG_PRINT("DMA initialized!\r\n");
|
||||||
|
/* USER CODE END MX_DMA_Init 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -426,7 +445,7 @@ static void MX_GPIO_Init(void)
|
|||||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||||
|
|
||||||
/*Configure GPIO pin Output Level */
|
/*Configure GPIO pin Output Level */
|
||||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);
|
||||||
|
|
||||||
/*Configure GPIO pins : PC13 PC14 PC15 PC0
|
/*Configure GPIO pins : PC13 PC14 PC15 PC0
|
||||||
PC1 PC2 PC3 PC4
|
PC1 PC2 PC3 PC4
|
||||||
@@ -446,35 +465,33 @@ static void MX_GPIO_Init(void)
|
|||||||
|
|
||||||
/*Configure GPIO pins : PA0 PA1 PA2 PA3
|
/*Configure GPIO pins : PA0 PA1 PA2 PA3
|
||||||
PA4 PA5 PA6 PA7
|
PA4 PA5 PA6 PA7
|
||||||
PA8 PA11 PA12 PA13
|
PA8 PA11 PA12 PA15 */
|
||||||
PA14 PA15 */
|
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|
||||||
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
|
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
|
||||||
|GPIO_PIN_8|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13
|
|GPIO_PIN_8|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_15;
|
||||||
|GPIO_PIN_14|GPIO_PIN_15;
|
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
/*Configure GPIO pins : PB0 PB1 PB2 PB10
|
/*Configure GPIO pins : PB0 PB1 PB2 PB10
|
||||||
PB11 PB14 PB15 PB6
|
PB11 PB14 PB15 PB3
|
||||||
PB7 */
|
PB4 */
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
|
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
|
||||||
|GPIO_PIN_11|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_6
|
|GPIO_PIN_11|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_3
|
||||||
|GPIO_PIN_7;
|
|GPIO_PIN_4;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
|
|
||||||
/*Configure GPIO pins : PB3 PB4 PB5 */
|
/*Configure GPIO pins : PB5 PB6 PB7 */
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5;
|
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
|
|
||||||
/* USER CODE BEGIN MX_GPIO_Init_2 */
|
/* USER CODE BEGIN MX_GPIO_Init_2 */
|
||||||
|
DEBUG_PRINT("GPIO initialized!\r\n");
|
||||||
/* USER CODE END MX_GPIO_Init_2 */
|
/* USER CODE END MX_GPIO_Init_2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,6 +526,8 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
|||||||
*/
|
*/
|
||||||
void Error_Handler(void)
|
void Error_Handler(void)
|
||||||
{
|
{
|
||||||
|
DEBUG_PRINT("ERROR: entering error handler\r\n");
|
||||||
|
|
||||||
/* 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();
|
||||||
|
|||||||
+21
-15
@@ -70,22 +70,24 @@ Mcu.Name=STM32F405RGTx
|
|||||||
Mcu.Package=LQFP64
|
Mcu.Package=LQFP64
|
||||||
Mcu.Pin0=PB12
|
Mcu.Pin0=PB12
|
||||||
Mcu.Pin1=PB13
|
Mcu.Pin1=PB13
|
||||||
Mcu.Pin10=PB3
|
Mcu.Pin10=PC12
|
||||||
Mcu.Pin11=PB4
|
Mcu.Pin11=PD2
|
||||||
Mcu.Pin12=PB5
|
Mcu.Pin12=PB5
|
||||||
Mcu.Pin13=PB8
|
Mcu.Pin13=PB6
|
||||||
Mcu.Pin14=PB9
|
Mcu.Pin14=PB7
|
||||||
Mcu.Pin15=VP_FREERTOS_VS_CMSIS_V2
|
Mcu.Pin15=PB8
|
||||||
Mcu.Pin16=VP_SYS_VS_tim6
|
Mcu.Pin16=PB9
|
||||||
|
Mcu.Pin17=VP_FREERTOS_VS_CMSIS_V2
|
||||||
|
Mcu.Pin18=VP_SYS_VS_tim6
|
||||||
Mcu.Pin2=PC8
|
Mcu.Pin2=PC8
|
||||||
Mcu.Pin3=PC9
|
Mcu.Pin3=PC9
|
||||||
Mcu.Pin4=PA9
|
Mcu.Pin4=PA9
|
||||||
Mcu.Pin5=PA10
|
Mcu.Pin5=PA10
|
||||||
Mcu.Pin6=PC10
|
Mcu.Pin6=PA13
|
||||||
Mcu.Pin7=PC11
|
Mcu.Pin7=PA14
|
||||||
Mcu.Pin8=PC12
|
Mcu.Pin8=PC10
|
||||||
Mcu.Pin9=PD2
|
Mcu.Pin9=PC11
|
||||||
Mcu.PinsNb=17
|
Mcu.PinsNb=19
|
||||||
Mcu.ThirdPartyNb=0
|
Mcu.ThirdPartyNb=0
|
||||||
Mcu.UserConstants=
|
Mcu.UserConstants=
|
||||||
Mcu.UserName=STM32F405RGTx
|
Mcu.UserName=STM32F405RGTx
|
||||||
@@ -113,18 +115,22 @@ NVIC.TimeBaseIP=TIM6
|
|||||||
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
|
||||||
PA10.Mode=Asynchronous
|
PA10.Mode=Asynchronous
|
||||||
PA10.Signal=USART1_RX
|
PA10.Signal=USART1_RX
|
||||||
|
PA13.Mode=Serial_Wire
|
||||||
|
PA13.Signal=SYS_JTMS-SWDIO
|
||||||
|
PA14.Mode=Serial_Wire
|
||||||
|
PA14.Signal=SYS_JTCK-SWCLK
|
||||||
PA9.Mode=Asynchronous
|
PA9.Mode=Asynchronous
|
||||||
PA9.Signal=USART1_TX
|
PA9.Signal=USART1_TX
|
||||||
PB12.Mode=CAN_Activate
|
PB12.Mode=CAN_Activate
|
||||||
PB12.Signal=CAN2_RX
|
PB12.Signal=CAN2_RX
|
||||||
PB13.Mode=CAN_Activate
|
PB13.Mode=CAN_Activate
|
||||||
PB13.Signal=CAN2_TX
|
PB13.Signal=CAN2_TX
|
||||||
PB3.Locked=true
|
|
||||||
PB3.Signal=GPIO_Output
|
|
||||||
PB4.Locked=true
|
|
||||||
PB4.Signal=GPIO_Output
|
|
||||||
PB5.Locked=true
|
PB5.Locked=true
|
||||||
PB5.Signal=GPIO_Output
|
PB5.Signal=GPIO_Output
|
||||||
|
PB6.Locked=true
|
||||||
|
PB6.Signal=GPIO_Output
|
||||||
|
PB7.Locked=true
|
||||||
|
PB7.Signal=GPIO_Output
|
||||||
PB8.Mode=CAN_Activate
|
PB8.Mode=CAN_Activate
|
||||||
PB8.Signal=CAN1_RX
|
PB8.Signal=CAN1_RX
|
||||||
PB9.Locked=true
|
PB9.Locked=true
|
||||||
|
|||||||
Reference in New Issue
Block a user