pm_mutex.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. #include "pm_mutex.h"
  13. #include <stdbool.h>
  14. #include <string.h>
  15. #include "nrf_error.h"
  16. #include "app_util_platform.h"
  17. /**@brief Locks the mutex defined by the mask.
  18. *
  19. * @param p_mutex pointer to the mutex storage.
  20. * @param mutex_mask the mask identifying the mutex position.
  21. *
  22. * @retval true if the mutex could be locked.
  23. * @retval false if the mutex was already locked.
  24. */
  25. static bool lock_by_mask(uint8_t * p_mutex, uint8_t mutex_mask)
  26. {
  27. bool success = false;
  28. if ( (*p_mutex & mutex_mask) == 0 )
  29. {
  30. CRITICAL_REGION_ENTER();
  31. if ( (*p_mutex & mutex_mask) == 0 )
  32. {
  33. *p_mutex |= mutex_mask;
  34. success = true;
  35. }
  36. CRITICAL_REGION_EXIT();
  37. }
  38. return ( success );
  39. }
  40. void pm_mutex_init(uint8_t * p_mutex, uint16_t mutex_size)
  41. {
  42. if (p_mutex != NULL)
  43. {
  44. memset(&p_mutex[0], 0, MUTEX_STORAGE_SIZE(mutex_size));
  45. }
  46. }
  47. bool pm_mutex_lock(uint8_t * p_mutex, uint16_t mutex_id)
  48. {
  49. if (p_mutex != NULL)
  50. {
  51. return ( lock_by_mask(&(p_mutex[mutex_id >> 3]), (1 << (mutex_id & 0x07))) );
  52. }
  53. else
  54. {
  55. return false;
  56. }
  57. }
  58. void pm_mutex_unlock(uint8_t * p_mutex, uint16_t mutex_id)
  59. {
  60. uint8_t mutex_base = mutex_id >> 3;
  61. uint8_t mutex_mask = (1 << (mutex_id & 0x07));
  62. if ((p_mutex != NULL)
  63. && (p_mutex[mutex_base] & mutex_mask))
  64. {
  65. CRITICAL_REGION_ENTER();
  66. p_mutex[mutex_base] &= ~mutex_mask;
  67. CRITICAL_REGION_EXIT();
  68. }
  69. }
  70. uint16_t pm_mutex_lock_first_available(uint8_t * p_mutex, uint16_t mutex_size)
  71. {
  72. if (p_mutex != NULL)
  73. {
  74. for ( uint16_t i = 0; i < mutex_size; i++ )
  75. {
  76. if ( lock_by_mask(&(p_mutex[i >> 3]), 1 << (i & 0x07)) )
  77. {
  78. return ( i );
  79. }
  80. }
  81. }
  82. return ( mutex_size );
  83. }
  84. bool pm_mutex_lock_status_get(uint8_t * p_mutex, uint16_t mutex_id)
  85. {
  86. if (p_mutex != NULL)
  87. {
  88. return ( (p_mutex[mutex_id >> 3] & (1 << (mutex_id & 0x07))) );
  89. }
  90. else
  91. {
  92. return true;
  93. }
  94. }