thread.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
  3. */
  4. #pragma once
  5. #include <uavcan_stm32/build_config.hpp>
  6. #if UAVCAN_STM32_CHIBIOS
  7. # include <ch.hpp>
  8. #elif UAVCAN_STM32_NUTTX
  9. # include <nuttx/config.h>
  10. # include <nuttx/fs/fs.h>
  11. # include <poll.h>
  12. # include <errno.h>
  13. # include <cstdio>
  14. # include <ctime>
  15. # include <cstring>
  16. #elif UAVCAN_STM32_BAREMETAL
  17. #elif UAVCAN_STM32_FREERTOS
  18. # include <cmsis_os.h>
  19. #else
  20. # error "Unknown OS"
  21. #endif
  22. #include <uavcan/uavcan.hpp>
  23. namespace uavcan_stm32
  24. {
  25. class CanDriver;
  26. #if UAVCAN_STM32_CHIBIOS
  27. class BusEvent
  28. {
  29. chibios_rt::CounterSemaphore sem_;
  30. public:
  31. BusEvent(CanDriver& can_driver)
  32. : sem_(0)
  33. {
  34. (void)can_driver;
  35. }
  36. bool wait(uavcan::MonotonicDuration duration);
  37. void signal();
  38. void signalFromInterrupt();
  39. };
  40. class Mutex
  41. {
  42. chibios_rt::Mutex mtx_;
  43. public:
  44. void lock();
  45. void unlock();
  46. };
  47. #elif UAVCAN_STM32_NUTTX
  48. /**
  49. * All bus events are reported as POLLIN.
  50. */
  51. class BusEvent : uavcan::Noncopyable
  52. {
  53. static const unsigned MaxPollWaiters = 8;
  54. ::file_operations file_ops_;
  55. ::pollfd* pollset_[MaxPollWaiters];
  56. CanDriver& can_driver_;
  57. bool signal_;
  58. static int openTrampoline(::file* filp);
  59. static int closeTrampoline(::file* filp);
  60. static int pollTrampoline(::file* filp, ::pollfd* fds, bool setup);
  61. int open(::file* filp);
  62. int close(::file* filp);
  63. int poll(::file* filp, ::pollfd* fds, bool setup);
  64. int addPollWaiter(::pollfd* fds);
  65. int removePollWaiter(::pollfd* fds);
  66. public:
  67. static const char* const DevName;
  68. BusEvent(CanDriver& can_driver);
  69. ~BusEvent();
  70. bool wait(uavcan::MonotonicDuration duration);
  71. void signalFromInterrupt();
  72. };
  73. class Mutex
  74. {
  75. pthread_mutex_t mutex_;
  76. public:
  77. Mutex()
  78. {
  79. init();
  80. }
  81. int init()
  82. {
  83. return pthread_mutex_init(&mutex_, UAVCAN_NULLPTR);
  84. }
  85. int deinit()
  86. {
  87. return pthread_mutex_destroy(&mutex_);
  88. }
  89. void lock()
  90. {
  91. (void)pthread_mutex_lock(&mutex_);
  92. }
  93. void unlock()
  94. {
  95. (void)pthread_mutex_unlock(&mutex_);
  96. }
  97. };
  98. #elif UAVCAN_STM32_BAREMETAL
  99. class BusEvent
  100. {
  101. volatile bool ready;
  102. public:
  103. BusEvent(CanDriver& can_driver)
  104. : ready(false)
  105. {
  106. (void)can_driver;
  107. }
  108. bool wait(uavcan::MonotonicDuration duration)
  109. {
  110. (void)duration;
  111. bool lready = ready;
  112. #if defined ( __CC_ARM )
  113. return __sync_lock_test_and_set(&lready, false);
  114. #elif defined ( __GNUC__ )
  115. return __atomic_exchange_n (&lready, false, __ATOMIC_SEQ_CST);
  116. #else
  117. # error "This compiler is not supported"
  118. #endif
  119. }
  120. void signal()
  121. {
  122. #if defined ( __CC_ARM )
  123. __sync_lock_release(&ready);
  124. #elif defined ( __GNUC__ )
  125. __atomic_store_n (&ready, true, __ATOMIC_SEQ_CST);
  126. #else
  127. # error "This compiler is not supported"
  128. #endif
  129. }
  130. void signalFromInterrupt()
  131. {
  132. #if defined ( __CC_ARM )
  133. __sync_lock_release(&ready);
  134. #elif defined ( __GNUC__ )
  135. __atomic_store_n (&ready, true, __ATOMIC_SEQ_CST);
  136. #else
  137. # error "This compiler is not supported"
  138. #endif
  139. }
  140. };
  141. class Mutex
  142. {
  143. public:
  144. void lock() { }
  145. void unlock() { }
  146. };
  147. #elif UAVCAN_STM32_FREERTOS
  148. class BusEvent
  149. {
  150. SemaphoreHandle_t sem_;
  151. BaseType_t higher_priority_task_woken;
  152. public:
  153. BusEvent(CanDriver& can_driver)
  154. {
  155. (void)can_driver;
  156. sem_ = xSemaphoreCreateBinary();
  157. }
  158. bool wait(uavcan::MonotonicDuration duration);
  159. void signal();
  160. void signalFromInterrupt();
  161. void yieldFromISR();
  162. };
  163. class Mutex
  164. {
  165. SemaphoreHandle_t mtx_;
  166. public:
  167. Mutex(void)
  168. {
  169. mtx_ = xSemaphoreCreateMutex();
  170. }
  171. void lock();
  172. void unlock();
  173. };
  174. #endif
  175. class MutexLocker
  176. {
  177. Mutex& mutex_;
  178. public:
  179. MutexLocker(Mutex& mutex)
  180. : mutex_(mutex)
  181. {
  182. mutex_.lock();
  183. }
  184. ~MutexLocker()
  185. {
  186. mutex_.unlock();
  187. }
  188. };
  189. }