modbus协议是一种已广泛应用于当今工业控制领域的通用通讯协议。通过此协议,控制器相互之间、或控制器经由网络(如以太网)可以和其它设备之间进行通信。modbus协议使用的是主从通讯技术,即由主设备主动查询和操作从设备。一般将主控设备方所使用的协议称为modbus master,从设备方使用的服务器协议称为modbus slave。典型的主设备包括工控机和工业控制器等;典型的从设备如plc可编程控制器等。modbus通讯物理接口可以选用串口(包括rs232和rs485),也可以选择以太网口。其通信遵循以下的过程:
• 主设备向从设备发送请求;
• 从设备分析并处理主设备的请求,然后向主设备发送结果;
• 如果出现任何差错,从设备将返回一个异常功能码。
英创公司提供的arm9嵌入式主板系列产品,均带有丰富的串口、网络资源、通用gpio接口等,同时具有强大的处理能力,除了适用于作为modbus 主设备的开发应用,还可以作为modbus从设备的开发应用。主控协议软件在英创的“linux下的modbus主控协议软件”一文已有介绍, 在本文中主要介绍基于实现modbus设备方协议的软件包“linux下的modbus设备方协议软件”(以下简称mbusslave软件包)。该软件的是以c函数加静态库libmbusslave.a的形式提供给客户。主要特征如下:
• 非常适用于实时的工业应用。
• 可以支持基于串口的modbus协议应用或者基于tcp的modbus协议应用。
• 支持rtu传输模式。
• 支持大多数的modbus功能码操作,包括对线圈、离散开关输入的位操作,以及对寄存器的字节操作。
• 可以获取通讯中传输协议的错误代码的详细信息。
作为modbus服务器,无论是基于串口还是基于tcp,在英创提供的mbusslave软件包中,实现了对于modbus应用报文的分析与响应,这只是modbus通讯的一部分。另一部分是还需要有对应用数据的访问,这部分的内容则需要用户自己来进行定义,为了方便客户的使用,在mbusslave软件包中通过函数指针的形式,实现了这些用户接口函数的自动加载,将用户应用数据处理和modbus应用报文响应关联起来。用户只需根据需求定义这些接口函数来实现相应的功能,各个函数具体的定义是通过专门的一个cpp文件:dataprovider.cpp来实现。所以在使用英创的mbusslave软件包时,有两个部分组成,一部分是 modbus_slave.h/ libmbusslave.a定义的api函数;另一部分是dataprovider.h /dataprovider.cpp定义的用户数据接口函数,其中接口函数需要用户在dataprovider.cpp中具体实现。
一、mbusslave软件包api函数
为了方便应用程序的使用,对不同的通讯介质保持一致的代码形式,英创所提供的mbusslave软件包的api函数可以同时支持基于串口和tcp的modbus协议,应用程序只需要在调用初始化函数时,用不同参数区分即可。以下介绍英创modbusslave软件包的相关api函数,各个函数的定义如下:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
功能描述:
通过串口或者网络tcp打开modbus协议,连接到modbus设备。对于串口方式,通过该函数打开串口,并设置相应串口的通讯参数,以满足数据和控制命令的通讯;对于tcp方式,通过该函数和modbus设备建立基于socket方式的tcp连接,利用该连接进行数据和控制命令的通讯。
输入参数 pportname:
该参数为char类型的字符串,该字符串中包含了启动modbus协议的需要设置的通讯参数信息。对于串口模式和tcp两种模式分别采用不同的格式的字符串。
(1) 串口模式:
字符串必须以ttys作为开头,后面再带上需要设置的串口通讯参数。格式为: ttysidx:baudrate-databits-stopbits-parity
其中idx为串口序号,':' 后为串口通讯参数,各个通讯参数均用整型数据来表示,依次为波特率、数据位、停止位、校验位,校验位 0-无校验 1-奇校验 2-偶校验。
如ttys2作为通讯的协议口,波特率:9600bps、8为数据位、1个停止位、无校验。其格式如下:'ttys2:9600-8-1-0' ;
也可以直接就用 'ttys2' 来表示,表明串口所用的为缺省参数:波特率 9600bps 数据位 8 停止位 1 无奇偶校验。
(2) tcp模式:
字符串以ip地址或者”*”作为开头,':'后为指定tcp连接的特殊端口号,modbus协议中缺省端口为502。如果不需要指定特殊端口,可以不带此参数。格式如:'192.168.201.178' 或者“*”,使用端口号为502;
slaveaddr:
modbus slave设备地址。
timeout:
设置modbus协议通讯响应的超时时间,单位为毫秒ms
mbusslave_interface:
数据处理函数指针结构,即需要加载modbus slave设备响应各个功能的用户数据处理接口函数。这些用户接口函数是由用户自己提供,用户可以根据选择的功能来实现。这些函数的名称和定义是固定的。分别为:
(1) 功能:读保持寄存器/读写寄存器,实现功能码3、23
int readholdingregisterstable( int startref, short regarr[], int refcnt );
(2) 功能:写寄存器,实现功能码6、16、22、23
int writeholdingregisterstable( int startref, const short regarr[], int refcnt );
(3) 功能:读输入寄存器,实现功能码4
int readinputregisterstable( int startref, short regarr[], int refcnt );
(4) 功能:读线圈,实现功能码1
int readcoilstable( int startref, char bitarr[], int refcnt );
(5) 功能:写线圈,实现功能码5、15
int writecoilstable( int startref, const char bitarr[], int refcnt );
(6) 功能:读离散量,实现功能码 2
int readinputdiscretestable( int startref, char bitarr[], int refcnt );
返回值 = null: 启动modbus设备失败。
!= null: 启动modbus设备成功,并返回相应的操作句柄。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// (1) handle mbusslave_startupserver( char* pportname, int slaveaddr, int timeout, modbusslave_interface mbusslave_interface );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
功能描述: modbus 服务器执行函数,用于对modbus报文的分析和响应。
该函数为阻塞模式,阻塞的时间为函数mbusslave_startupserver (…)中设置的modbus协议通讯响应的超时时间 timeout,也相当于等待请求响应的超时时间。实际应用中需要在线程中不断地调用该函数。
输入参数
hport: 启动modbus设备后获取的操作句柄
返回值 0: 相应操作成功
!=0: 错误代码,可调用函数mbusslave_geterrortext(…)获取错误的文本信息
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(2) int mbusslave_serverloop( handle hport );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 功能描述: 关闭modbus服务器应用。
输入参数
hport: 启动modbus设备后获取的操作句柄
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// (3) void mbusslave_shutdownserver( handle hport );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
功能描述: 获取modbus软件包的版本信息。
返回值 : modbus软件包的版本信息。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(4) char * mbusslave_getpackageversion( );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
功能描述: 根据错误代码获取错误文本信息。
返回值 :错误文本信息。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(5) char * mbusslave_geterrortext( int errcode );
modbus_slave api调用的使用范例:
1、启动modbus设备方协议
tcp方式:
hport = mbusslave_startupserver( '*', 1, 10000, mbusslave_interface );
串口方式:
hport=mbusslave_startupserver( 'ttys2:9600-8-1-0',1,10000, mbusslave_interface );
2、线程中调用serverloop 响应请求
while( 1 )
{
result = mbusslave_serverloop( hport );
if( result!=0 ) // 检查是否返回错误
{
// 出错处理:本例为获取并打印错误代码的文本信息
strcpy( strtext, mbusslave_geterrortext( result ) );
i1 = strlen( strtext );
if( i1>0 )
{
printf( ' error code: %s!\n', strtext );
}
}
}
二、mbusslave软件包用户接口函数
在dataprovider.h中共定义了6个用户数据接口函数定义如下:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
功能描述: 读保持寄存器/读写寄存器,实现功能码3、23
输入参数
startref: 寄存器的起始地址,范围:1-0x10000
regarr: 读取寄存器的值
refcnt: 需要读取的寄存器数目,范围:1-125
返回值
=1:操作成功
=0:不支持该项操作
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(1)int readholdingregisterstable( int startref, short regarr[], int refcnt );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
功能描述: 写寄存器,实现功能码6、16、22、23
输入参数
startref: 寄存器的起始地址,范围:1-0x10000
regarr: 写寄存器的值
refcnt: 需要操作的寄存器数目,范围:1-125
返回值
=1:操作成功
=0:不支持该项操作
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(2)int writeholdingregisterstable( int startref, const short regarr[], int refcnt );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
功能描述: 读输入寄存器,实现功能码4
输入参数
startref: 寄存器的起始地址,范围:1-0x10000
regarr: 读取寄存器的值
refcnt: 需要读取的寄存器数目,范围:1-125
返回值
=1:操作成功
=0:不支持该项操作
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(3)int readinputregisterstable ( int startref, short regarr[], int refcnt );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
功能描述: 读线圈,实现功能码1
输入参数
startref: 寄存器的起始地址,范围:1-0x10000
bitarr: 读取线圈的值
refcnt: 需要读取的线圈数目,范围:1-2000
返回值
=1:操作成功
=0:不支持该项操作
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(4)int readcoilstable( int startref, char bitarr[], int refcnt );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
功能描述: 写线圈,实现功能码5、15
输入参数
startref: 寄存器的起始地址,范围:1-0x10000
bitarr: 写线圈的值
refcnt: 需要操作的线圈数目,范围:1-2000
返回值
=1:操作成功
=0:不支持该项操作
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(5)int writecoilstable( int startref, const char bitarr[], int refcnt );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
功能描述: 读离散量,实现功能码 2
输入参数
startref: 寄存器的起始地址,范围:1-0x10000
bitarr: 读取离散量的值
refcnt: 需要读取的离散量数目,范围:1-2000
返回值
=1:操作成功
=0:不支持该项操作
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(6)int readinputdiscretestable( int startref, char bitarr[], int refcnt );
英创现有的linux工控主板均可支持该协议软件,感兴趣的客户向公司索取相关的测试代码。
相关阅读:英创嵌入式linux工控主板支持modbus主控协议软件
通用发布全新Ultium电池系统,加速进军电动车领域
5V降压转3.3V,5V转3V降压电源芯片AH8601B
海尔成功构建物联网家庭金融渠道
德州仪器推出首款零漂移、毫微功率放大器
氮化镓外延为何不生长在氮化镓衬底上?
英创信息技术Linux下的Modbus设备方协议软件介绍
该如何渗透检测APP存在的安全漏洞
如何解决5G物联网网关热管理问题
关于局域网和以太网的区别
如何抑制开关电源的输出纹波?
GPS再厉害,我们还是要有自己的北斗
MAX14885E 完全集成的VGA交叉点开关,具有宽带和增
匹克发布全球首款全3D打印的运动生活鞋
设计了一种简单、可靠、实用的超声波发射电路
2012年1-3月电子信息产业固定资产投资情况
华为在计算领域提出“ABC”曲线发展模型
步进电机的作用_步进电机选型
方波倍频器(SN15844N、SN7400N)
华为海思的芯片成长之路
SK海力士推出128层1Tb TLC 4D NAND SSD高容量存储解决方案