Hello,
I'm trying to make stm32f429 uavcan node to work with an imx6sx node. I have simply configured the imx6 node as a time sync master as shown in the tutorials. The IMX6 board tham i am using has 2 can ifaces. One is a time sync master and the other is a time sync slave. Both are working fine without any issues. But the stm32 node for some reason does not sync. Here's my setup for stm32.
RTOS: Chibios + tickless mode
UAVCAN_STM32_TIMER_NUMBER: 3
Number of ifaces: 1 (only using can1 for now since i dont have an extra transceiver currently).
Here is the source for the stm32 node
#include <node.hpp>
#include <ch.hpp>
#include <uavcan_stm32/can.hpp>
#include <uavcan_stm32/clock.hpp>
#include <sys.hpp>
#include <unistd.h>
#include <timing/MicrosecondDelay.h>
#include <uavcan/protocol/global_time_sync_slave.hpp>
#include <uavcan/protocol/dynamic_node_id_client.hpp>
namespace can{
constexpr uint32_t MemoryPoolSize=16384;
using Node=uavcan::Node<MemoryPoolSize>;
auto node_status_mode = uavcan::protocol::NodeStatus::MODE_OPERATIONAL;
auto node_status_health = uavcan::protocol::NodeStatus::HEALTH_OK;
/*
* @template param: RxQueueCapacity
* default value: 128
*/
uavcan_stm32::CanInitHelper<128> can;
static Node& getNode()
{
static Node node(can.driver,uavcan_stm32::SystemClock::instance());
return node;
}
void print_nodeInfo()
{
sys::syslog("Can bitrate: %u\r\n",125000);
sys::syslog("Node ID: %u\r\n",getNode().getNodeID());
sys::syslog("Node mode: %u\r\n",node_status_mode);
sys::syslog("Node Health: %u\r\n",node_status_health);
const decltype(auto) perf= getNode().getDispatcher().getTransferPerfCounter();
const auto pool_capacity = getNode().getAllocator().getBlockCapacity();
const auto peak_usage = getNode().getAllocator().getPeakNumUsedBlocks();
uavcan::CanIfacePerfCounters iface_perf;
iface_perf = getNode().getDispatcher().getCanIOManager().getIfacePerfCounters(0);
sys::syslog("Memory Pool Capacity: %u\r\n",pool_capacity);
sys::syslog("Memory Peak Usage: %u\r\n",peak_usage);
sys::syslog("Transfers Tx/Rx: %u / %u \r\n",perf.getTxTransferCount(),perf.getRxTransferCount());
sys::syslog("Transfer Errors: %u\r\n",(unsigned)perf.getErrorCount());
sys::syslog("Can Iface: %d\r\n",0);
sys::syslog("Frames Tx/Rx: %u / %u \r\n", (unsigned)(iface_perf.frames_tx),(unsigned)(iface_perf.frames_tx));
sys::syslog("Rx Overflows: %u\r\n",(unsigned)can.driver.getIface(0)->getRxQueueOverflowCount());
sys::syslog("Iface errors: %u\r\n",(unsigned)iface_perf.errors);
sys::syslog("------End of Block-------\r\n");
}
void Init()
{
int res=0;
//static const int self_node_id = 50;
stm32plus::MicrosecondDelay timer;
timer.initialise();
do{
uint32_t bitrate = 125000;
// res= can.init([&](){timer.delay(can.getRecommendedListeningDelay().toUSec());},bitrate);
res = can.init(bitrate);
if(res >= 0)
{
sys::syslog("Inited can at bitrate: %u bps\r\n",bitrate);
}
else
{
sys::syslog("Failed to init Can: %d Bitrate:%u \r\n",res,bitrate);
}
}while(res < 0);
}
class : public chibios_rt::BaseStaticThread<8192>
{
void init_node()
{
getNode().setName("org.uavcan.Slave_sync");
getNode().setNodeID(50);
while(true)
{
int node_res = getNode().start();
if(node_res < 0)
{
sys::syslog("Failed to Init Node: %d\r\n",node_res);
}
else
{
sys::syslog("Can Node Inited. Node ID %d\r\n",getNode().getNodeID().get());
break;
}
}
}
public:
void main() override
{
Init(); //Can Driver Init
init_node();
chThdSleep(MS2ST(10));
print_nodeInfo();
uavcan::GlobalTimeSyncSlave slave(getNode());
const int slave_res = slave.start();
if(slave_res < 0)
{
sys::syslog("Failed to init time sync slave: %d\r\n",slave_res);
}
getNode().getNodeStatusProvider().setHealth(node_status_health);
getNode().getNodeStatusProvider().setMode(node_status_mode);
getNode().setModeOperational();
while(true)
{
const int spin_res = getNode().spin(uavcan::MonotonicDuration::fromMSec(100));
if(spin_res < 0)
{
sys::syslog("Spin Error: %d\r\n",spin_res);
}
const bool active = slave.isActive();
const auto masterid = slave.getMasterNodeID().get();
const float time_since_last_adj= (getNode().getMonotonicTime() - slave.getLastAdjustmentTime()).toMSec();
sys::syslog("Slave Active: %d\r\n"
"Master ID: %d\r\n"
"Time since Last Adjustment: %f\r\n",active,masterid,time_since_last_adj);
}
}
}test_node;
int init()
{
(void)test_node.start(NORMALPRIO);
return 0;
}
}
The thread only ever reaches the line "iface_perf = getNode().getDispatcher().getCanIOManager().getIfacePerfCounters(0);" in the print_nodeInfo() method and then never gets rescheduled. This is not an rtos issue since other threads are working fine. I have initialized the can peripheral properly and can confirm that the interface is fully operational. One more thing that happens is after initialization. The node starts sending messages continuously non-stop overloading the bus. After some point the other nodes (IMX6 master and slave) stop communicating. How do i proceed further with this issue?
Regards.