STM32: Fixed critical sections, removed clock interface for can driver

This commit is contained in:
Pavel Kirienko 2014-04-05 00:11:21 +04:00
parent f66338d329
commit 6341be88fd
5 changed files with 34 additions and 43 deletions

View File

@ -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); }

View File

@ -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();
}
}

View File

@ -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--;

View File

@ -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)

View File

@ -30,7 +30,9 @@ void Event::signal()
void Event::signalFromInterrupt()
{
chSysLockFromIsr();
sem_.signalI();
chSysUnlockFromIsr();
}
#endif