本文主要讲述CANopen中的NMT报文,即网络管理(Network ManagemenT),该服务可以用于启动网络和监控设备。

NMT报文由NMT主机发送,对从机进行启动、监控和重启,在CANopen网络中只允许有一个活动的NMT主机。如果网络中有多个设备可以配置成主机,那么同一时刻只有一个可以配置成主机。


一 NMT报文及功能

NMT报文属于Master/Slave模式

1. 模块控制报文

该报文用于对Slave从机进行各种控制,报文格式如下,

必须由NMT Master发给NMT Slave(s),报文的COB-ID是0x000

报文数据段传输的第0个字节是CS (Command Specifier),用于表示控制命令,具体有以下5个命令,

PS:NMT Service这一列里有个Remote Node,即远程节点,其实就是Slave节点,这是相对于NMT Master来说的。如果NMT Master也是个CAN设备,那么NMT Master自身可以叫做Local Node

报文数据段传输的第1个字节是Slave从机的Node Id,如果为0,表示网内所有Slave设备都会收到这个报文。

2. 设备监控报文

该功能主要用于监控Slave设备的当前状态,分为Node Guarding和Heartbeat两种方式。

2.1 Node Guarding

NMT Master主动向Slave发送一个CAN远程帧(没有数据段),如下图,

然后Slave会返回一个指定格式的消息给Master,如下图,

Byte0包含一个toggle位(bit7),每一次Node Guard请求都会在0和1之间进行翻转(第一次值为0),翻转的目的是为了区分设备当前状态值和历史状态值;bit 6-0用来表示Slave的当前状态,有以下几种状态,

PS:状态0永远不会出现在Node Guarding的reply里,因为在Initialising状态下,不会对Node Guarding请求做出响应。

2.2 Heartbeat

也叫做心跳报文,由NMT Slave主动发送,NMT Master接收,无需response,这种模式也叫做生产者/消费者模式,NMT Slave是生产者,NMT Master是消费者

有以下4种状态,

当一个使用Heartbeat的CAN设备启动,其第一条心跳报文就是Boot-up,

2.3 小结

Node Guarding和Heartbeat都可以实现设备监控的目的,同一时刻只能使用其中一种,推荐使用Heartbeat,更加简单,另外Node Guarding需要用到远程帧,不是所有CAN设备都支持远程帧。

3. 启动报文

当NMT Slave设备启动时,都会发送这条报文,用来告知Master自己已经从 Initialising状态切换到Pre-operational状态。

启动报文和Heartbeat中的Boot-up有点重合,当一个使用Heartbeat的CAN设备启动,其第一条心跳报文就是Boot-up,但如果使用的是Node Guarding,那么CAN设备启动后发送的第一条报文就是启动报文,后续就是Node Guarding请求了。


二 代码实战

学习了理论后,再通过实践来加深理解。

首先,通过下面的Slave代码,创建1个Slave节点,id是6,初始化完成后自动进入Pre-operational状态,

import signal
import canopenrunning = Truedef sigint_handler(signum, frame):global runningprint('')running = Falseexit(0)# 处理按键发送的信号,优雅的关闭程序
signal.signal(signal.SIGINT,  sigint_handler)
signal.signal(signal.SIGHUP,  sigint_handler)
signal.signal(signal.SIGTERM, sigint_handler)# 创建一个网络用来表示CAN总线
network = canopen.Network()# 连接到CAN总线
network.connect(bustype='socketcan', channel='vcan0')# 创建slave节点,其id是6,对象字典为CANopenSocket.eds
node = network.create_node(6, 'CANopenSocket.eds')# node向CAN总线上发送启动消息
node.nmt.send_command(0)# node进入PRE-OPERATIONAL状态
node.nmt.state = 'PRE-OPERATIONAL'# node发送心跳报文,每隔1s发送一次
node.nmt.start_heartbeat(1000) # 1000ms# 循环
while running:pass

运行后在candump窗口下观察如下,

0x7F是127,表示can节点进入了Pre-operational状态。

下面是master代码,会把所有NMT的命令都执行一遍,具体可以看注释,

import time
import canopen# 创建一个网络用来表示CAN总线
network = canopen.Network()# 添加slave节点,其id是6,对象字典为CANopenSocket.eds
node = canopen.RemoteNode(6, 'CANopenSocket.eds')
network.add_node(node)# 连接到CAN总线
network.connect(bustype='socketcan', channel='vcan0')sleep_sec = 2 # 2秒# 发送'Start Remode Node'命令,把slave设置为OPERATIONAL状态
node.nmt.state = 'OPERATIONAL'time.sleep(sleep_sec)# 发送'Reset Node'命令,把slave设置为Initialising状态
node.nmt.state = 'RESET'time.sleep(sleep_sec)# 发送'Enter Pre-operational State'命令,把slave设置为PRE-OPERATIONAL状态
node.nmt.state = 'PRE-OPERATIONAL'time.sleep(sleep_sec)# 发送'Start Remode Node'命令,把slave设置为OPERATIONAL状态
node.nmt.state = 'OPERATIONAL'time.sleep(sleep_sec)# 发送'Stop Remode Node'命令,把slave设置为STOPPED状态
node.nmt.state = 'STOPPED'time.sleep(sleep_sec)# 发送'Reset Communication'命令,把slave设置为Initialising状态
node.nmt.send_command(0x82)time.sleep(sleep_sec)# 发送'Enter Pre-operational State'命令,把slave设置为PRE-OPERATIONAL状态
node.nmt.state = 'PRE-OPERATIONAL'time.sleep(sleep_sec)# 发送'Start Remode Node'命令,把slave设置为OPERATIONAL状态
node.nmt.state = 'OPERATIONAL'

运行master.py后,在candump窗口可以看到如下状态变化,

已上状态切换完全是按照CANopen DS301中规定的状态机进行的,如下图,


三 总结

本文主要讲述CANopen协议中的NMT报文,并以代码实战展示了如何使用NMT报文以及对应的状态切换。

如果有写的不对的地方,希望能留言指正,谢谢阅读。

学习CANopen --- [3] NMT报文相关推荐

  1. CanOpen协议栈学习笔记1-帧格式,SYNC和NMT报文介绍

    前面已经记录过can协议,后面开始CanOpen协议栈学习.其实协议栈代码已经看过了,而且已经在开发板上跑过了.这里回过头来,重新看下之前遇到的坑,记录下学习笔记.下面均以标准帧为例 文章目录 1.C ...

  2. 学习CANopen --- [2] PythonCANopen简单用法

    本文主要讲述如何在Linux下使用python进行简单的CANopen通信,使用了一个叫CANopen for Python的库,地址是https://github.com/christiansand ...

  3. 学习CANopen --- [5] SDO

    文章目录 前言 一 工作原理 二 使用范围 三 例子 1. COB-ID分析 2. 报文内容分析 --- 读操作 命令提示符 索引和子索引 报文中的数据值 3. 报文内容分析 --- 写操作 命令提示 ...

  4. CANopen原理--NMT状态机

    本文介绍CANopen中的NMT状态机,及在CanFestival中的实现过程. 一.NMT状态机 CANopen中状态机包含4个状态:Initialisation.Pre-operational.O ...

  5. C++网络编程学习:网络数据报文的收发

    网络编程学习记录 使用的语言为C/C++ 源码支持的平台为:Windows 笔记一:建立基础TCP服务端/客户端  点我跳转 笔记二:网络数据报文的收发  点我跳转 笔记三:升级为select网络模型 ...

  6. 理论学习-协议栈学习-CANopen协议梳理

    CANopen协议梳理 开放式系统互联模型 开放式系统互联模型 #mermaid-svg-vgZNn3jf2tTpscn0 .label{font-family:'trebuchet ms', ver ...

  7. LWIP学习笔记---网际控制报文协议ICMP

    网际控制报文协议 背景 相关概念 报文类型 报文格式 差错报文 查询报文 代码实现 数据结构 发送差错报文代码实现 回送报文请求 背景 IP协议并不完美,在传递数据时提供的是一种无连接的不可靠数据报交 ...

  8. 学习CANopen --- [10] 汽车外接OBD模块原理

    在某宝上搜索汽车OBD,可以发现很多卖OBD模块的,通过接入OBD模块可以增加车子本身没有的功能,如锁车升窗,行车自动落锁和后视镜折叠等,那么其实现原理是什么呢?使用时会造成亏电吗? 一 原理 OBD ...

  9. canopen12-python学习总结

    1.学习CANopen - [1] CANopenSocket简单用法 2.学习CANopen - [2] PythonCANopen简单用法 3.学习CANopen - [3] NMT报文 4.学习 ...

最新文章

  1. 【Windows Server 2019】 Windows Admin Center 4 添加服務器
  2. [转]C++/CLI与C#常用语法对比
  3. RocketMQ:消息ACK机制源码解析
  4. spark task和stage划分原理
  5. android自定义dialog 例子,android dialog自定义实例详解
  6. java编程线程怎么处理_java编程多线程并发处理的教程
  7. 统一对比学习框架?没错它来了。
  8. mysql 5.1升级windows_怎么在Windows下升级MySQL
  9. 《FilthyRichClients》读书笔记(一)-SwingのEDT
  10. *第二周*数据结构实践项目一【交换】
  11. 老男孩教育每日一题-第95天-shell脚本知识点:书写脚本完成ftp上传下载
  12. 双系统linux引导修复
  13. 软件质量应该如何保证?针对不同情况,项目各部门人员应如何保证软件质量?
  14. Bookmark Sentry – 检查重复、删除死链书签 Chrome扩展
  15. AD-FMCOMMS3 使用matlab+Linux/No-OS传输QPSK信号
  16. 有没有计算机网课,有没有电脑录制视频工具可以录制网课?
  17. 微信聊天记录内的文件如何实现自动同步备份?
  18. 数据挖掘中最容易犯的几个错误,你知道吗?
  19. python中assert是什么意思_python assert函数是什么以及如何使用?
  20. Linux下的动态库和静态库

热门文章

  1. Gartner技术成熟曲线详解
  2. APOLLO基本介绍
  3. splits——安卓gradle
  4. 北美年轻人也渴望新的社交软件?「Vibe」想用校园社群 Story 打开市场
  5. javaMail简单发送邮件
  6. 【Git】error: RPC failed; curl 56 GnuTLS recv error (-9): A TLS packet with unexpected length was rece
  7. android 程序运行,Android如何保持程序一直运行
  8. 烤仔TVのCCW丨密码学通识(一)密码学基础及常见误区
  9. 北邮计算机网络实践实验三,北邮计算机网络技术实践--实验三
  10. 计算机office用的是哪个版本,小编教你看office是哪个版本_查看office是哪个版本的方法...