基质喷涂
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

3 weeks ago
  1. /**
  2. ******************************************************************************
  3. * @file armlib_lock_glue.c
  4. * @author STMicroelectronics
  5. * @brief Implementation of ARM C library lock interface
  6. *
  7. * @details For more information about which C functions
  8. * need which of these lowlevel functions
  9. * please consult the "Arm C and C++ Libraries and
  10. * Floating-Point Support User Guide"
  11. ******************************************************************************
  12. * @attention
  13. *
  14. * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  15. * All rights reserved.</center></h2>
  16. *
  17. * This software component is licensed by ST under BSD 3-Clause license,
  18. * the "License"; You may not use this file except in compliance with the
  19. * License. You may obtain a copy of the License at:
  20. * opensource.org/licenses/BSD-3-Clause
  21. *
  22. ******************************************************************************
  23. */
  24. #if !defined(__CC_ARM) && !(defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
  25. #error "armlib_lock_glue.c" should be used with ARM Compilers only
  26. #endif /* !defined(__CC_ARM) && !(defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) */
  27. /* Includes ------------------------------------------------------------------*/
  28. #include <cmsis_compiler.h>
  29. /* Private functions ---------------------------------------------------------*/
  30. /**
  31. * @brief Global Error_Handler
  32. */
  33. __WEAK void Error_Handler(void)
  34. {
  35. /* Not used if it exists in project */
  36. while (1);
  37. }
  38. #ifdef __MICROLIB
  39. #warning Microlib does not provide mutex locks to guard against code that is not thread safe
  40. #else
  41. /* Includes ------------------------------------------------------------------*/
  42. #include "stm32_lock.h"
  43. /* Private typedef -----------------------------------------------------------*/
  44. typedef void *mutex_t;
  45. struct __lock
  46. {
  47. uint8_t initialized; /**< Flag to indicate that lock is initialized */
  48. LockingData_t lock_data; /**< The locking data */
  49. };
  50. /* Private defines -----------------------------------------------------------*/
  51. /** Maximal number of static allocated locks */
  52. #define MAX_LOCK 8
  53. /* Private macros ------------------------------------------------------------*/
  54. /** Convert pointer to pointer to instance of struct __lock */
  55. #define STM32_GET_LOCK_PTR(mutex_ptr) ((struct __lock *) *(mutex_ptr))
  56. /** See struct __lock definition */
  57. #define STM32_LOCK_PARAMETER(lock_ptr) (&(lock_ptr)->lock_data)
  58. /** See struct __lock definition */
  59. #define STM32_LOCK_INITIALIZED(lock_ptr) ((lock_ptr)->initialized)
  60. /* Private variables ---------------------------------------------------------*/
  61. /** Maximum system locks allowed by armlib */
  62. static struct __lock static_lock[MAX_LOCK];
  63. /** Lock for static_lock array */
  64. static LockingData_t static_list_lock = LOCKING_DATA_INIT;
  65. /* Private functions ---------------------------------------------------------*/
  66. /**
  67. * @brief Thread safety Initialization, called before main
  68. */
  69. __attribute__ ((constructor)) void __armlib_thread_safety_init()
  70. {
  71. uint32_t index;
  72. /* Mark all system locks as not initialized */
  73. stm32_lock_acquire(&static_list_lock);
  74. for (index = 0; index < STM32_LOCK_ARRAY_SIZE(static_lock); index++)
  75. {
  76. STM32_LOCK_INITIALIZED(&static_lock[index]) = 0;
  77. }
  78. stm32_lock_release(&static_list_lock);
  79. }
  80. /**
  81. * @defgroup _mutex_functions ARM library locks
  82. * @{
  83. */
  84. /**
  85. * @brief Initialize lock mutex
  86. * @param lock The lock
  87. * @return 0 on failure
  88. */
  89. __attribute__((used)) int _mutex_initialize(mutex_t *lock)
  90. {
  91. if (lock != NULL)
  92. {
  93. uint32_t index;
  94. stm32_lock_acquire(&static_list_lock);
  95. for (index = 0; index < STM32_LOCK_ARRAY_SIZE(static_lock); index++)
  96. {
  97. if (STM32_LOCK_INITIALIZED(&static_lock[index]) == 0)
  98. {
  99. *lock = &static_lock[index];
  100. STM32_LOCK_INITIALIZED(STM32_GET_LOCK_PTR(lock)) = 1;
  101. stm32_lock_init(STM32_LOCK_PARAMETER(STM32_GET_LOCK_PTR(lock)));
  102. stm32_lock_release(&static_list_lock);
  103. return 1;
  104. }
  105. }
  106. stm32_lock_release(&static_list_lock);
  107. }
  108. /* Not enough mutexes, MAX_LOCK should be incremented */
  109. return 0;
  110. }
  111. /**
  112. * @brief Acquire lock mutex
  113. * @param lock The lock
  114. */
  115. __attribute__((used)) void _mutex_acquire(mutex_t *lock)
  116. {
  117. STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
  118. stm32_lock_acquire(&static_list_lock);
  119. if (STM32_LOCK_INITIALIZED(STM32_GET_LOCK_PTR(lock)) == 1)
  120. {
  121. stm32_lock_acquire(STM32_LOCK_PARAMETER(STM32_GET_LOCK_PTR(lock)));
  122. }
  123. else
  124. {
  125. STM32_LOCK_BLOCK();
  126. }
  127. stm32_lock_release(&static_list_lock);
  128. }
  129. /**
  130. * @brief Release lock mutex
  131. * @param lock The lock
  132. */
  133. __attribute__((used)) void _mutex_release(mutex_t *lock)
  134. {
  135. STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
  136. stm32_lock_acquire(&static_list_lock);
  137. if (STM32_LOCK_INITIALIZED(STM32_GET_LOCK_PTR(lock)) == 1)
  138. {
  139. stm32_lock_release(STM32_LOCK_PARAMETER(STM32_GET_LOCK_PTR(lock)));
  140. }
  141. else
  142. {
  143. STM32_LOCK_BLOCK();
  144. }
  145. stm32_lock_release(&static_list_lock);
  146. }
  147. /**
  148. * @brief Free lock mutex
  149. * @param lock The lock
  150. */
  151. __attribute__((used)) void _mutex_free(mutex_t *lock)
  152. {
  153. STM32_LOCK_BLOCK_IF_NULL_ARGUMENT(lock);
  154. stm32_lock_acquire(&static_list_lock);
  155. if (STM32_LOCK_INITIALIZED(STM32_GET_LOCK_PTR(lock)) == 1)
  156. {
  157. STM32_LOCK_INITIALIZED(STM32_GET_LOCK_PTR(lock)) = 0;
  158. }
  159. else
  160. {
  161. STM32_LOCK_BLOCK();
  162. }
  163. stm32_lock_release(&static_list_lock);
  164. }
  165. /**
  166. * @}
  167. */
  168. #endif /* __MICROLIB */