freemodbus移植、实例及其测试方法

Modbus简介

参考:Modbus​协议​深入​讲解 https://www.ni.com/zh-cn/innovations/white-papers/14/the-modbus-protocol-in-depth.html

http://www.sohu.com/a/230628953_315598

官方文档:http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf

Modbus协议包括ASCII、RTU、TCP等,并没有规定物理层。此协议定义了控制器能够认识和使用的消息结构,而不管它们是经过何种网络进行通信的。标准的Modicon控制器使用RS232C实现串行的Modbus。Modbus的ASCII、RTU协议规定了消息、数据的结构、命令和就答的方式,数据通讯采用Maser/Slave方式,Master端发出数据请求消息,Slave端接收到正确消息后就可以发送数据到Master端以响应请求;Master端也可以直接发消息修改Slave端的数据,实现双向读写。

其通信协议理解也比较简单,其帧结构如下

地址码 + 功能码 + 数据区 + 错误校验

常用功能码

最常使用的读写功能码如下;

01   读取单个/多个线圈状态(类似DO:数字输出)

02   读取单个/多个离散输入(类似DI:数字输入)

03   读取单个/多个保存寄存器

04   读取单个/多个输入寄存器(类似AI:模拟输入)

05   写单个线圈状态

06   写单个保存寄存器

15   写多个线圈

16   写多个保存寄存器

FreeModbus简析

FreeMODBUS 提供了RTU/ASCII 传输模式及TCP协议支持。

FreeModbus协议对硬件的需求非常少——基本上任何具有串行接口,并且有一些能够容纳modbus数据帧的RAM的微控制器都足够了。

现支持如下功能码:

  • Read Input Register (0x04)
  • Read Holding Registers (0x03)
  • Write Single Register (0x06)
  • Write Multiple Registers (0x10)
  • Read/Write Multiple Registers (0x17)
  • Read Coils (0x01)
  • Write Single Coil (0x05)
  • Write Multiple Coils (0x0F)
  • Read Discrete Inputs (0x02)
  • Report Slave ID (0x11)

FreeModbus源码解析

参考:https://blog.csdn.net/u014748120/article/details/80313215

待续。。。

Modbus通信实现

本文测试主机为 arm-linux,可以使用 libmodbus 静态库实现modbus通信,为追求可移植性,本文主要使用 freemodbus 来实现。

1. libmodbus使用

ubuntu系统使用libmodbus可以使用以下命令安装

sudo apt-get install libmodbus-dev# 或者sudo apt-get install libmodbus5

使用文档参考:https://libmodbus.org/documentation/

库参考手册:https://libmodbus.org/docs/v3.1.4/

移植到arm的话则需下载源码进行交叉编译  http://libmodbus.org/releases/libmodbus-3.1.4.tar.gz

解压安装

tar -xzvf libmodbus-3.1.4.tar.gzcd libmodbus-3.1.4# 新建安装文件夹mkdir -p installchmod 777 install./configure --prefix=$(pwd)/install --host=arm-linux --enable-static ac_cv_func_malloc_0_nonnull=yes CC=arm-fsl-linux-gnueabi-gccmakemake install

在我的应用程序工程里面新建一个 libmodbus 文件夹,将上面安装 install目录下的 include和lib文件夹拷贝过来

我的工程总体结构如下所示

在 mys_src 里面添加 modbus 主机测试程序 modbus_test.c

makefile编写如下所示:

#编译配置,使能为1CONFIG_MODBUS_BUILD = 1#当前路径CUR_DIR := $(shell pwd)#libmodbus目录LIBMODBUS_DIR := $(CUR_DIR)/../libmodbus# 头文件路径INCLUDE :=INCLUDE += -I$(CUR_DIR)/../include/ifeq ($(CONFIG_MODBUS_BUILD), 1)INCLUDE += -I$(LIBMODBUS_DIR)/include/modbus/endif#C编译器的选项CFLAGS :=CFLAGS += -g -WallCFLAGS += -std=gnu99CFLAGS += $(INCLUDE)#库文件参数LDFLAGS :=#libmodbus共享库链接#LDFLAGS += -L$(LIBMODBUS_DIR)/lib#libmodbus静态库链接ifeq ($(CONFIG_MODBUS_BUILD), 1)LDFLAGS += $(LIBMODBUS_DIR)/lib/libmodbus.aendifSRCS += modbus_test.cOBJS += modbus_test.oBINS += modbus_testall:$(OBJS) $(BINS) $(OBJS):%.o:%.c    $(CC) -c $(CFLAGS) $^ -o $(OBJ_DIR)/$@$(BINS):$(OBJS)    $(CC) -o $(BIN_DIR)/$@ $(OBJ_DIR)/$^ $(LDFLAGS)

modbus_test.c

#include <stdio.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <modbus.h>#define MODBUS_DEV_NAME    "/dev/ttymxc3"    ///< 串口设备int main(void){    modbus_t *ctx =NULL;    // 以串口的方式创建libmobus实例,并设置参数    ctx = modbus_new_rtu(MODBUS_DEV_NAME, 115200, 'N', 8, 1);    if (ctx == NULL)                //使用UART4,对应的设备描述符为ttymxc3    {        fprintf(stderr, "Unable to allocate libmodbus contex\n");        return -1;    }    // 使用RS485时需考虑设置串口模式、RTS引脚等//    modbus_rtu_set_serial_mode(MODBUS_RTU_RS485);    //设置串口模式    modbus_set_debug(ctx, 1);      //设置1可看到调试信息    modbus_set_slave(ctx, 1);      //设置slave ID    if (modbus_connect(ctx) == -1) //等待连接设备    {        fprintf(stderr, "Connection failed:%s\n", modbus_strerror(errno));        return -1;    }    int i,rc;    uint16_t tab_reg[64] = {0}; //定义存放数据的数组    while (1)    {        printf("\n----------------\n");        //读取保持寄存器的值,可读取多个连续输入保持寄存器        rc = modbus_read_registers(ctx, 0, 10, tab_reg);        if (rc == -1)        {            fprintf(stderr,"%s\n", modbus_strerror(errno));            return -1;        }        for (i=0; i<10; i++)        {            printf("reg[%d] = %d(0x%x)\n", i, tab_reg[i], tab_reg[i]);        }        usleep(5000000);    }    modbus_close(ctx);  //关闭modbus连接    modbus_free(ctx);   //释放modbus资源,使用完libmodbus需要释放掉    return 0;}

编译之后可通过nfs挂载进行测试

modbus从机模拟

Modbus slave测试工具可以用来做modbus从机设备,从而实现arm控制板通过串口与PC端模拟的modbus从机进行通信测试。

Modbus slave下载地址:https://www.modbustools.com/download/ModbusSlaveSetup64Bit.exe

然后设置 setup->slave definition   从机ID、设置为保存寄存器,10条

同时我们也给寄存器设置一些值

开发板运行测试程序后,成功读取modbus从机寄存器值

2.freemodbus在linux上的使用

(0)

相关推荐