mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-28 07:33:35 +08:00
STM32: Fixed critical sections, removed clock interface for can driver
This commit is contained in:
@@ -17,11 +17,6 @@ namespace clock
|
|||||||
*/
|
*/
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
/**
|
|
||||||
* For CAN timestamping.
|
|
||||||
*/
|
|
||||||
uavcan::uint64_t getUtcUSecFromInterrupt();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For general usage.
|
* 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.
|
* Trivial system clock implementation; can be redefined by the application.
|
||||||
* Uses a simple 16-bit hardware timer for both UTC and monotonic clocks.
|
* 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() { }
|
SystemClock() { }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static SystemClock& instance();
|
static SystemClock& instance();
|
||||||
|
|
||||||
virtual uavcan::uint64_t getUtcUSecFromInterrupt() const { return clock::getUtcUSecFromInterrupt(); }
|
|
||||||
|
|
||||||
virtual uavcan::MonotonicTime getMonotonic() const { return clock::getMonotonic(); }
|
virtual uavcan::MonotonicTime getMonotonic() const { return clock::getMonotonic(); }
|
||||||
virtual uavcan::UtcTime getUtc() const { return clock::getUtc(); }
|
virtual uavcan::UtcTime getUtc() const { return clock::getUtc(); }
|
||||||
virtual void adjustUtc(uavcan::UtcDuration adjustment) { clock::adjustUtc(adjustment); }
|
virtual void adjustUtc(uavcan::UtcDuration adjustment) { clock::adjustUtc(adjustment); }
|
||||||
|
|||||||
@@ -21,14 +21,8 @@
|
|||||||
#if UAVCAN_STM32_CHIBIOS
|
#if UAVCAN_STM32_CHIBIOS
|
||||||
|
|
||||||
# define UAVCAN_STM32_IRQ_HANDLER(id) CH_IRQ_HANDLER(id)
|
# define UAVCAN_STM32_IRQ_HANDLER(id) CH_IRQ_HANDLER(id)
|
||||||
|
# define UAVCAN_STM32_IRQ_PROLOGUE() CH_IRQ_PROLOGUE()
|
||||||
# define UAVCAN_STM32_IRQ_PROLOGUE() \
|
# define UAVCAN_STM32_IRQ_EPILOGUE() CH_IRQ_EPILOGUE()
|
||||||
CH_IRQ_PROLOGUE(); \
|
|
||||||
chSysLockFromIsr()
|
|
||||||
|
|
||||||
# define UAVCAN_STM32_IRQ_EPILOGUE() \
|
|
||||||
chSysUnlockFromIsr(); \
|
|
||||||
CH_IRQ_EPILOGUE()
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -93,4 +87,11 @@ struct CriticalSectionLock
|
|||||||
~CriticalSectionLock() { chSysEnable(); }
|
~CriticalSectionLock() { chSysEnable(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace clock
|
||||||
|
{
|
||||||
|
|
||||||
|
uavcan::uint64_t getUtcUSecFromCanInterrupt();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ CanIface* ifaces[UAVCAN_STM32_NUM_IFACES] =
|
|||||||
|
|
||||||
inline void handleTxInterrupt(uavcan::uint8_t iface_index)
|
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)
|
if (utc_usec > 0)
|
||||||
{
|
{
|
||||||
utc_usec--;
|
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)
|
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)
|
if (utc_usec > 0)
|
||||||
{
|
{
|
||||||
utc_usec--;
|
utc_usec--;
|
||||||
|
|||||||
@@ -23,9 +23,6 @@
|
|||||||
# error "This UAVCAN_STM32_TIMER_NUMBER is not supported yet"
|
# error "This UAVCAN_STM32_TIMER_NUMBER is not supported yet"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TIMX_IRQ_ENABLE() TIMX->DIER = TIM_DIER_UIE
|
|
||||||
#define TIMX_IRQ_DISABLE() TIMX->DIER = 0
|
|
||||||
|
|
||||||
namespace uavcan_stm32
|
namespace uavcan_stm32
|
||||||
{
|
{
|
||||||
namespace clock
|
namespace clock
|
||||||
@@ -85,13 +82,11 @@ void init()
|
|||||||
/**
|
/**
|
||||||
* Callable from any context
|
* 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(initialized);
|
||||||
assert(TIMX->DIER & TIM_DIER_UIE);
|
assert(TIMX->DIER & TIM_DIER_UIE);
|
||||||
|
|
||||||
TIMX_IRQ_DISABLE();
|
|
||||||
|
|
||||||
volatile uavcan::uint64_t time = *value;
|
volatile uavcan::uint64_t time = *value;
|
||||||
volatile uavcan::uint32_t cnt = TIMX->CNT;
|
volatile uavcan::uint32_t cnt = TIMX->CNT;
|
||||||
|
|
||||||
@@ -110,19 +105,21 @@ static uavcan::uint64_t sampleSpecifiedTime(const volatile uavcan::uint64_t* con
|
|||||||
time += USecPerOverflow;
|
time += USecPerOverflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMX_IRQ_ENABLE();
|
|
||||||
|
|
||||||
return time + cnt;
|
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()
|
uavcan::MonotonicTime getMonotonic()
|
||||||
{
|
{
|
||||||
const uavcan::uint64_t usec = sampleSpecifiedTime(&time_mono);
|
uavcan::uint64_t usec = 0;
|
||||||
|
{
|
||||||
|
CriticalSectionLock locker;
|
||||||
|
usec = sampleFromCriticalSection(&time_mono);
|
||||||
|
}
|
||||||
#if !NDEBUG
|
#if !NDEBUG
|
||||||
static uavcan::uint64_t prev_usec = 0; // Self-test
|
static uavcan::uint64_t prev_usec = 0; // Self-test
|
||||||
assert(prev_usec <= usec);
|
assert(prev_usec <= usec);
|
||||||
@@ -133,7 +130,16 @@ uavcan::MonotonicTime getMonotonic()
|
|||||||
|
|
||||||
uavcan::UtcTime getUtc()
|
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)
|
void adjustUtc(uavcan::UtcDuration adjustment)
|
||||||
@@ -172,15 +178,13 @@ void adjustUtc(uavcan::UtcDuration adjustment)
|
|||||||
if (adjustment.isNegative() &&
|
if (adjustment.isNegative() &&
|
||||||
uavcan::uint64_t(adjustment.getAbs().toUSec()) > time_utc)
|
uavcan::uint64_t(adjustment.getAbs().toUSec()) > time_utc)
|
||||||
{
|
{
|
||||||
TIMX_IRQ_DISABLE();
|
CriticalSectionLock locker;
|
||||||
time_utc = 1;
|
time_utc = 1;
|
||||||
TIMX_IRQ_ENABLE();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TIMX_IRQ_DISABLE();
|
CriticalSectionLock locker;
|
||||||
time_utc += adjustment.toUSec();
|
time_utc += adjustment.toUSec();
|
||||||
TIMX_IRQ_ENABLE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utc_set)
|
if (utc_set)
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ void Event::signal()
|
|||||||
|
|
||||||
void Event::signalFromInterrupt()
|
void Event::signalFromInterrupt()
|
||||||
{
|
{
|
||||||
|
chSysLockFromIsr();
|
||||||
sem_.signalI();
|
sem_.signalI();
|
||||||
|
chSysUnlockFromIsr();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user