14 #if UAVCAN_STM32_CHIBIOS
28 # if (CH_KERNEL_MAJOR == 2)
29 ret = sem_.waitTimeout(TIME_IMMEDIATE);
31 ret = sem_.wait(TIME_IMMEDIATE);
36 # if (CH_KERNEL_MAJOR == 2)
37 ret = sem_.waitTimeout((usec > MaxDelayUSec) ? US2ST(MaxDelayUSec) : US2ST(usec));
38 # elif defined(MS2ST) // ChibiOS 3+
39 ret = sem_.wait((usec > MaxDelayUSec) ? US2ST(MaxDelayUSec) : US2ST(usec));
41 ret = sem_.wait(::systime_t((usec > MaxDelayUSec) ? TIME_US2I(MaxDelayUSec) : TIME_US2I(usec)));
44 # if (CH_KERNEL_MAJOR == 2)
51 void BusEvent::signal()
56 void BusEvent::signalFromInterrupt()
58 # if (CH_KERNEL_MAJOR == 2)
79 # if (CH_KERNEL_MAJOR == 2)
80 chibios_rt::BaseThread::unlockMutex();
87 #elif UAVCAN_STM32_FREERTOS
99 ret = xSemaphoreTake( sem_, ( TickType_t ) 0 );
103 ret = xSemaphoreTake( sem_, (msec > MaxDelayMSec) ? (MaxDelayMSec/portTICK_RATE_MS) : (msec/portTICK_RATE_MS));
105 return ret == pdTRUE;
108 void BusEvent::signal()
110 xSemaphoreGive( sem_ );
113 void BusEvent::signalFromInterrupt()
115 higher_priority_task_woken = pdFALSE;
117 xSemaphoreGiveFromISR( sem_, &higher_priority_task_woken );
120 void BusEvent::yieldFromISR()
122 portYIELD_FROM_ISR( higher_priority_task_woken );
130 xSemaphoreTake( mtx_, portMAX_DELAY );
135 xSemaphoreGive( mtx_ );
139 #elif UAVCAN_STM32_NUTTX
141 const unsigned BusEvent::MaxPollWaiters;
142 const char*
const BusEvent::DevName =
"/dev/uavcan/busevent";
144 int BusEvent::openTrampoline(::
file* filp)
146 return static_cast<BusEvent*
>(filp->f_inode->i_private)->open(filp);
149 int BusEvent::closeTrampoline(::
file* filp)
151 return static_cast<BusEvent*
>(filp->f_inode->i_private)->close(filp);
154 int BusEvent::pollTrampoline(::
file* filp, ::pollfd* fds,
bool setup)
156 return static_cast<BusEvent*
>(filp->f_inode->i_private)->poll(filp, fds,
setup);
159 int BusEvent::open(::
file* filp)
165 int BusEvent::close(::
file* filp)
171 int BusEvent::poll(::
file* filp, ::pollfd* fds,
bool setup)
173 CriticalSectionLocker locker;
178 ret = addPollWaiter(fds);
187 fds->revents |= fds->events & (can_driver_.hasReadableInterfaces() ? POLLIN : 0);
188 if (fds->revents != 0)
190 (void)sem_post(fds->sem);
196 ret = removePollWaiter(fds);
202 int BusEvent::addPollWaiter(::pollfd* fds)
204 for (
unsigned i = 0; i < MaxPollWaiters; i++)
215 int BusEvent::removePollWaiter(::pollfd* fds)
217 for (
unsigned i = 0; i < MaxPollWaiters; i++)
219 if (fds == pollset_[i])
228 BusEvent::BusEvent(CanDriver& can_driver)
229 : can_driver_(can_driver)
232 std::memset(&file_ops_, 0,
sizeof(file_ops_));
233 std::memset(pollset_, 0,
sizeof(pollset_));
234 file_ops_.open = &BusEvent::openTrampoline;
235 file_ops_.close = &BusEvent::closeTrampoline;
236 file_ops_.poll = &BusEvent::pollTrampoline;
238 if (register_driver(DevName, &file_ops_, 0666,
static_cast<void*
>(
this)) != 0)
244 BusEvent::~BusEvent()
246 (void)unregister_driver(DevName);
256 CriticalSectionLocker locker;
268 void BusEvent::signalFromInterrupt()
271 for (
unsigned i = 0; i < MaxPollWaiters; i++)
273 ::pollfd*
const fd = pollset_[i];
276 fd->revents |= fd->events & POLLIN;
277 if ((fd->revents != 0) && (fd->sem->semcount <= 0))
279 (void)sem_post(fd->sem);