From 6341be88fd411e87c5c91d33305f633de4e22ffa Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 5 Apr 2014 00:11:21 +0400 Subject: [PATCH] STM32: Fixed critical sections, removed clock interface for can driver --- .../driver/include/uavcan_stm32/clock.hpp | 18 +--------- .../stm32/driver/src/internal.hpp | 17 ++++----- .../stm32/driver/src/uc_stm32_can.cpp | 4 +-- .../stm32/driver/src/uc_stm32_clock.cpp | 36 ++++++++++--------- .../stm32/driver/src/uc_stm32_thread.cpp | 2 ++ 5 files changed, 34 insertions(+), 43 deletions(-) diff --git a/libuavcan_drivers/stm32/driver/include/uavcan_stm32/clock.hpp b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/clock.hpp index 600b5f4dec..b3e6a5c1b7 100644 --- a/libuavcan_drivers/stm32/driver/include/uavcan_stm32/clock.hpp +++ b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/clock.hpp @@ -17,11 +17,6 @@ namespace clock */ void init(); -/** - * For CAN timestamping. - */ -uavcan::uint64_t getUtcUSecFromInterrupt(); - /** * For general usage. */ @@ -48,28 +43,17 @@ uavcan::uint32_t getUtcAjdustmentJumpCount(); } -/** - * Clock interface for CAN driver. - */ -class ICanTimestampingClock : public uavcan::ISystemClock -{ -public: - virtual uavcan::uint64_t getUtcUSecFromInterrupt() const = 0; -}; - /** * Trivial system clock implementation; can be redefined by the application. * Uses a simple 16-bit hardware timer for both UTC and monotonic clocks. */ -class SystemClock : public ICanTimestampingClock, uavcan::Noncopyable +class SystemClock : public uavcan::ISystemClock, uavcan::Noncopyable { SystemClock() { } public: static SystemClock& instance(); - virtual uavcan::uint64_t getUtcUSecFromInterrupt() const { return clock::getUtcUSecFromInterrupt(); } - virtual uavcan::MonotonicTime getMonotonic() const { return clock::getMonotonic(); } virtual uavcan::UtcTime getUtc() const { return clock::getUtc(); } virtual void adjustUtc(uavcan::UtcDuration adjustment) { clock::adjustUtc(adjustment); } diff --git a/libuavcan_drivers/stm32/driver/src/internal.hpp b/libuavcan_drivers/stm32/driver/src/internal.hpp index 31cd62d7e8..68ede133d4 100644 --- a/libuavcan_drivers/stm32/driver/src/internal.hpp +++ b/libuavcan_drivers/stm32/driver/src/internal.hpp @@ -21,14 +21,8 @@ #if UAVCAN_STM32_CHIBIOS # define UAVCAN_STM32_IRQ_HANDLER(id) CH_IRQ_HANDLER(id) - -# define UAVCAN_STM32_IRQ_PROLOGUE() \ - CH_IRQ_PROLOGUE(); \ - chSysLockFromIsr() - -# define UAVCAN_STM32_IRQ_EPILOGUE() \ - chSysUnlockFromIsr(); \ - CH_IRQ_EPILOGUE() +# define UAVCAN_STM32_IRQ_PROLOGUE() CH_IRQ_PROLOGUE() +# define UAVCAN_STM32_IRQ_EPILOGUE() CH_IRQ_EPILOGUE() #else @@ -93,4 +87,11 @@ struct CriticalSectionLock ~CriticalSectionLock() { chSysEnable(); } }; +namespace clock +{ + +uavcan::uint64_t getUtcUSecFromCanInterrupt(); + +} + } diff --git a/libuavcan_drivers/stm32/driver/src/uc_stm32_can.cpp b/libuavcan_drivers/stm32/driver/src/uc_stm32_can.cpp index 0fd3c6f4fc..2ed001a866 100644 --- a/libuavcan_drivers/stm32/driver/src/uc_stm32_can.cpp +++ b/libuavcan_drivers/stm32/driver/src/uc_stm32_can.cpp @@ -23,7 +23,7 @@ CanIface* ifaces[UAVCAN_STM32_NUM_IFACES] = inline void handleTxInterrupt(uavcan::uint8_t iface_index) { - uavcan::uint64_t utc_usec = clock::getUtcUSecFromInterrupt(); + uavcan::uint64_t utc_usec = clock::getUtcUSecFromCanInterrupt(); if (utc_usec > 0) { utc_usec--; @@ -41,7 +41,7 @@ inline void handleTxInterrupt(uavcan::uint8_t iface_index) inline void handleRxInterrupt(uavcan::uint8_t iface_index, uavcan::uint8_t fifo_index) { - uavcan::uint64_t utc_usec = clock::getUtcUSecFromInterrupt(); + uavcan::uint64_t utc_usec = clock::getUtcUSecFromCanInterrupt(); if (utc_usec > 0) { utc_usec--; diff --git a/libuavcan_drivers/stm32/driver/src/uc_stm32_clock.cpp b/libuavcan_drivers/stm32/driver/src/uc_stm32_clock.cpp index 33321efdce..e1eb899b54 100644 --- a/libuavcan_drivers/stm32/driver/src/uc_stm32_clock.cpp +++ b/libuavcan_drivers/stm32/driver/src/uc_stm32_clock.cpp @@ -23,9 +23,6 @@ # error "This UAVCAN_STM32_TIMER_NUMBER is not supported yet" #endif -#define TIMX_IRQ_ENABLE() TIMX->DIER = TIM_DIER_UIE -#define TIMX_IRQ_DISABLE() TIMX->DIER = 0 - namespace uavcan_stm32 { namespace clock @@ -85,13 +82,11 @@ void init() /** * Callable from any context */ -static uavcan::uint64_t sampleSpecifiedTime(const volatile uavcan::uint64_t* const value) +static uavcan::uint64_t sampleFromCriticalSection(const volatile uavcan::uint64_t* const value) { assert(initialized); assert(TIMX->DIER & TIM_DIER_UIE); - TIMX_IRQ_DISABLE(); - volatile uavcan::uint64_t time = *value; volatile uavcan::uint32_t cnt = TIMX->CNT; @@ -110,19 +105,21 @@ static uavcan::uint64_t sampleSpecifiedTime(const volatile uavcan::uint64_t* con time += USecPerOverflow; } - TIMX_IRQ_ENABLE(); - return time + cnt; } -uavcan::uint64_t getUtcUSecFromInterrupt() +uavcan::uint64_t getUtcUSecFromCanInterrupt() { - return utc_set ? sampleSpecifiedTime(&time_utc) : 0; + return utc_set ? sampleFromCriticalSection(&time_utc) : 0; } uavcan::MonotonicTime getMonotonic() { - const uavcan::uint64_t usec = sampleSpecifiedTime(&time_mono); + uavcan::uint64_t usec = 0; + { + CriticalSectionLock locker; + usec = sampleFromCriticalSection(&time_mono); + } #if !NDEBUG static uavcan::uint64_t prev_usec = 0; // Self-test assert(prev_usec <= usec); @@ -133,7 +130,16 @@ uavcan::MonotonicTime getMonotonic() uavcan::UtcTime getUtc() { - return utc_set ? uavcan::UtcTime::fromUSec(sampleSpecifiedTime(&time_utc)) : uavcan::UtcTime(); + if (utc_set) + { + uavcan::uint64_t usec = 0; + { + CriticalSectionLock locker; + usec = sampleFromCriticalSection(&time_utc); + } + return uavcan::UtcTime::fromUSec(usec); + } + return uavcan::UtcTime(); } void adjustUtc(uavcan::UtcDuration adjustment) @@ -172,15 +178,13 @@ void adjustUtc(uavcan::UtcDuration adjustment) if (adjustment.isNegative() && uavcan::uint64_t(adjustment.getAbs().toUSec()) > time_utc) { - TIMX_IRQ_DISABLE(); + CriticalSectionLock locker; time_utc = 1; - TIMX_IRQ_ENABLE(); } else { - TIMX_IRQ_DISABLE(); + CriticalSectionLock locker; time_utc += adjustment.toUSec(); - TIMX_IRQ_ENABLE(); } if (utc_set) diff --git a/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp b/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp index 4bdeedece9..69be6247c5 100644 --- a/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp +++ b/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp @@ -30,7 +30,9 @@ void Event::signal() void Event::signalFromInterrupt() { + chSysLockFromIsr(); sem_.signalI(); + chSysUnlockFromIsr(); } #endif