mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-03 15:58:53 +08:00
Disabled SCE interrupts; error handling is now polling based
This commit is contained in:
@@ -117,7 +117,6 @@ class CanIface : public uavcan::ICanIface, uavcan::Noncopyable
|
|||||||
uavcan::uint32_t served_aborts_cnt_;
|
uavcan::uint32_t served_aborts_cnt_;
|
||||||
BusEvent& update_event_;
|
BusEvent& update_event_;
|
||||||
TxItem pending_tx_[NumTxMailboxes];
|
TxItem pending_tx_[NumTxMailboxes];
|
||||||
uavcan::uint8_t last_hw_error_code_;
|
|
||||||
uavcan::uint8_t peak_tx_mailbox_index_;
|
uavcan::uint8_t peak_tx_mailbox_index_;
|
||||||
const uavcan::uint8_t self_index_;
|
const uavcan::uint8_t self_index_;
|
||||||
bool had_activity_;
|
bool had_activity_;
|
||||||
@@ -155,7 +154,6 @@ public:
|
|||||||
, error_cnt_(0)
|
, error_cnt_(0)
|
||||||
, served_aborts_cnt_(0)
|
, served_aborts_cnt_(0)
|
||||||
, update_event_(update_event)
|
, update_event_(update_event)
|
||||||
, last_hw_error_code_(0)
|
|
||||||
, peak_tx_mailbox_index_(0)
|
, peak_tx_mailbox_index_(0)
|
||||||
, self_index_(self_index)
|
, self_index_(self_index)
|
||||||
, had_activity_(false)
|
, had_activity_(false)
|
||||||
@@ -174,7 +172,15 @@ public:
|
|||||||
|
|
||||||
void handleTxInterrupt(uavcan::uint64_t utc_usec);
|
void handleTxInterrupt(uavcan::uint64_t utc_usec);
|
||||||
void handleRxInterrupt(uavcan::uint8_t fifo_index, uavcan::uint64_t utc_usec);
|
void handleRxInterrupt(uavcan::uint8_t fifo_index, uavcan::uint64_t utc_usec);
|
||||||
void handleStatusChangeInterrupt();
|
|
||||||
|
/**
|
||||||
|
* This method is used to count errors and abort transmission on error if necessary.
|
||||||
|
* This functionality used to be implemented in the SCE interrupt handler, but that approach was
|
||||||
|
* generating too much processing overhead, especially on disconnected interfaces.
|
||||||
|
*
|
||||||
|
* Should be called from RX ISR, TX ISR, and select(); interrupts must be enabled.
|
||||||
|
*/
|
||||||
|
void pollErrorFlags();
|
||||||
|
|
||||||
void discardTimedOutTxMailboxes(uavcan::MonotonicTime current_time);
|
void discardTimedOutTxMailboxes(uavcan::MonotonicTime current_time);
|
||||||
|
|
||||||
@@ -200,12 +206,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
unsigned getRxQueueLength() const;
|
unsigned getRxQueueLength() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns last hardware error code (LEC field in the register ESR).
|
|
||||||
* The error code will be reset.
|
|
||||||
*/
|
|
||||||
uavcan::uint8_t yieldLastHardwareErrorCode();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this iface had at least one successful IO since previous call of this method.
|
* Whether this iface had at least one successful IO since previous call of this method.
|
||||||
* This is designed for use with iface activity LEDs.
|
* This is designed for use with iface activity LEDs.
|
||||||
|
|||||||
@@ -118,19 +118,6 @@ inline void handleRxInterrupt(uavcan::uint8_t iface_index, uavcan::uint8_t fifo_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void handleStatusChangeInterrupt(uavcan::uint8_t iface_index)
|
|
||||||
{
|
|
||||||
UAVCAN_ASSERT(iface_index < UAVCAN_STM32_NUM_IFACES);
|
|
||||||
if (ifaces[iface_index] != NULL)
|
|
||||||
{
|
|
||||||
ifaces[iface_index]->handleStatusChangeInterrupt();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UAVCAN_ASSERT(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -517,7 +504,6 @@ int CanIface::init(const uavcan::uint32_t bitrate, const OperatingMode mode)
|
|||||||
error_cnt_ = 0;
|
error_cnt_ = 0;
|
||||||
served_aborts_cnt_ = 0;
|
served_aborts_cnt_ = 0;
|
||||||
uavcan::fill_n(pending_tx_, NumTxMailboxes, TxItem());
|
uavcan::fill_n(pending_tx_, NumTxMailboxes, TxItem());
|
||||||
last_hw_error_code_ = 0;
|
|
||||||
peak_tx_mailbox_index_ = 0;
|
peak_tx_mailbox_index_ = 0;
|
||||||
had_activity_ = false;
|
had_activity_ = false;
|
||||||
|
|
||||||
@@ -547,9 +533,7 @@ int CanIface::init(const uavcan::uint32_t bitrate, const OperatingMode mode)
|
|||||||
|
|
||||||
can_->IER = bxcan::IER_TMEIE | // TX mailbox empty
|
can_->IER = bxcan::IER_TMEIE | // TX mailbox empty
|
||||||
bxcan::IER_FMPIE0 | // RX FIFO 0 is not empty
|
bxcan::IER_FMPIE0 | // RX FIFO 0 is not empty
|
||||||
bxcan::IER_FMPIE1 | // RX FIFO 1 is not empty
|
bxcan::IER_FMPIE1; // RX FIFO 1 is not empty
|
||||||
bxcan::IER_ERRIE | // General error IRQ
|
|
||||||
bxcan::IER_LECIE; // Last error code change
|
|
||||||
|
|
||||||
can_->MCR &= ~bxcan::MCR_INRQ; // Leave init mode
|
can_->MCR &= ~bxcan::MCR_INRQ; // Leave init mode
|
||||||
|
|
||||||
@@ -631,6 +615,8 @@ void CanIface::handleTxInterrupt(const uavcan::uint64_t utc_usec)
|
|||||||
handleTxMailboxInterrupt(2, txok, utc_usec);
|
handleTxMailboxInterrupt(2, txok, utc_usec);
|
||||||
}
|
}
|
||||||
update_event_.signalFromInterrupt();
|
update_event_.signalFromInterrupt();
|
||||||
|
|
||||||
|
pollErrorFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanIface::handleRxInterrupt(uavcan::uint8_t fifo_index, uavcan::uint64_t utc_usec)
|
void CanIface::handleRxInterrupt(uavcan::uint8_t fifo_index, uavcan::uint64_t utc_usec)
|
||||||
@@ -692,16 +678,17 @@ void CanIface::handleRxInterrupt(uavcan::uint8_t fifo_index, uavcan::uint64_t ut
|
|||||||
rx_queue_.push(frame, utc_usec, 0);
|
rx_queue_.push(frame, utc_usec, 0);
|
||||||
had_activity_ = true;
|
had_activity_ = true;
|
||||||
update_event_.signalFromInterrupt();
|
update_event_.signalFromInterrupt();
|
||||||
|
|
||||||
|
pollErrorFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanIface::handleStatusChangeInterrupt()
|
void CanIface::pollErrorFlags()
|
||||||
{
|
{
|
||||||
can_->MSR = bxcan::MSR_ERRI; // Clear error
|
|
||||||
|
|
||||||
const uavcan::uint8_t lec = uavcan::uint8_t((can_->ESR & bxcan::ESR_LEC_MASK) >> bxcan::ESR_LEC_SHIFT);
|
const uavcan::uint8_t lec = uavcan::uint8_t((can_->ESR & bxcan::ESR_LEC_MASK) >> bxcan::ESR_LEC_SHIFT);
|
||||||
if (lec != 0)
|
if (lec != 0)
|
||||||
{
|
{
|
||||||
last_hw_error_code_ = lec;
|
CriticalSectionLocker cs_locker;
|
||||||
|
|
||||||
can_->ESR = 0;
|
can_->ESR = 0;
|
||||||
error_cnt_++;
|
error_cnt_++;
|
||||||
|
|
||||||
@@ -790,14 +777,6 @@ unsigned CanIface::getRxQueueLength() const
|
|||||||
return rx_queue_.getLength();
|
return rx_queue_.getLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
uavcan::uint8_t CanIface::yieldLastHardwareErrorCode()
|
|
||||||
{
|
|
||||||
CriticalSectionLocker lock;
|
|
||||||
const uavcan::uint8_t val = last_hw_error_code_;
|
|
||||||
last_hw_error_code_ = 0;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CanIface::hadActivity()
|
bool CanIface::hadActivity()
|
||||||
{
|
{
|
||||||
CriticalSectionLocker lock;
|
CriticalSectionLocker lock;
|
||||||
@@ -858,8 +837,11 @@ uavcan::int16_t CanDriver::select(uavcan::CanSelectMasks& inout_masks,
|
|||||||
const uavcan::MonotonicTime time = clock::getMonotonic();
|
const uavcan::MonotonicTime time = clock::getMonotonic();
|
||||||
|
|
||||||
if0_.discardTimedOutTxMailboxes(time); // Check TX timeouts - this may release some TX slots
|
if0_.discardTimedOutTxMailboxes(time); // Check TX timeouts - this may release some TX slots
|
||||||
|
if0_.pollErrorFlags();
|
||||||
|
|
||||||
#if UAVCAN_STM32_NUM_IFACES > 1
|
#if UAVCAN_STM32_NUM_IFACES > 1
|
||||||
if1_.discardTimedOutTxMailboxes(time);
|
if1_.discardTimedOutTxMailboxes(time);
|
||||||
|
if1_.pollErrorFlags();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inout_masks = makeSelectMasks(pending_tx); // Check if we already have some of the requested events
|
inout_masks = makeSelectMasks(pending_tx); // Check if we already have some of the requested events
|
||||||
@@ -931,12 +913,10 @@ void CanDriver::initOnce()
|
|||||||
IRQ_ATTACH(STM32_IRQ_CAN1TX, can1_irq);
|
IRQ_ATTACH(STM32_IRQ_CAN1TX, can1_irq);
|
||||||
IRQ_ATTACH(STM32_IRQ_CAN1RX0, can1_irq);
|
IRQ_ATTACH(STM32_IRQ_CAN1RX0, can1_irq);
|
||||||
IRQ_ATTACH(STM32_IRQ_CAN1RX1, can1_irq);
|
IRQ_ATTACH(STM32_IRQ_CAN1RX1, can1_irq);
|
||||||
IRQ_ATTACH(STM32_IRQ_CAN1SCE, can1_irq);
|
|
||||||
# if UAVCAN_STM32_NUM_IFACES > 1
|
# if UAVCAN_STM32_NUM_IFACES > 1
|
||||||
IRQ_ATTACH(STM32_IRQ_CAN2TX, can2_irq);
|
IRQ_ATTACH(STM32_IRQ_CAN2TX, can2_irq);
|
||||||
IRQ_ATTACH(STM32_IRQ_CAN2RX0, can2_irq);
|
IRQ_ATTACH(STM32_IRQ_CAN2RX0, can2_irq);
|
||||||
IRQ_ATTACH(STM32_IRQ_CAN2RX1, can2_irq);
|
IRQ_ATTACH(STM32_IRQ_CAN2RX1, can2_irq);
|
||||||
IRQ_ATTACH(STM32_IRQ_CAN2SCE, can2_irq);
|
|
||||||
# endif
|
# endif
|
||||||
# undef IRQ_ATTACH
|
# undef IRQ_ATTACH
|
||||||
#elif UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
|
#elif UAVCAN_STM32_CHIBIOS || UAVCAN_STM32_BAREMETAL
|
||||||
@@ -945,12 +925,10 @@ void CanDriver::initOnce()
|
|||||||
nvicEnableVector(CAN1_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
nvicEnableVector(CAN1_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
||||||
nvicEnableVector(CAN1_RX0_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
nvicEnableVector(CAN1_RX0_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
||||||
nvicEnableVector(CAN1_RX1_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
nvicEnableVector(CAN1_RX1_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
||||||
nvicEnableVector(CAN1_SCE_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
|
||||||
# if UAVCAN_STM32_NUM_IFACES > 1
|
# if UAVCAN_STM32_NUM_IFACES > 1
|
||||||
nvicEnableVector(CAN2_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
nvicEnableVector(CAN2_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
||||||
nvicEnableVector(CAN2_RX0_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
nvicEnableVector(CAN2_RX0_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
||||||
nvicEnableVector(CAN2_RX1_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
nvicEnableVector(CAN2_RX1_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
||||||
nvicEnableVector(CAN2_SCE_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1050,10 +1028,6 @@ static int can1_irq(const int irq, void*)
|
|||||||
{
|
{
|
||||||
uavcan_stm32::handleRxInterrupt(0, 1);
|
uavcan_stm32::handleRxInterrupt(0, 1);
|
||||||
}
|
}
|
||||||
else if (irq == STM32_IRQ_CAN1SCE)
|
|
||||||
{
|
|
||||||
uavcan_stm32::handleStatusChangeInterrupt(0);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PANIC();
|
PANIC();
|
||||||
@@ -1077,10 +1051,6 @@ static int can2_irq(const int irq, void*)
|
|||||||
{
|
{
|
||||||
uavcan_stm32::handleRxInterrupt(1, 1);
|
uavcan_stm32::handleRxInterrupt(1, 1);
|
||||||
}
|
}
|
||||||
else if (irq == STM32_IRQ_CAN2SCE)
|
|
||||||
{
|
|
||||||
uavcan_stm32::handleStatusChangeInterrupt(1);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PANIC();
|
PANIC();
|
||||||
@@ -1114,14 +1084,6 @@ UAVCAN_STM32_IRQ_HANDLER(CAN1_RX1_IRQHandler)
|
|||||||
UAVCAN_STM32_IRQ_EPILOGUE();
|
UAVCAN_STM32_IRQ_EPILOGUE();
|
||||||
}
|
}
|
||||||
|
|
||||||
UAVCAN_STM32_IRQ_HANDLER(CAN1_SCE_IRQHandler);
|
|
||||||
UAVCAN_STM32_IRQ_HANDLER(CAN1_SCE_IRQHandler)
|
|
||||||
{
|
|
||||||
UAVCAN_STM32_IRQ_PROLOGUE();
|
|
||||||
uavcan_stm32::handleStatusChangeInterrupt(0);
|
|
||||||
UAVCAN_STM32_IRQ_EPILOGUE();
|
|
||||||
}
|
|
||||||
|
|
||||||
# if UAVCAN_STM32_NUM_IFACES > 1
|
# if UAVCAN_STM32_NUM_IFACES > 1
|
||||||
|
|
||||||
UAVCAN_STM32_IRQ_HANDLER(CAN2_TX_IRQHandler);
|
UAVCAN_STM32_IRQ_HANDLER(CAN2_TX_IRQHandler);
|
||||||
@@ -1148,14 +1110,6 @@ UAVCAN_STM32_IRQ_HANDLER(CAN2_RX1_IRQHandler)
|
|||||||
UAVCAN_STM32_IRQ_EPILOGUE();
|
UAVCAN_STM32_IRQ_EPILOGUE();
|
||||||
}
|
}
|
||||||
|
|
||||||
UAVCAN_STM32_IRQ_HANDLER(CAN2_SCE_IRQHandler);
|
|
||||||
UAVCAN_STM32_IRQ_HANDLER(CAN2_SCE_IRQHandler)
|
|
||||||
{
|
|
||||||
UAVCAN_STM32_IRQ_PROLOGUE();
|
|
||||||
uavcan_stm32::handleStatusChangeInterrupt(1);
|
|
||||||
UAVCAN_STM32_IRQ_EPILOGUE();
|
|
||||||
}
|
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
#endif // UAVCAN_STM32_NUTTX
|
#endif // UAVCAN_STM32_NUTTX
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user