mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-10-06 09:02:52 +08:00
fix(uavcan): warn while the dynamic node ID allocation table is full (#28243)
centralized::Storage never evicts, so a node ID spent on a board that is gone stays spent. Once all of them are, every board the table has not seen before is refused a node ID through a UAVCAN_TRACE that compiles to nothing here - silent on the bus and on the console, so a full table reads as a dead node. Boards already in the table still get their cached ID and join fine, so the bus looks healthy. A test station cycling boards through one flight controller fills the table and stops allocating for good. PX4_ERR every 5 s while full: the table does not empty itself, so this is a fault someone has to clear, not a one-time notice.
This commit is contained in:
@@ -759,6 +759,10 @@ UavcanNode::Run()
|
||||
_servers->setArmed(actuator_armed.armed || actuator_armed.prearmed);
|
||||
}
|
||||
|
||||
if (_servers != nullptr) {
|
||||
_servers->warn_if_node_id_allocation_table_full();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODULES_NFS_MOUNT
|
||||
|
||||
if (_servers != nullptr) {
|
||||
|
||||
@@ -154,6 +154,30 @@ int UavcanServers::init()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UavcanServers::warn_if_node_id_allocation_table_full()
|
||||
{
|
||||
/*
|
||||
The table never evicts an entry, so a node ID spent on a board that is no longer present stays spent. Once
|
||||
all of them are, every board the table has not seen before is refused a node ID, and the refusal is silent
|
||||
on the bus and here - the node just never appears, which reads as a dead node rather than a full table.
|
||||
Keep saying so: the table does not empty itself, so this is a fault someone has to clear.
|
||||
*/
|
||||
if (_server_instance.getNumAllocations() < uavcan::NodeID::MaxRecommendedForRegularNodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hrt_abstime now = hrt_absolute_time();
|
||||
|
||||
if (_node_id_table_full_warned != 0 && now - _node_id_table_full_warned < NODE_ID_TABLE_FULL_WARN_INTERVAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
_node_id_table_full_warned = now;
|
||||
PX4_ERR("dynamic node ID table is full (%u/%u): no new node can join, delete %s and reboot",
|
||||
static_cast<unsigned>(_server_instance.getNumAllocations()),
|
||||
static_cast<unsigned>(uavcan::NodeID::MaxRecommendedForRegularNodes), UAVCAN_NODE_DB_PATH);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODULES_NFS_MOUNT
|
||||
void UavcanServers::check_nfs()
|
||||
{
|
||||
|
||||
@@ -71,6 +71,8 @@ public:
|
||||
|
||||
int init();
|
||||
|
||||
void warn_if_node_id_allocation_table_full();
|
||||
|
||||
#ifdef CONFIG_MODULES_NFS_MOUNT
|
||||
void check_nfs();
|
||||
#endif
|
||||
@@ -86,6 +88,8 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
static constexpr hrt_abstime NODE_ID_TABLE_FULL_WARN_INTERVAL{5_s};
|
||||
|
||||
void unpackFwFromROMFS(const char *sd_path, const char *romfs_path);
|
||||
void migrateFWFromRoot(const char *sd_path, const char *sd_root_path);
|
||||
int copyFw(const char *dst, const char *src);
|
||||
@@ -100,5 +104,7 @@ private:
|
||||
|
||||
uavcan::NodeInfoRetriever &_node_info_retriever;
|
||||
|
||||
hrt_abstime _node_id_table_full_warned{0};
|
||||
|
||||
uORB::Subscription _nfs_up_sub{ORB_ID(nfs_up)};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user