From 5442c0ac04700dc8ade4774ebb793592758bd67d Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Mon, 1 Jun 2015 16:36:02 +0300 Subject: [PATCH] Revert "STM32 NuttX driver: Edge-triggered poll(), sort of fixes #35" This reverts commit 22787651e699c58b18258a8cb01249b0f5f329cb. --- .../stm32/driver/include/uavcan_stm32/can.hpp | 3 +- .../driver/include/uavcan_stm32/thread.hpp | 14 +++++---- .../stm32/driver/src/uc_stm32_thread.cpp | 30 ++++++++++++++----- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/libuavcan_drivers/stm32/driver/include/uavcan_stm32/can.hpp b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/can.hpp index 170d69b820..45e022bf38 100644 --- a/libuavcan_drivers/stm32/driver/include/uavcan_stm32/can.hpp +++ b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/can.hpp @@ -194,7 +194,8 @@ class CanDriver : public uavcan::ICanDriver, uavcan::Noncopyable public: template CanDriver(CanRxItem (&rx_queue_storage)[UAVCAN_STM32_NUM_IFACES][RxQueueCapacity]) - : if0_(bxcan::Can[0], update_event_, 0, rx_queue_storage[0], RxQueueCapacity) + : update_event_(*this) + , if0_(bxcan::Can[0], update_event_, 0, rx_queue_storage[0], RxQueueCapacity) #if UAVCAN_STM32_NUM_IFACES > 1 , if1_(bxcan::Can[1], update_event_, 1, rx_queue_storage[1], RxQueueCapacity) #endif diff --git a/libuavcan_drivers/stm32/driver/include/uavcan_stm32/thread.hpp b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/thread.hpp index 5d084d6a94..d2c6869ddc 100644 --- a/libuavcan_drivers/stm32/driver/include/uavcan_stm32/thread.hpp +++ b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/thread.hpp @@ -34,9 +34,11 @@ class BusEvent chibios_rt::CounterSemaphore sem_; public: - BusEvent() + BusEvent(CanDriver& can_driver) : sem_(0) - { } + { + (void)can_driver; + } bool wait(uavcan::MonotonicDuration duration); @@ -56,15 +58,13 @@ public: #elif UAVCAN_STM32_NUTTX -/** - * All bus events are reported as POLLIN. - */ class BusEvent : uavcan::Noncopyable { static const unsigned MaxPollWaiters = 8; ::file_operations file_ops_; ::pollfd* pollset_[MaxPollWaiters]; + CanDriver& can_driver_; bool signal_; static int openTrampoline(::file* filp); @@ -75,13 +75,15 @@ class BusEvent : uavcan::Noncopyable int close(::file* filp); int poll(::file* filp, ::pollfd* fds, bool setup); + unsigned makePollMask() const; + int addPollWaiter(::pollfd* fds); int removePollWaiter(::pollfd* fds); public: static const char* const DevName; - BusEvent(); + BusEvent(CanDriver& can_driver); ~BusEvent(); bool wait(uavcan::MonotonicDuration duration); diff --git a/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp b/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp index 4c7c16927e..c24885968d 100644 --- a/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp +++ b/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp @@ -99,7 +99,7 @@ int BusEvent::poll(::file* filp, ::pollfd* fds, bool setup) ret = addPollWaiter(fds); if (ret == 0) { - fds->revents |= fds->events & POLLIN; + fds->revents |= fds->events & makePollMask(); if (fds->revents != 0) { (void)sem_post(fds->sem); @@ -114,11 +114,26 @@ int BusEvent::poll(::file* filp, ::pollfd* fds, bool setup) return ret; } +unsigned BusEvent::makePollMask() const +{ + const uavcan::CanSelectMasks select_masks = can_driver_.makeSelectMasks(); + unsigned poll_mask = 0; + if (select_masks.read != 0) + { + poll_mask |= POLLIN; + } + if (select_masks.write != 0) + { + poll_mask |= POLLOUT; + } + return poll_mask; +} + int BusEvent::addPollWaiter(::pollfd* fds) { for (unsigned i = 0; i < MaxPollWaiters; i++) { - if (pollset_[i] == NULL) + if (pollset_[i] == nullptr) { pollset_[i] = fds; return 0; @@ -133,15 +148,16 @@ int BusEvent::removePollWaiter(::pollfd* fds) { if (fds == pollset_[i]) { - pollset_[i] = NULL; + pollset_[i] = nullptr; return 0; } } return -EINVAL; } -BusEvent::BusEvent() - : signal_(false) +BusEvent::BusEvent(CanDriver& can_driver) + : can_driver_(can_driver) + , signal_(false) { std::memset(&file_ops_, 0, sizeof(file_ops_)); std::memset(pollset_, 0, sizeof(pollset_)); @@ -185,9 +201,9 @@ void BusEvent::signalFromInterrupt() for (unsigned i = 0; i < MaxPollWaiters; i++) { ::pollfd* const fd = pollset_[i]; - if (fd != NULL) + if (fd != nullptr) { - fd->revents |= fd->events & POLLIN; + fd->revents = fd->events & makePollMask(); if ((fd->revents != 0) && (fd->sem->semcount <= 0)) { (void)sem_post(fd->sem);