uavcan:Support runtime setting of CAN interfaces

This commit is contained in:
David Sidrane
2020-03-10 15:53:16 -07:00
committed by Daniel Agar
parent 82ab1413fc
commit 4b9e6964f4
4 changed files with 34 additions and 24 deletions
@@ -340,7 +340,7 @@ public:
CanDriver driver; CanDriver driver;
CanInitHelper() : CanInitHelper(uint32_t unused = 0x7) :
driver(queue_storage_) driver(queue_storage_)
{ {
} }
@@ -234,6 +234,7 @@ class CanDriver : public uavcan::ICanDriver, uavcan::Noncopyable
#if UAVCAN_STM32_NUM_IFACES > 1 #if UAVCAN_STM32_NUM_IFACES > 1
CanIface if1_; CanIface if1_;
#endif #endif
uint32_t enabledInterfaces_;
virtual uavcan::int16_t select(uavcan::CanSelectMasks &inout_masks, virtual uavcan::int16_t select(uavcan::CanSelectMasks &inout_masks,
const uavcan::CanFrame * (& pending_tx)[uavcan::MaxCanIfaces], const uavcan::CanFrame * (& pending_tx)[uavcan::MaxCanIfaces],
@@ -249,6 +250,7 @@ public:
#if UAVCAN_STM32_NUM_IFACES > 1 #if UAVCAN_STM32_NUM_IFACES > 1
, if1_(bxcan::Can[1], update_event_, 1, rx_queue_storage[1], RxQueueCapacity) , if1_(bxcan::Can[1], update_event_, 1, rx_queue_storage[1], RxQueueCapacity)
#endif #endif
, enabledInterfaces_(0x7)
{ {
uavcan::StaticAssert < (RxQueueCapacity <= CanIface::MaxRxQueueCapacity) >::check(); uavcan::StaticAssert < (RxQueueCapacity <= CanIface::MaxRxQueueCapacity) >::check();
} }
@@ -267,7 +269,7 @@ public:
* Returns zero if OK. * Returns zero if OK.
* Returns negative value if failed (e.g. invalid bitrate). * Returns negative value if failed (e.g. invalid bitrate).
*/ */
int init(const uavcan::uint32_t bitrate, const CanIface::OperatingMode mode); int init(const uavcan::uint32_t bitrate, const CanIface::OperatingMode mode, const uavcan::uint32_t EnabledInterfaces);
virtual CanIface *getIface(uavcan::uint8_t iface_index); virtual CanIface *getIface(uavcan::uint8_t iface_index);
@@ -296,9 +298,11 @@ public:
enum { BitRateAutoDetect = 0 }; enum { BitRateAutoDetect = 0 };
CanDriver driver; CanDriver driver;
uint32_t enabledInterfaces_;
CanInitHelper() : CanInitHelper(const uavcan::uint32_t EnabledInterfaces = 0x7) :
driver(queue_storage_) driver(queue_storage_),
enabledInterfaces_(EnabledInterfaces)
{ } { }
/** /**
@@ -309,7 +313,7 @@ public:
*/ */
int init(uavcan::uint32_t bitrate) int init(uavcan::uint32_t bitrate)
{ {
return driver.init(bitrate, CanIface::NormalMode); return driver.init(bitrate, CanIface::NormalMode, enabledInterfaces_);
} }
/** /**
@@ -330,7 +334,7 @@ public:
int init(DelayCallable delay_callable, uavcan::uint32_t &inout_bitrate = BitRateAutoDetect) int init(DelayCallable delay_callable, uavcan::uint32_t &inout_bitrate = BitRateAutoDetect)
{ {
if (inout_bitrate > 0) { if (inout_bitrate > 0) {
return driver.init(inout_bitrate, CanIface::NormalMode); return driver.init(inout_bitrate, CanIface::NormalMode, enabledInterfaces_);
} else { } else {
static const uavcan::uint32_t StandardBitRates[] = { static const uavcan::uint32_t StandardBitRates[] = {
@@ -343,7 +347,7 @@ public:
for (uavcan::uint8_t br = 0; br < sizeof(StandardBitRates) / sizeof(StandardBitRates[0]); br++) { for (uavcan::uint8_t br = 0; br < sizeof(StandardBitRates) / sizeof(StandardBitRates[0]); br++) {
inout_bitrate = StandardBitRates[br]; inout_bitrate = StandardBitRates[br];
const int res = driver.init(inout_bitrate, CanIface::SilentMode); const int res = driver.init(inout_bitrate, CanIface::SilentMode, enabledInterfaces_);
delay_callable(); delay_callable();
@@ -351,7 +355,7 @@ public:
for (uavcan::uint8_t iface = 0; iface < driver.getNumIfaces(); iface++) { for (uavcan::uint8_t iface = 0; iface < driver.getNumIfaces(); iface++) {
if (!driver.getIface(iface)->isRxBufferEmpty()) { if (!driver.getIface(iface)->isRxBufferEmpty()) {
// Re-initializing in normal mode // Re-initializing in normal mode
return driver.init(inout_bitrate, CanIface::NormalMode); return driver.init(inout_bitrate, CanIface::NormalMode, enabledInterfaces_);
} }
} }
} }
@@ -917,7 +917,8 @@ void CanDriver::initOnce()
#endif #endif
} }
int CanDriver::init(const uavcan::uint32_t bitrate, const CanIface::OperatingMode mode) int CanDriver::init(const uavcan::uint32_t bitrate, const CanIface::OperatingMode mode,
const uavcan::uint32_t enabledInterfaces)
{ {
int res = 0; int res = 0;
@@ -934,28 +935,33 @@ int CanDriver::init(const uavcan::uint32_t bitrate, const CanIface::OperatingMod
/* /*
* CAN1 * CAN1
*/ */
UAVCAN_STM32_LOG("Initing iface 0..."); if (enabledInterfaces & 1) {
ifaces[0] = &if0_; // This link must be initialized first, UAVCAN_STM32_LOG("Initing iface 0...");
res = if0_.init(bitrate, mode); // otherwise an IRQ may fire while the interface is not linked yet; ifaces[0] = &if0_; // This link must be initialized first,
res = if0_.init(bitrate, mode); // otherwise an IRQ may fire while the interface is not linked yet;
if (res < 0) { // a typical race condition. if (res < 0) { // a typical race condition.
UAVCAN_STM32_LOG("Iface 0 init failed %i", res); UAVCAN_STM32_LOG("Iface 0 init failed %i", res);
ifaces[0] = UAVCAN_NULLPTR; ifaces[0] = UAVCAN_NULLPTR;
goto fail; goto fail;
}
} }
/* /*
* CAN2 * CAN2
*/ */
#if UAVCAN_STM32_NUM_IFACES > 1 #if UAVCAN_STM32_NUM_IFACES > 1
UAVCAN_STM32_LOG("Initing iface 1...");
ifaces[1] = &if1_; // Same thing here.
res = if1_.init(bitrate, mode);
if (res < 0) { if (enabledInterfaces & 2) {
UAVCAN_STM32_LOG("Iface 1 init failed %i", res); UAVCAN_STM32_LOG("Initing iface 1...");
ifaces[1] = UAVCAN_NULLPTR; ifaces[1] = &if1_; // Same thing here.
goto fail; res = if1_.init(bitrate, mode);
if (res < 0) {
UAVCAN_STM32_LOG("Iface 1 init failed %i", res);
ifaces[1] = UAVCAN_NULLPTR;
goto fail;
}
} }
#endif #endif
+1 -1
View File
@@ -518,7 +518,7 @@ UavcanNode::start(uavcan::NodeID node_id, uint32_t bitrate)
if (can == nullptr) { if (can == nullptr) {
can = new CanInitHelper(); can = new CanInitHelper(board_get_can_interfaces());
if (can == nullptr) { // We don't have exceptions so bad_alloc cannot be thrown if (can == nullptr) { // We don't have exceptions so bad_alloc cannot be thrown
PX4_ERR("Out of memory"); PX4_ERR("Out of memory");