libuav original
Dependents: UAVCAN UAVCAN_Subscriber
thread.hpp
00001 /* 00002 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> 00003 */ 00004 00005 #pragma once 00006 00007 #include <uavcan_stm32/build_config.hpp> 00008 00009 #if UAVCAN_STM32_CHIBIOS 00010 # include <ch.hpp> 00011 #elif UAVCAN_STM32_NUTTX 00012 # include <nuttx/config.h> 00013 # include <nuttx/fs/fs.h> 00014 # include <poll.h> 00015 # include <errno.h> 00016 # include <cstdio> 00017 # include <ctime> 00018 # include <cstring> 00019 #elif UAVCAN_STM32_BAREMETAL 00020 #elif UAVCAN_STM32_FREERTOS 00021 # include <cmsis_os.h> 00022 #else 00023 # error "Unknown OS" 00024 #endif 00025 00026 #include <uavcan/uavcan.hpp> 00027 00028 namespace uavcan_stm32 00029 { 00030 00031 class CanDriver; 00032 00033 #if UAVCAN_STM32_CHIBIOS 00034 00035 class BusEvent 00036 { 00037 chibios_rt::CounterSemaphore sem_; 00038 00039 public: 00040 BusEvent(CanDriver& can_driver) 00041 : sem_(0) 00042 { 00043 (void)can_driver; 00044 } 00045 00046 bool wait(uavcan::MonotonicDuration duration); 00047 00048 void signal(); 00049 00050 void signalFromInterrupt(); 00051 }; 00052 00053 class Mutex 00054 { 00055 chibios_rt::Mutex mtx_; 00056 00057 public: 00058 void lock(); 00059 void unlock(); 00060 }; 00061 00062 #elif UAVCAN_STM32_NUTTX 00063 00064 /** 00065 * All bus events are reported as POLLIN. 00066 */ 00067 class BusEvent : uavcan::Noncopyable 00068 { 00069 static const unsigned MaxPollWaiters = 8; 00070 00071 ::file_operations file_ops_; 00072 ::pollfd* pollset_[MaxPollWaiters]; 00073 CanDriver& can_driver_; 00074 bool signal_; 00075 00076 static int openTrampoline(::file* filp); 00077 static int closeTrampoline(::file* filp); 00078 static int pollTrampoline(::file* filp, ::pollfd* fds, bool setup); 00079 00080 int open(::file* filp); 00081 int close(::file* filp); 00082 int poll(::file* filp, ::pollfd* fds, bool setup); 00083 00084 int addPollWaiter(::pollfd* fds); 00085 int removePollWaiter(::pollfd* fds); 00086 00087 public: 00088 static const char* const DevName; 00089 00090 BusEvent(CanDriver& can_driver); 00091 ~BusEvent(); 00092 00093 bool wait(uavcan::MonotonicDuration duration); 00094 00095 void signalFromInterrupt(); 00096 }; 00097 00098 class Mutex 00099 { 00100 pthread_mutex_t mutex_; 00101 00102 public: 00103 Mutex() 00104 { 00105 init(); 00106 } 00107 00108 int init() 00109 { 00110 return pthread_mutex_init(&mutex_, UAVCAN_NULLPTR); 00111 } 00112 00113 int deinit() 00114 { 00115 return pthread_mutex_destroy(&mutex_); 00116 } 00117 00118 void lock() 00119 { 00120 (void)pthread_mutex_lock(&mutex_); 00121 } 00122 00123 void unlock() 00124 { 00125 (void)pthread_mutex_unlock(&mutex_); 00126 } 00127 }; 00128 #elif UAVCAN_STM32_BAREMETAL 00129 00130 class BusEvent 00131 { 00132 volatile bool ready; 00133 00134 public: 00135 BusEvent(CanDriver& can_driver) 00136 : ready(false) 00137 { 00138 (void)can_driver; 00139 } 00140 00141 bool wait(uavcan::MonotonicDuration duration) 00142 { 00143 (void)duration; 00144 bool lready = ready; 00145 #if defined ( __CC_ARM ) 00146 return __sync_lock_test_and_set(&lready, false); 00147 #elif defined ( __GNUC__ ) 00148 return __atomic_exchange_n (&lready, false, __ATOMIC_SEQ_CST); 00149 #else 00150 # error "This compiler is not supported" 00151 #endif 00152 } 00153 00154 void signal() 00155 { 00156 #if defined ( __CC_ARM ) 00157 __sync_lock_release(&ready); 00158 #elif defined ( __GNUC__ ) 00159 __atomic_store_n (&ready, true, __ATOMIC_SEQ_CST); 00160 #else 00161 # error "This compiler is not supported" 00162 #endif 00163 } 00164 00165 void signalFromInterrupt() 00166 { 00167 #if defined ( __CC_ARM ) 00168 __sync_lock_release(&ready); 00169 #elif defined ( __GNUC__ ) 00170 __atomic_store_n (&ready, true, __ATOMIC_SEQ_CST); 00171 #else 00172 # error "This compiler is not supported" 00173 #endif 00174 } 00175 }; 00176 00177 class Mutex 00178 { 00179 public: 00180 void lock() { } 00181 void unlock() { } 00182 }; 00183 00184 #elif UAVCAN_STM32_FREERTOS 00185 00186 class BusEvent 00187 { 00188 SemaphoreHandle_t sem_; 00189 BaseType_t higher_priority_task_woken; 00190 00191 public: 00192 BusEvent(CanDriver& can_driver) 00193 { 00194 (void)can_driver; 00195 sem_ = xSemaphoreCreateBinary(); 00196 } 00197 00198 bool wait(uavcan::MonotonicDuration duration); 00199 00200 void signal(); 00201 00202 void signalFromInterrupt(); 00203 00204 void yieldFromISR(); 00205 }; 00206 00207 class Mutex 00208 { 00209 SemaphoreHandle_t mtx_; 00210 00211 public: 00212 Mutex(void) 00213 { 00214 mtx_ = xSemaphoreCreateMutex(); 00215 } 00216 void lock(); 00217 void unlock(); 00218 }; 00219 00220 #endif 00221 00222 00223 class MutexLocker 00224 { 00225 Mutex& mutex_; 00226 00227 public: 00228 MutexLocker(Mutex& mutex) 00229 : mutex_(mutex) 00230 { 00231 mutex_.lock(); 00232 } 00233 ~MutexLocker() 00234 { 00235 mutex_.unlock(); 00236 } 00237 }; 00238 00239 }
Generated on Tue Jul 12 2022 17:17:35 by 1.7.2