硬汉嵌入式论坛

 找回密码
 立即注册
查看: 484|回复: 0
收起左侧

[STM32CubeMX] STM32CubeMX生成的用于C库API多任务调用的MDK, IAR和GCC接口文件

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107262
QQ
发表于 2023-10-1 00:37:09 | 显示全部楼层 |阅读模式
勾选这个:

12.png

MDK:

[C] 纯文本查看 复制代码
/**
  ******************************************************************************
  * @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>&#169; 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 */


IAR:

[C] 纯文本查看 复制代码
/**
  ******************************************************************************
  * @file      dlib_lock_glue.c
  * @author    STMicroelectronics
  * @brief     Implementation of IAR DLib 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 lowlevel functions
  * please consult the IAR C/C++ Development Guide
  * and DLib_Threads.h
  *
  * @see [url]http://ftp.iar.se/WWWfiles/arm/webic/doc/EWARM_DevelopmentGuide.ENU.pdf[/url]
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; 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
  *
  ******************************************************************************
  */

#ifndef __ICCARM__
#error "dlib_lock_glue.c" should be used with IAR DLib only
#endif /* __ICCARM__ */

/* Includes ------------------------------------------------------------------*/
#include <DLib_Threads.h>
#include <stdio.h>
#include <stdlib.h>
#include "stm32_lock.h"

/* Private functions ---------------------------------------------------------*/

/**
  * @brief Global Error_Handler
  */
__WEAK void Error_Handler(void)
{
  /* Not used if it exists in project */
  while (1);
}

/* Private typedef -----------------------------------------------------------*/
struct __lock
{
  uint8_t initialized; /**< Flag to indicate that lock is initialized */
  LockingData_t lock_data; /**< The locking data */
};

/* Private macros ------------------------------------------------------------*/
/** Convert pointer to pointer to instance of struct __lock */
#define STM32_GET_LOCK_PTR(iar_Rmtx_ptr) ((struct __lock *) *(iar_Rmtx_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)

/** Size of array */
#define STM32_LOCK_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))

/* Private variables ---------------------------------------------------------*/
/** Maximum system locks allowed by DLib */
static __no_init struct __lock static_system_lock[_MAX_LOCK];

/** Lock for static_system_lock array */
static LockingData_t static_system_list_lock = LOCKING_DATA_INIT;

#ifdef FOPEN_MAX
/** Maximum file locks allowed by DLib */
static __no_init struct __lock static_file_lock[FOPEN_MAX];

/** Lock for static_file_lock array */
static LockingData_t static_file_list_lock = LOCKING_DATA_INIT;
#endif /* FOPEN_MAX */

/* Private functions ---------------------------------------------------------*/

/**
  * @brief Thread safety Initialization, called before main
  */
__attribute__ ((constructor)) void __dlib_thread_safety_init()
{
  uint32_t index;

  /* Mark all system locks as not initialized */
  stm32_lock_acquire(&static_system_list_lock);
  for (index = 0; index < STM32_LOCK_ARRAY_SIZE(static_system_lock); index++)
  {
    STM32_LOCK_INITIALIZED(&static_system_lock[index]) = 0;
  }
  stm32_lock_release(&static_system_list_lock);

  /* Mark all file locks as not initialized */
#ifdef FOPEN_MAX
  stm32_lock_acquire(&static_file_list_lock);
  for (index = 0; index < STM32_LOCK_ARRAY_SIZE(static_file_lock); index++)
  {
    STM32_LOCK_INITIALIZED(&static_file_lock[index]) = 0;
  }
  stm32_lock_release(&static_file_list_lock);
#endif /* FOPEN_MAX */

  /* Initialize system and file locks */
  __iar_Initlocks();

  /* Run the C++ global object constructors */
#ifdef __cplusplus
  extern void __iar_dynamic_initialization();
  __iar_dynamic_initialization();
#endif /* __cplusplus */
}

/**
  * @defgroup __iar_system_Mtx_Functions IAR system locks
  * @{
  */

/**
  * @brief Initialize a system lock
  * @param lock The lock
  */
void __iar_system_Mtxinit(__iar_Rmtx *lock)
{
  uint32_t index;

  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

  stm32_lock_acquire(&static_system_list_lock);
  for (index = 0; index < STM32_LOCK_ARRAY_SIZE(static_system_lock); index++)
  {
    if (STM32_LOCK_INITIALIZED(&static_system_lock[index]) == 0)
    {
      *lock = &static_system_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_system_list_lock);
      return;
    }
  }

  /* Not enough mutexes, this should never happen */
  STM32_LOCK_BLOCK();

  /* Release of static_system_list_lock, not possible since STM32_LOCK_BLOCK is invoked */
}

/**
  * @brief Lock a system lock
  * @param lock The lock
  */
void __iar_system_Mtxlock(__iar_Rmtx *lock)
{
  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

  stm32_lock_acquire(&static_system_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_system_list_lock);
}

/**
  * @brief Unlock a system lock
  * @param lock The lock
  */
void __iar_system_Mtxunlock(__iar_Rmtx *lock)
{
  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

  stm32_lock_acquire(&static_system_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_system_list_lock);
}

/**
  * @brief Destroy a system lock
  * @param lock The lock
  */
void __iar_system_Mtxdst(__iar_Rmtx *lock)
{
  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

  stm32_lock_acquire(&static_system_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_system_list_lock);
}

/**
  * @}
  */

/**
  * @defgroup __iar_file_Mtx_Functions IAR file locks
  * @{
  */

/**
  * @brief Initialize a file lock
  * @param lock The lock
  */
void __iar_file_Mtxinit(__iar_Rmtx *lock)
{
#ifdef FOPEN_MAX
  uint32_t index;

  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

  stm32_lock_acquire(&static_file_list_lock);
  for (index = 0; index < STM32_LOCK_ARRAY_SIZE(static_file_lock); index++)
  {
    if (STM32_LOCK_INITIALIZED(&static_file_lock[index]) == 0)
    {
      *lock = &static_file_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_file_list_lock);
      return;
    }
  }

  /* Not enough mutexes, this should never happen */
  STM32_LOCK_BLOCK();

  /* Release of static_file_lock, not possible since STM32_LOCK_BLOCK is invoked */
#else
  STM32_LOCK_UNUSED(lock);

  /* Not enough mutexes, this should never happen */
  STM32_LOCK_BLOCK();
#endif /* FOPEN_MAX */
}

/**
  * @brief Lock a file lock
  * @param lock The lock
  */
void __iar_file_Mtxlock(__iar_Rmtx *lock)
{
  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

#ifdef FOPEN_MAX
  stm32_lock_acquire(&static_file_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_file_list_lock);
#else
  STM32_LOCK_BLOCK();
#endif /* FOPEN_MAX */
}

/**
  * @brief Unlock a file lock
  * @param lock The lock
  */
void __iar_file_Mtxunlock(__iar_Rmtx *lock)
{
  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

#ifdef FOPEN_MAX
  stm32_lock_acquire(&static_file_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_file_list_lock);
#else
  STM32_LOCK_BLOCK();
#endif /* FOPEN_MAX */
}

/**
  * @brief Destroy a file lock
  * @param lock The lock
  */
void __iar_file_Mtxdst(__iar_Rmtx *lock)
{
  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

#ifdef FOPEN_MAX
  stm32_lock_acquire(&static_file_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_file_list_lock);
#else
  STM32_LOCK_BLOCK();
#endif /* FOPEN_MAX */
}

/**
  * @}
  */

/**
  * @defgroup __iar_dynamic_Mtx_Functions IAR C++ dynamic locks
  * @{
  */

/**
  * @brief Initialize a C++ dynamic lock
  * @param lock The lock
  */
void __iar_Initdynamiclock(__iar_Rmtx *lock)
{
  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

  *lock = malloc(sizeof(LockingData_t));
  if (*lock != NULL)
  {
    stm32_lock_init(*lock);
  }
  else
  {
    /* Cannot allocate memory for a new mutex */
    STM32_LOCK_BLOCK();
  }
}

/**
  * @brief Lock a C++ dynamic lock
  * @param lock The lock
  */
void __iar_Lockdynamiclock(__iar_Rmtx *lock)
{
  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

  if (*lock != NULL)
  {
    stm32_lock_acquire(*lock);
  }
  else
  {
    STM32_LOCK_BLOCK();
  }
}

/**
  * @brief Unlock a C++ dynamic lock
  * @param lock The lock
  */
void __iar_Unlockdynamiclock(__iar_Rmtx *lock)
{
  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

  if (*lock != NULL)
  {
    stm32_lock_release(*lock);
  }
  else
  {
    STM32_LOCK_BLOCK();
  }
}

/**
  * @brief Destroy a C++ dynamic lock
  * @param lock The lock
  */
void __iar_Dstdynamiclock(__iar_Rmtx *lock)
{
  STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);

  free(*lock);
  *lock = NULL;
}

/**
  * @}
  */



GCC:

[C] 纯文本查看 复制代码
/**
  ******************************************************************************
  * @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 [url]https://sourceware.org/newlib/libc.html[/url]
  *
  *            For more information about the one-time construction API for C++,
  *            see [url]https://itanium-cxx-abi.github.io/cxx-abi/abi.html#once-ctor[/url]
  *
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 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 ---------------------------------------------------------*/

/**
  * @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 [url]https://sourceware.org/newlib/libc.html[/url]
  * @{
  */

#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)

/* 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 [url]https://itanium-cxx-abi.github.io/cxx-abi/abi.html#once-ctor[/url]
  *
  * 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 ---------------------------------------------------------*/

/**
  * @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__ */

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-23 13:29 , Processed in 0.280511 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表