今天我们继续来介绍TSMaster新功能—J1939多帧报文收发。这个功能属于J1939的高级功能,需要license的授权,具体操作需求可以联系我们。
一、J1939功能使用
我们假设已经拥有了带license的硬件,以TC1005为例,选择硬件通道后连接应用程序,随后打开about窗口,就可以看到拥有license的列表。其中有一个J1939的option,接下来介绍这个功能的使用。
> 首先打开TSMaster的安装目录,进入demo文件夹,找到示例数据库J1939ILDemo的数据库文件。我们将其拖入TSMaster中,这个拖入的过程需要在程序断开连接的时候来完成,可以看到,这个数据库里面有四帧报文,它的PGN分别为EF00,EF00,FF02和FF01。
> 其中前两帧为点对点的多帧,分别是节点2往1发,1往2发;后两个是广播,分别是地址2的广播和地址1的广播。以第一帧为例,他的DLC=35个字节,这意味着这个信号可以在这35乘以8,也就是280个位置里面任意排布。那么报文中的sgn1~4就是模拟了这种情况。如果希望发送这些报文,我们可以直接使用发送窗口,我们打开CAN Transmit窗口,点击左上角的来自数据库的按钮,选择刚才看到的四帧报文,然后再将视图切换成J1939,这样协议相关的信息就一览无余了。
前两个是点对点,后两个是广播,可以从目的地址看出来,对于广播报文来讲,发送节点只要自顾自的发送就可以了。而对于前两个点对点的发送过程,不但需要发送节点,还需要接收节点在过程中进行应答,才能完成整个发送过程。所以我们还需要激活TSMaster内置的J1939的仿真节点。
> 接下来我们来到仿真,J1939的仿真配置对话框里面,可以看到节点1和2,分别被标注为Node1和Node2,所有的节点都勾选了仿真发送功能,但是仿真接收功能默认是没有勾选的。我们可以通过激活rbs的方法来自动激活这两个接收的功能,同时呢也可以手动勾上,在此我们就手动勾选,并且点击应用设置来关闭对话框。
> 这个时候就可以启动仿真了,我们按下F5,然后打开trace窗口,随后呢我们激活这4个节点的这4个报文的发送,就依次点击发送就可以了。于是在右侧的trace窗口中间就可以看到这4个多帧报文的接收情况。他们的DLC分别是右边的35,36,13和33,然后右边显示的就是他们的默认的数据段默认都是0。
> 我们当然可以修改他们的数据字节来任意的修改他们的数据,那这里就可以看到这是我们刚才修改的结果,我们当然还可以通过信号生成器的方式来改,比如说我们选中第一帧报文,在这个sgn1 a2上面选择正弦,然后点击配置,我们可以把峰值改的稍微大一点,然后点击应用、点击启动,这个时候就可以看到这个sgn1 a2就在发生变化。
> 接下来可以打开图形窗口,将这个信号拖进来,就可以看到正弦波,当然这个正弦波的频率比较低,这是因为它是多帧,它发一帧需要200毫秒,所以一秒只有5个点,我们还可以通过其他的窗口来进行观察,比如说数值显示。
> 接下来可以打开图形窗口,将这个信号拖进来,就可以看到正弦波,当然这个正弦波的频率比较低,这是因为它是多帧,它发一帧需要200毫秒,所以一秒只有5个点,我们还可以通过其他的窗口来进行观察,比如说数值显示。
二、J1939一系列API函数
J1939有一套API的函数,通过这一套API就可以实现J1939的信号读写、报文发送等等一系列功能。
> 我们打开一个自动化模块,然后选中入口点,按回车增加一系列的动作。我们选第一个动作,然后设置他为API函数调用,在过滤器里面敲入1939,就可以看到1939的一系列API。这其中有1939的标识符的get和set方法以及下面的多帧报文的发送方法。关于标识符的get和set方法在此就不展开描述,大家完全可以查看c代码编辑器里面的小程序的帮助文档,里面有详细的介绍,在右侧也可以看到示例代码。那么这次我们着重介绍一下1939的多帧发送的API。
> 首先我们可以选中1939异步发送API,那么发送分为同步和异步两种,同步意味着发完之后程序才会往下走,异步则意味着只要将数据推入发送缓存,程序就可以继续往下,那么不管是同步还是异步,还分了两种类型。一种是不带字符串的发送,一种是基于字符串的发送。那么基于字符串方式的发送,他的数据是以逗号来进行分隔,那么这两种方式自动化模块都是支持的。因为在自动化模块里面,数组均以逗号分隔的字符串表达,那么我们可以选择一个异步发送,函数就可以看到这个函数有7个输入的参数。
> 那么第一个参数是通道号,我们可以选择常量,比如说,channel1然后PGN,在此我们就可以输入。比如说我们可以选广播,就是刚才看到的OxFF01,然后优先级是6,默认源地址是2,目的地址是1,然后PDU的数据我们可以随意填写。比如说Ox11,然后我们可以将这个复制多份,密贴多份,这里长度是可以很长。他的实际长度是被最后一个参数限制,那么在此我们可以保持跟dbc的一致,也就是35,然后我们就可以启动,按F9启动发送或者点击发送按钮,那么就可以发送成功。
> 那么第一个参数是通道号,我们可以选择常量,比如说,channel1然后PGN,在此我们就可以输入。比如说我们可以选广播,就是刚才看到的OxFF01,然后优先级是6,默认源地址是2,目的地址是1,然后PDU的数据我们可以随意填写。比如说Ox11,然后我们可以将这个复制多份,密贴多份,这里长度是可以很长。他的实际长度是被最后一个参数限制,那么在此我们可以保持跟dbc的一致,也就是35,然后我们就可以启动,按F9启动发送或者点击发送按钮,那么就可以发送成功。
那这是原始报文的发送方法,倘若需要修改报文里面的信号的值,就需要rbs的仿真引擎来支持,那我们可以点击CAN总线仿真窗口来模拟节点的行为,我们激活这两个节点,然后将总线仿真设置为自动启动,这个时候可以看到rbs已经在工作了,并且得到了我们通过发送窗口一样的结果。
> 当然发送窗口这个时候是不应该启动发送,回到自动化模块里面,删除我们的原始的报文发送的动作,设置一个新的动作衍生函数调用,在此我们搜索set Signal by address,通过这个函数就可以实现rbs里面信号的任意修改。那这里有两个参数,分别是信号地址和值,那么信号地址就是我们所需要发送的信号的数据库地址,我们可以随便选一个比如说A_Node1 signal 1_a1,我们可以点击复制数据库地址,然后到这里粘贴即可,然后他的值我们可以随意修改,然后我们可以点击启动,那么这样就实现了这个信号的修改,可以看到A_Node1里面的这个信号已经变成1111,就是我们所设置的值,那么这就是信号的发送。
如果是希望接收一个信号的值,该怎么做呢?
我们可以用到signal server的方法:还是来到函数调用,删除我们刚才的发送,然后再多加几个动作。我们首先将它改为函数调用,然后输入SGN SRV,这就是signal server的系列函数。
> 那这里需要一个流程,首先需要注册我们关心的信号,需要用到register_can_signal_by_message ID或者是name,我们在这里选择message ID,那么我们就需要到rbs里面去copy这个报文的ID,copy过来的时候需要把后面的x删掉,让这个字符串是一个有效的16进制值,通道还是可以用之前的通道1,然后信号名称就是我们关心的信号。
> 比如说sgn1_a1,我们自己直接输入sgn1_a1,client ID是这个函数注册成功之后给到我们程序的一个handle,我们可以新建个变量来存储它,就命名ID就行。这个时候直接已经可以点击本地变量关联我们的ID,然后我们可以等一会再读取信号的值,那这个时候可以调用wait函数,比如说等个3秒,然后接下去就是一个读取过程,同样用到了Signal server sgnsrv get_can_signal物理值。最后通过这个方法去取得,得到的信号的物理值,那么在这里可以同样选择channel1 client ID就填我们刚才所得到的变量ID,然后这里就是输出的值,我们同样可以用一个变量来装,这里需要添加的就是个double型的变量,value写个v就行,然后在这个地方选择v,然后同时还会返回最后的时间戳,如果不需要的话,我们这里默认填个0就行或者不填。
> 然后这个时候我们可以将我们读到的值打印出来,这时候就需要用到log函数字符串,我们可以写我们的变量v的值作为字符串,那么log level,可以用一种颜色,比如说绿色,然后我们点击启动,这个时候首先获取ID等待,然后最后获取值结束,那么我们会看一下每一步骤的运行结果。在这里都有反馈,这里是实际传入的参数值,wait然后读到的参数值然后我们可以看一下打印出来值就是111,就是我们之前设定的值,那么我们完全可以改一下这个值,比如说改成12345,这个值最大就是2047,我们就设它为2047,这个时候我们只要再启动一下程序,我们打开log,就可以看到我们获取的值跟我们设定值是一样。这就是1939系列API的用法。
作者: TOSUN同星, 来源:面包板社区
链接: https://mbb.eet-china.com/blog/uid-me-4003892.html
版权声明:本文为博主原创,未经本人允许,禁止转载!
文章评论(0条评论)
登录后参与讨论