libuav original

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers thread.hpp Source File

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 }