第八节、关于SDO:
SDO主要用于对象字典的信息传送。SDO传输按照客户端-服务器模式进行,并且只能由客户端发起,服务器应答。当然,发起和应答的SDO的COB-ID是不同的。
SDO的COB-ID可以见第五节,只能是0x580+Node_ID或0x600+Node_ID(Node_ID从1开始)。
SDO的格式还是相对比较固定的,除了分段报文,都遵循下面的格式:
上图右下区域的0、1、2…7,都是一个字节。也就是说命令代码一个字节,主索引两个字节,子索引一个字节,数据4个字节(不用的写0)。这里的(主)索引和子索引都应该是对象字典里能实际找到的索引(毕竟SDO就是读写对象字典用的)。
这里还要注意,无论是(主)索引还是数据,只要超过1个字节的信息,都是低字节在前(左)、高字节在后(右)传送。
SDO 的传输分为不高于 4 个字节和高于 4 个字节的对象数据传输。 不高于 4 个字节采用加速(expedited) SDO 传输方式,高于 4 个字节采用分段传输或块传输方式。
所谓加速SDO,就是说数据不超过4字节,一次就能传完的SDO。加速SDO又分为SDO加速写和SDO加速读两种情况。分别见下面两张连续的图。
数据超过4字节的时候,采用分段传输,下面以分段读为例说明。分段读的过程分为三个阶段,首先是读请求,然后是若干字段传输,最后是尾段收尾,不同阶段SDO有所不同,如下面连续三图所示:
说明一下上面三张图:分段读仍然由客户端发起。其实对于客户端来说,SDO的分段读和加速读的发起过程是完全一样的,只是服务器端返回的命令码(分段读是0x41)不同。
中间的数据传输阶段,一次最多只能传送7个字节(加速最多只有4字节),而且低字节在前。在分段读阶段,命令码的bit4是反转位(t),每传一个报文反转一次(第一个报文反转位从0开始)。客户端命令码的bit5和bit6固定为11;服务器端命令码的bit5和bit6固定为0,其余位为0,所以组合之后,客户端的命令码在0x60和0x70之间来回切;服务器端的命令码在0x00和0x10之间来回切。
最后的收尾阶段,根据收尾数据的多少,服务器的命令码也有所区别。
其实,在CANopen协议中,命令码是有格式计算的,并不是按上图死记硬背——上图只是把计算结果直接显示出来而已。以SDO分段读的命令码为例,编码规律可以参看文档CiA301+V4.2.0(中文注释版).pdf的47页和48页。但也要说明,我这里说的分段读,在文档中叫分段上传,上传应该理解成上传给客户端;自然,下载才是下载到服务器!
最后,无论分段传送如何进行,报文都一定是由客户端和服务器端成对交互的,数据再多,服务器端也不会跳过客户端的报文,主动连续发送多个报文的。