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;
CanInitHelper() :
CanInitHelper(uint32_t unused = 0x7) :
driver(queue_storage_)
{
}
@@ -234,6 +234,7 @@ class CanDriver : public uavcan::ICanDriver, uavcan::Noncopyable
#if UAVCAN_STM32_NUM_IFACES > 1
CanIface if1_;
#endif
uint32_t enabledInterfaces_;
virtual uavcan::int16_t select(uavcan::CanSelectMasks &inout_masks,
const uavcan::CanFrame * (& pending_tx)[uavcan::MaxCanIfaces],
@@ -249,6 +250,7 @@ public:
#if UAVCAN_STM32_NUM_IFACES > 1
, if1_(bxcan::Can[1], update_event_, 1, rx_queue_storage[1], RxQueueCapacity)
#endif
, enabledInterfaces_(0x7)
{
uavcan::StaticAssert < (RxQueueCapacity <= CanIface::MaxRxQueueCapacity) >::check();
}
@@ -267,7 +269,7 @@ public:
* Returns zero if OK.
* 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);
@@ -296,9 +298,11 @@ public:
enum { BitRateAutoDetect = 0 };
CanDriver driver;
uint32_t enabledInterfaces_;
CanInitHelper() :
driver(queue_storage_)
CanInitHelper(const uavcan::uint32_t EnabledInterfaces = 0x7) :
driver(queue_storage_),
enabledInterfaces_(EnabledInterfaces)
{ }
/**
@@ -309,7 +313,7 @@ public:
*/
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)
{
if (inout_bitrate > 0) {
return driver.init(inout_bitrate, CanIface::NormalMode);
return driver.init(inout_bitrate, CanIface::NormalMode, enabledInterfaces_);
} else {
static const uavcan::uint32_t StandardBitRates[] = {
@@ -343,7 +347,7 @@ public:
for (uavcan::uint8_t br = 0; br < sizeof(StandardBitRates) / sizeof(StandardBitRates[0]); 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();
@@ -351,7 +355,7 @@ public:
for (uavcan::uint8_t iface = 0; iface < driver.getNumIfaces(); iface++) {
if (!driver.getIface(iface)->isRxBufferEmpty()) {
// 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
}
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;
@@ -934,28 +935,33 @@ int CanDriver::init(const uavcan::uint32_t bitrate, const CanIface::OperatingMod
/*
* CAN1
*/
UAVCAN_STM32_LOG("Initing iface 0...");
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 (enabledInterfaces & 1) {
UAVCAN_STM32_LOG("Initing iface 0...");
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.
UAVCAN_STM32_LOG("Iface 0 init failed %i", res);
ifaces[0] = UAVCAN_NULLPTR;
goto fail;
if (res < 0) { // a typical race condition.
UAVCAN_STM32_LOG("Iface 0 init failed %i", res);
ifaces[0] = UAVCAN_NULLPTR;
goto fail;
}
}
/*
* CAN2
*/
#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) {
UAVCAN_STM32_LOG("Iface 1 init failed %i", res);
ifaces[1] = UAVCAN_NULLPTR;
goto fail;
if (enabledInterfaces & 2) {
UAVCAN_STM32_LOG("Initing iface 1...");
ifaces[1] = &if1_; // Same thing here.
res = if1_.init(bitrate, mode);
if (res < 0) {
UAVCAN_STM32_LOG("Iface 1 init failed %i", res);
ifaces[1] = UAVCAN_NULLPTR;
goto fail;
}
}
#endif
+1 -1
View File
@@ -518,7 +518,7 @@ UavcanNode::start(uavcan::NodeID node_id, uint32_t bitrate)
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
PX4_ERR("Out of memory");