利用MagiSync的优势

  • 2023-10-31
  • Troy Via

MagiSync是我们的SemiPro、Professional和Precision产品中提供的一项功能,使用它可自动同步连接到同一USB根集线器的Kvaser USB设备上的时钟信号。当设备插入电源并通电时,这种同步就会发生,并且不需要任何配置即可激活此功能。

如果您选中菜单项“查看”->“已同步硬件”,就可以通过查看Kvaser设备指南来判断哪些设备已同步。

正如您所看到的,Kvaser Hybrid Pro和Kvaser Memorator Pro被同步到了MagiSync Group 1中。附带的Leaf Light v2不包括在内,因为它不支持MagiSync。因此,Hybrid Pro和Memorator Pro通道上的时钟信号是同步的,而Leaf Light HS v2通道则不同步。

随着时钟信号的同步,我们现在需要将时钟放在同一时域内,以保证从每个通道返回的时间戳在同一时刻是相同的。这样就能更轻松地分析从多个通道上接收的数据。这是通过使用CANlib SDK中的kvTimeDomain***函数来完成的。

第一步是创建一个时域,供您希望具有同步时间戳的所有句柄使用。

Canlib.canStatus status = Canlib.kvTimeDomainCreate(out object myTimeDomain);

下一步是配置每个通道的句柄。因此,需要获取您的通道句柄并设置其比特率。在我的示例代码中,我使用通道枚举1和3来对应Kvaser Hybrid Pro的第一个通道和Kvaser Memorator Pro的第一个通道,如下所示:

int hybridHnd = Canlib.canOpenChannel(1, 0);
int memoHnd = Canlib.canOpenChannel(3, 0);
status = Canlib.canSetBusParams(hybridHnd, Canlib.canBITRATE_250K, 0, 0, 0, 1);
status = Canlib.canSetBusParams(memoHnd, Canlib.canBITRATE_250K, 0, 0, 0, 1);

通常情况下,当通道句柄设置为总线开启时,时间戳会重置为零。当使用时域时,我们希望只有在重置时域时才将时间戳重置为零。因此,我们需要使用canIoCtl函数来关闭正常行为。

object autoResetOff = (UInt32)0;
status = Canlib.canIoCtl(hybridHnd, Canlib.canIOCTL_SET_BUSON_TIME_AUTO_RESET, ref autoResetOff);
status = Canlib.canIoCtl(memoHnd, Canlib.canIOCTL_SET_BUSON_TIME_AUTO_RESET, ref autoResetOff);

然后,我们使用kvTimeDomainAddHandle函数将句柄添加到时域中。

status = Canlib.kvTimeDomainAddHandle(myTimeDomain, hybridHnd);
status = Canlib.kvTimeDomainAddHandle(myTimeDomain, memoHnd);

启动总线前,我们需要将时域重置为零。

status = Canlib.kvTimeDomainResetTime(myTimeDomain);

现在我们已准备好启动通道句柄总线了。

status = canBusOn(hybridHnd);
status = canBusOn(memoHnd);

此时,在两个通道上接收的帧的时间戳将被同步。以下是完整示例程序的输出结果,其中从左到右的列依次为通道、标识符、标志、dlc、数据字节和时间戳。

**** 运行程序时的截屏显示在两个通道上接收到的具有相同时间戳的相同信息 ****

作为使用kvTimeDomain***函数的最后一步,您应该使用kvTimeDomain RemoveHandle和kvTimeDomainDelete函数来正确清理句柄和时域。

status = Canlib.canBusOff(hybridHnd);
status = Canlib.canBusOff(memoHnd);
status = Canlib.kvTimeDomainRemoveHandle(myTimeDomain, hybridHnd);
status = Canlib.kvTimeDomainRemoveHandle(myTimeDomain, memoHnd);
status = Canlib.canClose(hybridHnd);
status = Canlib.canClose(memoHnd);
status = Canlib.kvTimeDomainDelete(myTimeDomain);

如果您喜欢在同一时域中获得所有的时间戳,您可能还想调整时间戳的解析度。报告的默认时间戳精度是1毫秒。但是您可以使用canIoCtl函数来调整每个句柄时间戳的精度。

object timerScale = (UInt32)1;  // set resolution to 1 microsecond
status = Canlib.canIoCtl(hybridHnd, Canlib.canIOCTL_SET_TIMER_SCALE, ref timerScale);
status = Canlib.canIoCtl(memoHnd, Canlib.canIOCTL_SET_TIMER_SCALE, ref timerScale);

应在重置时域并使句柄在总线上处于激活状态之前进行此更改。

如需了解更多信息,请参见CANlib帮助文档。如果您有任何问题或希望获取本文中的示例应用副本,请发送邮件至support@kvaser.com

Author Image

Troy Via

Troy Via是Kvaser股份有限公司的软件和支持工程师。Troy为Kvaser编写了多个培训视频,是产品开发团队的关键成员。他也代表Kvaser参加NMEA讨论。工作之余,他还是一名狂热的游戏玩家。

联系我们