You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
5.4 KiB
197 lines
5.4 KiB
/**
|
|
******************************************************************************
|
|
* @file armlib_lock_glue.c
|
|
* @author STMicroelectronics
|
|
* @brief Implementation of ARM C library lock interface
|
|
*
|
|
* @details For more information about which C functions
|
|
* need which of these lowlevel functions
|
|
* please consult the "Arm C and C++ Libraries and
|
|
* Floating-Point Support User Guide"
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
|
|
* All rights reserved.</center></h2>
|
|
*
|
|
* This software component is licensed by ST under BSD 3-Clause license,
|
|
* the "License"; You may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at:
|
|
* opensource.org/licenses/BSD-3-Clause
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
#if !defined(__CC_ARM) && !(defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
|
#error "armlib_lock_glue.c" should be used with ARM Compilers only
|
|
#endif /* !defined(__CC_ARM) && !(defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) */
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include <cmsis_compiler.h>
|
|
|
|
/* Private functions ---------------------------------------------------------*/
|
|
|
|
/**
|
|
* @brief Global Error_Handler
|
|
*/
|
|
__WEAK void Error_Handler(void)
|
|
{
|
|
/* Not used if it exists in project */
|
|
while (1);
|
|
}
|
|
|
|
#ifdef __MICROLIB
|
|
#warning Microlib does not provide mutex locks to guard against code that is not thread safe
|
|
#else
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "stm32_lock.h"
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
typedef void *mutex_t;
|
|
|
|
struct __lock
|
|
{
|
|
uint8_t initialized; /**< Flag to indicate that lock is initialized */
|
|
LockingData_t lock_data; /**< The locking data */
|
|
};
|
|
|
|
/* Private defines -----------------------------------------------------------*/
|
|
/** Maximal number of static allocated locks */
|
|
#define MAX_LOCK 8
|
|
|
|
/* Private macros ------------------------------------------------------------*/
|
|
/** Convert pointer to pointer to instance of struct __lock */
|
|
#define STM32_GET_LOCK_PTR(mutex_ptr) ((struct __lock *) *(mutex_ptr))
|
|
|
|
/** See struct __lock definition */
|
|
#define STM32_LOCK_PARAMETER(lock_ptr) (&(lock_ptr)->lock_data)
|
|
|
|
/** See struct __lock definition */
|
|
#define STM32_LOCK_INITIALIZED(lock_ptr) ((lock_ptr)->initialized)
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
/** Maximum system locks allowed by armlib */
|
|
static struct __lock static_lock[MAX_LOCK];
|
|
|
|
/** Lock for static_lock array */
|
|
static LockingData_t static_list_lock = LOCKING_DATA_INIT;
|
|
|
|
/* Private functions ---------------------------------------------------------*/
|
|
|
|
/**
|
|
* @brief Thread safety Initialization, called before main
|
|
*/
|
|
__attribute__ ((constructor)) void __armlib_thread_safety_init()
|
|
{
|
|
uint32_t index;
|
|
|
|
/* Mark all system locks as not initialized */
|
|
stm32_lock_acquire(&static_list_lock);
|
|
for (index = 0; index < STM32_LOCK_ARRAY_SIZE(static_lock); index++)
|
|
{
|
|
STM32_LOCK_INITIALIZED(&static_lock[index]) = 0;
|
|
}
|
|
stm32_lock_release(&static_list_lock);
|
|
}
|
|
|
|
/**
|
|
* @defgroup _mutex_functions ARM library locks
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief Initialize lock mutex
|
|
* @param lock The lock
|
|
* @return 0 on failure
|
|
*/
|
|
__attribute__((used)) int _mutex_initialize(mutex_t *lock)
|
|
{
|
|
if (lock != NULL)
|
|
{
|
|
uint32_t index;
|
|
|
|
stm32_lock_acquire(&static_list_lock);
|
|
for (index = 0; index < STM32_LOCK_ARRAY_SIZE(static_lock); index++)
|
|
{
|
|
if (STM32_LOCK_INITIALIZED(&static_lock[index]) == 0)
|
|
{
|
|
*lock = &static_lock[index];
|
|
STM32_LOCK_INITIALIZED(STM32_GET_LOCK_PTR(lock)) = 1;
|
|
stm32_lock_init(STM32_LOCK_PARAMETER(STM32_GET_LOCK_PTR(lock)));
|
|
stm32_lock_release(&static_list_lock);
|
|
return 1;
|
|
}
|
|
}
|
|
stm32_lock_release(&static_list_lock);
|
|
}
|
|
|
|
/* Not enough mutexes, MAX_LOCK should be incremented */
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Acquire lock mutex
|
|
* @param lock The lock
|
|
*/
|
|
__attribute__((used)) void _mutex_acquire(mutex_t *lock)
|
|
{
|
|
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
|
|
|
stm32_lock_acquire(&static_list_lock);
|
|
if (STM32_LOCK_INITIALIZED(STM32_GET_LOCK_PTR(lock)) == 1)
|
|
{
|
|
stm32_lock_acquire(STM32_LOCK_PARAMETER(STM32_GET_LOCK_PTR(lock)));
|
|
}
|
|
else
|
|
{
|
|
STM32_LOCK_BLOCK();
|
|
}
|
|
stm32_lock_release(&static_list_lock);
|
|
}
|
|
|
|
/**
|
|
* @brief Release lock mutex
|
|
* @param lock The lock
|
|
*/
|
|
__attribute__((used)) void _mutex_release(mutex_t *lock)
|
|
{
|
|
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
|
|
|
stm32_lock_acquire(&static_list_lock);
|
|
if (STM32_LOCK_INITIALIZED(STM32_GET_LOCK_PTR(lock)) == 1)
|
|
{
|
|
stm32_lock_release(STM32_LOCK_PARAMETER(STM32_GET_LOCK_PTR(lock)));
|
|
}
|
|
else
|
|
{
|
|
STM32_LOCK_BLOCK();
|
|
}
|
|
stm32_lock_release(&static_list_lock);
|
|
}
|
|
|
|
/**
|
|
* @brief Free lock mutex
|
|
* @param lock The lock
|
|
*/
|
|
__attribute__((used)) void _mutex_free(mutex_t *lock)
|
|
{
|
|
STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
|
|
|
|
stm32_lock_acquire(&static_list_lock);
|
|
if (STM32_LOCK_INITIALIZED(STM32_GET_LOCK_PTR(lock)) == 1)
|
|
{
|
|
STM32_LOCK_INITIALIZED(STM32_GET_LOCK_PTR(lock)) = 0;
|
|
}
|
|
else
|
|
{
|
|
STM32_LOCK_BLOCK();
|
|
}
|
|
stm32_lock_release(&static_list_lock);
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#endif /* __MICROLIB */
|