free - modbus分析

更新时间:2023-11-28 09:54:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

1. FreeMODUS简介

FreeMODBUS是一个针对嵌入式应用的一个免费(自由)的通用MODBUS协议的实现(移植)。

官方网站http://www.freemodbus.org/index.php?lang=cn

源码下载地址http://sourceforge.net/projects/freemodbus.berlios/?source=directory

Modbus是一个工业制造环境中应用的一个通用协议。一个Modbus通信协议栈包括两层:Modbus应用层协议,该层定义了数据模式和功能;另外一层是网络层。在当前版本中,FreeMODBUS 提供了一个针对Modbus 应用层协议V1.1以及支持在Modbus over serial line speifications 1.0 协议中定义的RTU/ASCII 传输模式。自从0.7版本以后,FreeModbus也支持在 Modbus Messaging on TCP/IP Implementation Guide V1.0a中定义的Modbus TCP协议。FreeModbus是遵循BSD许可证,这意味着用户可以将FreeModbus应用于商业环境中。目前支持的Modbus功能包括: 读输入寄存器(0x04) 读保持寄存器(0x03) 写单个寄存器 (0x06) 写多个寄存器 (0x10) 读/写多个寄存器(0x17) 读线圈状态 (0x01) 写单个线圈(0x05) 写多个线圈(0x0F) 读离散输入(0x02) 报告从结点ID (0x11)

Modbus RTU/ASCII帧的接受和发送通过硬件提取层的回调函数驱动的一个状态机实现的。这就使得该协议很容易移植到新的平台上。当一个数据帧组合完毕,该数据将自动被传到Modbus应用层,数据帧的内容在该应用层得到解释。应用层提供Hooks(钩子函数),以方便增加新的Modbus功能。

如果在处理一个新的数据帧时用到了Modbus TCP,移植层必须向协议层发送一个事件标志。协议层将调用一个返回接收到的Modbus TCP帧的功能函数。如果创建了一个有效的回复并且移植层支持Modbus回复。该层将向子端回复一个反馈。

2. 实现FreeModbus协议所需要的软/硬件需求

实现Modbus协议对硬件的需求是极其少的-任何一个具有串行接口和一定量的能够处理modbus数据帧的RAM就足够了。

一个支持中断的异步串行接口,该中断至少包括接收缓冲区满中断和发送寄存器空中断 一个定时器,用以产生Modbus的RTU模式所需要的T3.5个字符的超时时间

对于软件部分而言,实现Modbus仅仅需要一个简单的事件队列。在STR71X/FreeRTOS 的移植中,使用了FreeRTOS的队列来实现了该事件队列以降低处理Modbus任务时的时间消

耗。较小的微控制器往往不使用实时内核,在这种情况下,可以通过全局变量的使用来实现这个事件队列(Atmel的AVR控制器的移植中使用了该方法)。

实际的内存需求量决定于使用的模块的多少。第一个表列出了所有功能模块所需要的内存量。对应ARM来讲,内存量的获取是通过使用GNUARM编译器在使用-O1命令下统计得来的。AVR所需要得内存量是通过WINAVR编译器在使用-Os命令下统计得来得。

3. demo程序分析

3.1. LPC214X:不带操作系统的RTU/ASCII模式

main函数结构:

eMBInit//初始化modbus工作模式 eMBEnable//使能modbus协议栈 while(1) { eMBPoll//查询、处理modbus事件 }

回调函数

1、读输入寄存器 eMBRegInputCB

参数列表:

pucRegBuffer: 寄存器数据缓冲 usAddress: 寄存器首地址 usNRegs: 寄存器个数

返回值

MB_ENOERR: 成功

MB_ENOREG: 非法寄存器地址

2、读/写保持寄存器 eMBRegInputCB

参数列表:

pucRegBuffer: 寄存器数据缓冲 usAddress: 寄存器首地址 usNRegs: 寄存器个数 eMode 访问模式:读或写

返回值

MB_ENOERR: 成功

MB_ENOREG: 非法寄存器地址

3、读/写线圈寄存器 eMBRegCoilsCB

参数列表:

pucRegBuffer: 寄存器数据缓冲 usAddress: 第一个线圈地址 usNCoils: 线圈个数 eMode 访问模式:读或写

返回值

MB_ENOERR: 成功

MB_ENOREG: 非法寄存器地址

4、读离散输入 eMBRegDiscreteCB

参数列表:

pucRegBuffer: 寄存器数据缓冲 usAddress: 离散输入首地址 usNDiscrete: 离散输入个数

返回值

MB_ENOERR: 成功

MB_ENOREG: 非法寄存器地址

位域操作函数 xMBUtilSetBits xMBUtilGetBits

配置文件mbconfig.h

3.2. LINUX:linux系统下的RTU/ASCII模式

使用线程和线程互斥锁调用eMBPoll,操作串口设备文件实现串口操作,读取系统时间实现定时器操作

3.3. LINUXTCP:linux系统下的TCP模式

使用线程和线程互斥锁调用eMBPoll,监听sockect操作TCP,读取系统时间实现定时器操

实现关键

xMBPortTCPPool

xMBTCPPortSendResponse

3.4. MCF5235TCP:FreeRTOS系统下的TCP模式

网络协议栈使用lwip,信息传递使用mailbox

4. RTU/ASCII模式移植步骤

4.1. 建立新工程

复制demo\\BARE另存为my_target 4.2. 移植平台定义文件port.h

检查demo\\my_target\\port.h是否适合当前平台, 至少应定义临界保护的两个宏 ENTER_CRITICAL_SECTION EXIT_CRITICAL_SECTION

4.3. 移植定时器操作porttimer.c

modbus协议栈需要一个定时器检查帧结束。定时器分辩率应达到半个字符时间,例如波特率115200,数据位10bit时,半个字符时间为(10/115200)/2=43us 这个最小超时时间用于帧间3.5字符时间检测。 ModbusRTU规范中提到:

在通信速率等于或低于19200 bps 时,这两个定时必须严格遵守; 对于波特率大于19200 bps 的情形,应该使用2 个定时的固定值:

建议的字符间超时时间(t1.5)为750μs,帧间的超时时间(t3.5) 为1.750ms。 (FreeMODBUS只使用t3.5作为帧间间隔检测,并没使用t1.5帧内间隔检测) 实现如下函数:

定时器初始化xMBPortTimersInit( USHORT usTim1Timerout50us ) 定时器使能vMBPortTimersEnable 定时器禁止vMBPortTimersDisable

定时器中断服务处理prvvTIMERExpiredISR

并用示波器测量xMBPortTimersInit以50us的定时是否淮确。 因为ASCII模式定时时间很大,xMBPortTimersInit定时时间到达MB_ASCII_TIMEOUT_SEC定时时间也不会超出范围(mbconfig.h中定义) 4.4. 移植串口操作文件portserial.c

RTU/ASCII模式是基于串口的,所以要实现串口适配层的相关函数 串口初始化xMBPortSerialInit

串口收发使能vMBPortSerialEnable 串口发送一字节xMBPortSerialPutByte 串口接收一字节xMBPortSerialGetByte 串口发送中断服务prvvUARTTxReadyISR

串口接收中断服务prvvUARTRxISR 4.5. 移植事件操作文件portevent.c (1) 不使用操作系统

移植任务就完成了,只需在main函数这样调用 eMBInit//初始化modbus工作模式 eMBEnable//使能modbus协议栈 while(1) { eMBPoll()//查询、处理modbus事件 }

(2)使用操作系统

a、创建一个任务,不停地调用eMBPoll while(1) {

eMBPoll(); } b、

修改发送事件到队列的函数xMBPortEventPost(这个函数可能被ISR调用) 修改从队列检索事件的函数xMBPortEventGet.它被eMBPoll周期性地调用。这个函数会一直阻塞到有事件发送到队列. c、另外串口和定时器中断服务函数要修改.

从中断服务函数返回时,协议处理回调函数pxMBFrameCBByteReceived、

pxMBFrameCBTransmitterEmpty和pxMBPortCBTimerExpired返回TRUE时,应执行上下文件切换,因为这时事件已经发送到队列中了,如果忘记这条,协议栈的能性将会非常差。

5. TCP模式移植步骤

5.1. 建立新工程

复制demo\\BARE另存为my_target 5.2. 移植平台定义文件port.h

检查demo\\my_target\\port.h是否适合当前平台 (1)使用操作系统

如果使用操作系统的保护机制,不需要定义临界保护的两个宏 ENTER_CRITICAL_SECTION EXIT_CRITICAL_SECTION (2)不使用操作系统

需要定义临界保护的两个宏 ENTER_CRITICAL_SECTION EXIT_CRITICAL_SECTION

5.3. 移植TCP操作文件porttcp.c

TCP模式是基于TCP网络协议栈的,所以要实现TCP网络适配层的相关函数

本文来源:https://www.bwwdw.com/article/os1t.html

Top