Correct CAN baud rates for SAEJ1939 and enable silent mode
- Silent mode is also enabled by hardware (TJA1050) but better safe than sorry - Baud rates are 500kbps for primary bus and 250kpbs for secondary bus
This commit is contained in:
@@ -0,0 +1,435 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @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__ */
|
||||
@@ -0,0 +1,375 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32_lock.h
|
||||
* @author STMicroelectronics
|
||||
* @brief STMicroelectronics lock mechanisms
|
||||
*
|
||||
* @details
|
||||
* This implementation supports the following strategies for handling
|
||||
* thread-safe locks. The strategy can be explicitly selected by
|
||||
* defining <tt>\STM32_THREAD_SAFE_STRATEGY = \<number></tt> in the project.
|
||||
* Please look at the '<toolchain/library>_lock_glue.c' file for more details.
|
||||
*
|
||||
* 1. User defined thread-safe implementation.
|
||||
* User defined solution for handling thread-safety.
|
||||
* <br>
|
||||
* <b>NOTE:</b> The stubs in stm32_lock_user.h needs to be implemented to gain
|
||||
* thread-safety.
|
||||
*
|
||||
* 2. [<b>DEFAULT</b>] Allow lock usage from interrupts.
|
||||
* This implementation will ensure thread-safety by disabling all interrupts
|
||||
* during e.g. calls to malloc.
|
||||
* <br>
|
||||
* <b>NOTE:</b> Disabling all interrupts creates interrupt latency which
|
||||
* might not be desired for this application!
|
||||
*
|
||||
* 3. Deny lock usage from interrupts.
|
||||
* This implementation assumes single thread of execution.
|
||||
* <br>
|
||||
* <b>NOTE:</b> Thread-safety dependent functions will enter an infinity loop
|
||||
* if used in interrupt context.
|
||||
*
|
||||
* 4. Allow lock usage from interrupts. Implemented using FreeRTOS locks.
|
||||
* This implementation will ensure thread-safety by entering RTOS ISR capable
|
||||
* critical sections during e.g. calls to malloc.
|
||||
* By default this implementation supports 2 levels of recursive locking.
|
||||
* Adding additional levels requires 4 bytes per lock per level of RAM.
|
||||
* <br>
|
||||
* <b>NOTE:</b> Interrupts with high priority are not disabled. This implies
|
||||
* that the lock is not thread-safe from high priority interrupts!
|
||||
*
|
||||
* 5. Deny lock usage from interrupts. Implemented using FreeRTOS locks.
|
||||
* This implementation will ensure thread-safety by suspending all tasks
|
||||
* during e.g. calls to malloc.
|
||||
* <br>
|
||||
* <b>NOTE:</b> Thread-safety dependent functions will enter an infinity loop
|
||||
* if used in interrupt context.
|
||||
*
|
||||
******************************************************************************
|
||||
* @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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __STM32_LOCK_H__
|
||||
#define __STM32_LOCK_H__
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <cmsis_compiler.h>
|
||||
|
||||
#ifndef STM32_THREAD_SAFE_STRATEGY
|
||||
#define STM32_THREAD_SAFE_STRATEGY 2 /**< Assume strategy 2 if not specified */
|
||||
#endif /* STM32_THREAD_SAFE_STRATEGY */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* Function prototypes -------------------------------------------------------*/
|
||||
void Error_Handler(void);
|
||||
|
||||
/* Public macros -------------------------------------------------------------*/
|
||||
/** Blocks execution */
|
||||
#define STM32_LOCK_BLOCK() \
|
||||
do \
|
||||
{ \
|
||||
__disable_irq(); \
|
||||
Error_Handler(); \
|
||||
while (1); \
|
||||
} while (0)
|
||||
|
||||
/** Blocks execution if argument is NULL */
|
||||
#define STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(x) \
|
||||
do \
|
||||
{ \
|
||||
if ((x) == NULL) \
|
||||
{ \
|
||||
STM32_LOCK_BLOCK(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/** Blocks execution if in interrupt context */
|
||||
#define STM32_LOCK_BLOCK_IF_INTERRUPT_CONTEXT() \
|
||||
do \
|
||||
{ \
|
||||
if (__get_IPSR()) \
|
||||
{ \
|
||||
STM32_LOCK_BLOCK(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/** Hide unused parameter warning from compiler */
|
||||
#define STM32_LOCK_UNUSED(var) (void)var
|
||||
|
||||
/** Size of array */
|
||||
#define STM32_LOCK_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
|
||||
|
||||
#if STM32_THREAD_SAFE_STRATEGY == 1
|
||||
/*
|
||||
* User defined thread-safe implementation.
|
||||
*/
|
||||
|
||||
/* Includes ----------------------------------------------------------------*/
|
||||
/** STM32 lock API version */
|
||||
#define STM32_LOCK_API 1
|
||||
#include "stm32_lock_user.h"
|
||||
#undef STM32_LOCK_API
|
||||
|
||||
#elif STM32_THREAD_SAFE_STRATEGY == 2
|
||||
/*
|
||||
* Allow lock usage from interrupts.
|
||||
*/
|
||||
|
||||
/* Private defines ---------------------------------------------------------*/
|
||||
/** Initialize members in instance of <code>LockingData_t</code> structure */
|
||||
#define LOCKING_DATA_INIT { 0, 0 }
|
||||
|
||||
/* Private typedef ---------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t flag; /**< Backup of PRIMASK.PM at nesting level 0 */
|
||||
uint8_t counter; /**< Nesting level */
|
||||
} LockingData_t;
|
||||
|
||||
/* Private functions -------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initialize STM32 lock
|
||||
* @param lock The lock to init
|
||||
*/
|
||||
static inline void stm32_lock_init(LockingData_t *lock)
|
||||
{
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
lock->flag = 0;
|
||||
lock->counter = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Acquire STM32 lock
|
||||
* @param lock The lock to acquire
|
||||
*/
|
||||
static inline void stm32_lock_acquire(LockingData_t *lock)
|
||||
{
|
||||
uint8_t flag = (uint8_t)(__get_PRIMASK() & 0x1); /* PRIMASK.PM */
|
||||
__disable_irq();
|
||||
__DSB();
|
||||
__ISB();
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
if (lock->counter == 0)
|
||||
{
|
||||
lock->flag = flag;
|
||||
}
|
||||
else if (lock->counter == UINT8_MAX)
|
||||
{
|
||||
STM32_LOCK_BLOCK();
|
||||
}
|
||||
lock->counter++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release STM32 lock
|
||||
* @param lock The lock to release
|
||||
*/
|
||||
static inline void stm32_lock_release(LockingData_t *lock)
|
||||
{
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
if (lock->counter == 0)
|
||||
{
|
||||
STM32_LOCK_BLOCK();
|
||||
}
|
||||
lock->counter--;
|
||||
if (lock->counter == 0 && lock->flag == 0)
|
||||
{
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
|
||||
#elif STM32_THREAD_SAFE_STRATEGY == 3
|
||||
/*
|
||||
* Deny lock usage from interrupts.
|
||||
*/
|
||||
|
||||
/* Private defines ---------------------------------------------------------*/
|
||||
/** Initialize members in instance of <code>LockingData_t</code> structure */
|
||||
#define LOCKING_DATA_INIT 0
|
||||
|
||||
/* Private typedef ---------------------------------------------------------*/
|
||||
typedef uint8_t LockingData_t; /**< Unused */
|
||||
|
||||
/* Private functions -------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initialize STM32 lock
|
||||
* @param lock The lock to init
|
||||
*/
|
||||
static inline void stm32_lock_init(LockingData_t *lock)
|
||||
{
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Acquire STM32 lock
|
||||
* @param lock The lock to acquire
|
||||
*/
|
||||
static inline void stm32_lock_acquire(LockingData_t *lock)
|
||||
{
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
STM32_LOCK_BLOCK_IF_INTERRUPT_CONTEXT();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release ST lock
|
||||
* @param lock The lock to release
|
||||
*/
|
||||
static inline void stm32_lock_release(LockingData_t *lock)
|
||||
{
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
STM32_LOCK_BLOCK_IF_INTERRUPT_CONTEXT();
|
||||
}
|
||||
|
||||
#elif STM32_THREAD_SAFE_STRATEGY == 4
|
||||
/*
|
||||
* Allow lock usage from interrupts. Implemented using FreeRTOS locks.
|
||||
*/
|
||||
|
||||
/* Includes ----------------------------------------------------------------*/
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
|
||||
#if defined (__GNUC__) && !defined (__CC_ARM) && configUSE_NEWLIB_REENTRANT == 0
|
||||
#warning Please set configUSE_NEWLIB_REENTRANT to 1 in FreeRTOSConfig.h, otherwise newlib will not be thread-safe
|
||||
#endif /* defined (__GNUC__) && !defined (__CC_ARM) && configUSE_NEWLIB_REENTRANT == 0 */
|
||||
|
||||
/* Private defines ---------------------------------------------------------*/
|
||||
/** Initialize members in instance of <code>LockingData_t</code> structure */
|
||||
#define LOCKING_DATA_INIT { {0, 0}, 0 }
|
||||
#define STM32_LOCK_MAX_NESTED_LEVELS 2 /**< Max nesting level of interrupts */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t basepri[STM32_LOCK_MAX_NESTED_LEVELS];
|
||||
uint8_t nesting_level;
|
||||
} LockingData_t;
|
||||
|
||||
/* Private macros ----------------------------------------------------------*/
|
||||
/** Blocks execution if reached max nesting level */
|
||||
#define STM32_LOCK_ASSERT_VALID_NESTING_LEVEL(lock) \
|
||||
do \
|
||||
{ \
|
||||
if (lock->nesting_level >= STM32_LOCK_ARRAY_SIZE(lock->basepri)) \
|
||||
{ \
|
||||
STM32_LOCK_BLOCK(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Private functions -------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initialize STM32 lock
|
||||
* @param lock The lock to init
|
||||
*/
|
||||
static inline void stm32_lock_init(LockingData_t *lock)
|
||||
{
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
for (size_t i = 0; i < STM32_LOCK_ARRAY_SIZE(lock->basepri); i++)
|
||||
{
|
||||
lock->basepri[i] = 0;
|
||||
}
|
||||
lock->nesting_level = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Acquire STM32 lock
|
||||
* @param lock The lock to acquire
|
||||
*/
|
||||
static inline void stm32_lock_acquire(LockingData_t *lock)
|
||||
{
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
STM32_LOCK_ASSERT_VALID_NESTING_LEVEL(lock);
|
||||
lock->basepri[lock->nesting_level++] = taskENTER_CRITICAL_FROM_ISR();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release STM32 lock
|
||||
* @param lock The lock to release
|
||||
*/
|
||||
static inline void stm32_lock_release(LockingData_t *lock)
|
||||
{
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
lock->nesting_level--;
|
||||
STM32_LOCK_ASSERT_VALID_NESTING_LEVEL(lock);
|
||||
taskEXIT_CRITICAL_FROM_ISR(lock->basepri[lock->nesting_level]);
|
||||
}
|
||||
|
||||
#undef STM32_LOCK_ASSERT_VALID_NESTING_LEVEL
|
||||
#undef STM32_LOCK_MAX_NESTED_LEVELS
|
||||
|
||||
#elif STM32_THREAD_SAFE_STRATEGY == 5
|
||||
/*
|
||||
* Deny lock usage from interrupts. Implemented using FreeRTOS locks.
|
||||
*/
|
||||
|
||||
/* Includes ----------------------------------------------------------------*/
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#if defined (__GNUC__) && !defined (__CC_ARM) && configUSE_NEWLIB_REENTRANT == 0
|
||||
#warning Please set configUSE_NEWLIB_REENTRANT to 1 in FreeRTOSConfig.h, otherwise newlib will not be thread-safe
|
||||
#endif /* defined (__GNUC__) && !defined (__CC_ARM) && configUSE_NEWLIB_REENTRANT == 0 */
|
||||
|
||||
/* Private defines ---------------------------------------------------------*/
|
||||
/** Initialize members in instance of <code>LockingData_t</code> structure */
|
||||
#define LOCKING_DATA_INIT 0
|
||||
|
||||
/* Private typedef ---------------------------------------------------------*/
|
||||
typedef uint8_t LockingData_t; /**< Unused */
|
||||
|
||||
/* Private functions -------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initialize STM32 lock
|
||||
* @param lock The lock to init
|
||||
*/
|
||||
static inline void stm32_lock_init(LockingData_t *lock)
|
||||
{
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Acquire STM32 lock
|
||||
* @param lock The lock to acquire
|
||||
*/
|
||||
static inline void stm32_lock_acquire(LockingData_t *lock)
|
||||
{
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
STM32_LOCK_BLOCK_IF_INTERRUPT_CONTEXT();
|
||||
vTaskSuspendAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release STM32 lock
|
||||
* @param lock The lock to release
|
||||
*/
|
||||
static inline void stm32_lock_release(LockingData_t *lock)
|
||||
{
|
||||
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
||||
STM32_LOCK_BLOCK_IF_INTERRUPT_CONTEXT();
|
||||
xTaskResumeAll();
|
||||
}
|
||||
|
||||
#else
|
||||
#error Invalid STM32_THREAD_SAFE_STRATEGY specified
|
||||
#endif /* STM32_THREAD_SAFE_STRATEGY */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __STM32_LOCK_H__ */
|
||||
+22
-12
@@ -223,11 +223,11 @@ static void MX_CAN1_Init(void)
|
||||
|
||||
/* USER CODE END CAN1_Init 1 */
|
||||
hcan1.Instance = CAN1;
|
||||
hcan1.Init.Prescaler = 16;
|
||||
hcan1.Init.Mode = CAN_MODE_NORMAL;
|
||||
hcan1.Init.Prescaler = 4;
|
||||
hcan1.Init.Mode = CAN_MODE_SILENT;
|
||||
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
|
||||
hcan1.Init.TimeSeg1 = CAN_BS1_1TQ;
|
||||
hcan1.Init.TimeSeg2 = CAN_BS2_1TQ;
|
||||
hcan1.Init.TimeSeg1 = CAN_BS1_16TQ;
|
||||
hcan1.Init.TimeSeg2 = CAN_BS2_4TQ;
|
||||
hcan1.Init.TimeTriggeredMode = DISABLE;
|
||||
hcan1.Init.AutoBusOff = DISABLE;
|
||||
hcan1.Init.AutoWakeUp = DISABLE;
|
||||
@@ -260,11 +260,11 @@ static void MX_CAN2_Init(void)
|
||||
|
||||
/* USER CODE END CAN2_Init 1 */
|
||||
hcan2.Instance = CAN2;
|
||||
hcan2.Init.Prescaler = 16;
|
||||
hcan2.Init.Mode = CAN_MODE_NORMAL;
|
||||
hcan2.Init.Prescaler = 8;
|
||||
hcan2.Init.Mode = CAN_MODE_SILENT;
|
||||
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
|
||||
hcan2.Init.TimeSeg1 = CAN_BS1_1TQ;
|
||||
hcan2.Init.TimeSeg2 = CAN_BS2_1TQ;
|
||||
hcan2.Init.TimeSeg1 = CAN_BS1_16TQ;
|
||||
hcan2.Init.TimeSeg2 = CAN_BS2_4TQ;
|
||||
hcan2.Init.TimeTriggeredMode = DISABLE;
|
||||
hcan2.Init.AutoBusOff = DISABLE;
|
||||
hcan2.Init.AutoWakeUp = DISABLE;
|
||||
@@ -355,6 +355,9 @@ static void MX_GPIO_Init(void)
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pins : PC13 PC14 PC15 PC0
|
||||
PC1 PC2 PC3 PC4
|
||||
PC5 PC6 PC7 */
|
||||
@@ -384,15 +387,22 @@ static void MX_GPIO_Init(void)
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : PB0 PB1 PB2 PB10
|
||||
PB11 PB14 PB15 PB3
|
||||
PB4 PB5 PB6 PB7 */
|
||||
PB11 PB14 PB15 PB6
|
||||
PB7 */
|
||||
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_3
|
||||
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
|
||||
|GPIO_PIN_11|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_6
|
||||
|GPIO_PIN_7;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : PB3 PB4 PB5 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN MX_GPIO_Init_2 */
|
||||
|
||||
/* USER CODE END MX_GPIO_Init_2 */
|
||||
|
||||
+30
-17
@@ -2,18 +2,22 @@
|
||||
CAD.formats=
|
||||
CAD.pinconfig=
|
||||
CAD.provider=
|
||||
CAN1.BS1=CAN_BS1_1TQ
|
||||
CAN1.BS2=CAN_BS2_1TQ
|
||||
CAN1.CalculateBaudRate=875000
|
||||
CAN1.CalculateTimeBit=1142
|
||||
CAN1.CalculateTimeQuantum=380.95238095238096
|
||||
CAN1.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate,BS1,BS2
|
||||
CAN2.BS1=CAN_BS1_1TQ
|
||||
CAN2.BS2=CAN_BS2_1TQ
|
||||
CAN2.CalculateBaudRate=875000
|
||||
CAN2.CalculateTimeBit=1142
|
||||
CAN2.CalculateTimeQuantum=380.95238095238096
|
||||
CAN2.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate,BS1,BS2
|
||||
CAN1.BS1=CAN_BS1_16TQ
|
||||
CAN1.BS2=CAN_BS2_4TQ
|
||||
CAN1.CalculateBaudRate=500000
|
||||
CAN1.CalculateTimeBit=2000
|
||||
CAN1.CalculateTimeQuantum=95.23809523809524
|
||||
CAN1.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate,BS1,Prescaler,BS2,Mode
|
||||
CAN1.Mode=CAN_MODE_SILENT
|
||||
CAN1.Prescaler=4
|
||||
CAN2.BS1=CAN_BS1_16TQ
|
||||
CAN2.BS2=CAN_BS2_4TQ
|
||||
CAN2.CalculateBaudRate=250000
|
||||
CAN2.CalculateTimeBit=4000
|
||||
CAN2.CalculateTimeQuantum=190.47619047619048
|
||||
CAN2.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate,BS1,Prescaler,BS2,Mode
|
||||
CAN2.Mode=CAN_MODE_SILENT
|
||||
CAN2.Prescaler=8
|
||||
Dma.Request0=SDIO_RX
|
||||
Dma.Request1=SDIO_TX
|
||||
Dma.RequestsNb=2
|
||||
@@ -64,17 +68,20 @@ Mcu.Name=STM32F405RGTx
|
||||
Mcu.Package=LQFP64
|
||||
Mcu.Pin0=PB12
|
||||
Mcu.Pin1=PB13
|
||||
Mcu.Pin10=VP_FREERTOS_VS_CMSIS_V2
|
||||
Mcu.Pin11=VP_SYS_VS_tim6
|
||||
Mcu.Pin10=PB5
|
||||
Mcu.Pin11=PB8
|
||||
Mcu.Pin12=PB9
|
||||
Mcu.Pin13=VP_FREERTOS_VS_CMSIS_V2
|
||||
Mcu.Pin14=VP_SYS_VS_tim6
|
||||
Mcu.Pin2=PC8
|
||||
Mcu.Pin3=PC9
|
||||
Mcu.Pin4=PC10
|
||||
Mcu.Pin5=PC11
|
||||
Mcu.Pin6=PC12
|
||||
Mcu.Pin7=PD2
|
||||
Mcu.Pin8=PB8
|
||||
Mcu.Pin9=PB9
|
||||
Mcu.PinsNb=12
|
||||
Mcu.Pin8=PB3
|
||||
Mcu.Pin9=PB4
|
||||
Mcu.PinsNb=15
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32F405RGTx
|
||||
@@ -104,6 +111,12 @@ PB12.Mode=CAN_Activate
|
||||
PB12.Signal=CAN2_RX
|
||||
PB13.Mode=CAN_Activate
|
||||
PB13.Signal=CAN2_TX
|
||||
PB3.Locked=true
|
||||
PB3.Signal=GPIO_Output
|
||||
PB4.Locked=true
|
||||
PB4.Signal=GPIO_Output
|
||||
PB5.Locked=true
|
||||
PB5.Signal=GPIO_Output
|
||||
PB8.Mode=CAN_Activate
|
||||
PB8.Signal=CAN1_RX
|
||||
PB9.Locked=true
|
||||
|
||||
Reference in New Issue
Block a user