基于libmodbus3.1.6版本环境搭建及demo

libmodbus3.1.6版本搭建开发环境&&demo

  1. 解压:tar -zxvf libmodbus-3.1.6.tar.gz
  2. 创建安装目录:mkdir install
  3. 进入源文件里面:cd libmodbus-3.1.6
  4. 配置环境安装路径和交叉编译链:
    ./configure --host=交叉编译工具链 --enable-static --prefix=安装路径
    安装路径:/home/hison/install/
    交叉编译工具链:mipsel-linux-

交叉工具链地址查找方法:新打开一个标签页 输入命令 mipsel-linux-gcc -v
也就是查看自己的交叉工具链版本号 里面的目标环境就是交叉工具链

  1. 进入cd /libmodbus-3.1.6目录,执行 ./configure运行出现如下界面即可进行下一步
    执行./configure运行图
    6、执行之后/libmodbus-3.1.6目录出现个Makefile,执行make
    编译好库文件效果图

  2. 安装到工作路径:make install
    在这里插入图片描述

  3. 大功告成 lib动态库即可大显身手哦!

Modbus_TCP 客户端小demo

#include <stdio.h>
#include "modbus.h"
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main(int argc,char *argv[])
{
	int i = 0;
    int s, ser;
	int rc = 0;
	
	//创建套接字ctx
	modbus_t *ctx = NULL;
    //绑定 ip, port
    ctx = modbus_new_tcp("192.168.1.2", 502); 
    //定义从机地址 
    modbus_set_slave(ctx, 2); 
	//监听从机连接 
    ser = modbus_tcp_listen(ctx, 128);
	//定义映射内存空间
	modbus_mapping_t *mb_mapping = NULL;								
	//modbus数据存储 
	uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];									     
	
	for(;;)
	{
		/*
			接受客户端发来的信息  对于此函数本人的理解是这样的
			服务器阻塞客户端连接
			不能连续阻塞Listen就相当于中介 accept具体的卖家 手头有我要的东西
			中介只负责往里接客 卖家就负责将自己的货卖出去
		*/
		s = modbus_tcp_accept(ctx, &ser);
			
		printf("Master3:Connect to client's get ready!\n");			
		//映射虚拟内存
		mb_mapping = modbus_mapping_new(MODBUS_MAX_READ_BITS, 0,
										MODBUS_MAX_READ_REGISTERS, 0);//包含保持位、输入位、保持寄存器、输入寄存器
		if (mb_mapping == NULL) {
			fprintf(stderr, "Failed to allocate the mapping: %s\n",
					modbus_strerror(errno));
			modbus_free(ctx);
			return -1;
		}
		//初始化几个保持寄存器
	   mb_mapping->tab_registers[0] = 1;
	   mb_mapping->tab_registers[1] = 2;
	   mb_mapping->tab_registers[2] = 3;
	   mb_mapping->tab_registers[3] = 4;
	   mb_mapping->tab_registers[4] = 5;
	   mb_mapping->tab_registers[5] = 6;
		/*mb_mapping1 = modbus_mapping_new(0, MODBUS_MAX_WRITE_BITS,
											0, MODBUS_MAX_WRITE_REGISTERS);
		if (mb_mapping1 == NULL) {
		fprintf(stderr, "Failed to allocate the mapping1: %s\n",
		modbus_strerror(errno));
		modbus_free(ctx);
		return -1;
		}*/
			
		for(;;)
		{				
			
			/*
				网络OSI模型 总共分为7层:
				应用层 表示层 会话层 物理层  网络层 数据链路层 传输层
				
				TCP/IP模型
				应用层 物理层 网络层(IP层) 传输层(网络接口层)
			*/
				//MODBUS CTRL PROGRAM	
				memset(query, 0, sizeof(query));		//对寄存器清零
				rc = modbus_receive(ctx, query);		//接受信息函数
				
				if (rc > 0) {
				   
					for(;i<12;i++){	//查看modbus协议码 判断功能码所在内存
						printf("query[%d]=%d(0x%x)\n",i,query[i]);}	
					int rc = modbus_reply(ctx, query, rc, mb_mapping);		//响应信息函数
					if(rc==-1)
					{
						 fprintf(stderr, "Write err: %s\n",
							modbus_strerror(errno));
						modbus_free(ctx);
						return -1;
					}
					
					if(query[7]=0x03)
					{
						//保持寄存器
					}
					
					else if(query[7]==0x04)
					{
						//输入寄存器
					}
					
				}
				else if (rc  == -1) {
					//Connection closed by the client or error
					printf("Quit the loop2: %s\n", modbus_strerror(errno));
					break;
				}
		}
	}
		
	close(s);							//结束从机连接 
    modbus_close(ctx);
    modbus_free(ctx);
    modbus_mapping_free(mb_mapping); 	//释放申请的虚拟内存空间
	return 0;
}

此程序仅限借鉴,希望各位大佬多提点建议,本人第一次解协议,modbus是工业通用的协议之一,默认端口502,好了 就是这些了。

libmodbus 是一个开源的库,用于与各种类型的工业设备进行Modbus协议的通信。为了提高通信稳定性,你可以从以下几个方面进行设置: 1. 设置超时:为读写操作设置合理的超时时间,以便在网络不稳定时能够及时重新尝试。 2. 设置重试次数:在网络请求失败时进行重试,直到达到最大重试次数。 3. 错误处理:增加错误检测和处理机制,比如自动重连等。 以下是一个简单的代码示例,展示了如何使用libmodbus库设置超时时间和重试次数: ```c #include <stdio.h> #include <modbus.h> int main() { modbus_t *ctx; int rc; uint16_t tab_reg[32]; // 创建一个新的Modbus RTU上下文 ctx = modbus_new_rtu("/dev/ttyUSB0", 19200, 'N', 8, 1); if (ctx == NULL) { fprintf(stderr, "Unable to create the libmodbus context\n"); return -1; } // 设置超时时间和重试次数 modbus_set_slave(ctx, 1); // 设置从设备地址 modbus_set_timeout(ctx, 1); // 设置超时时间为1秒 modbus_set_retries(ctx, 3); // 设置重试次数为3 // 连接到串行设备 rc = modbus_connect(ctx); if (rc == -1) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; } // 读取保持寄存器 rc = modbus_read_registers(ctx, 0, 10, tab_reg); if (rc == -1) { fprintf(stderr, "Read failed: %s\n", modbus_strerror(errno)); } else { printf("Read %d registers\n", rc); for (int i = 0; i < rc; i++) { printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]); } } // 断开连接 modbus_close(ctx); modbus_free(ctx); return 0; } ``` 在这个示例中,我们首先创建了一个Modbus RTU上下文,并设置了从设备地址、超时时间和重试次数。然后尝试连接到串行设备,并读取保持寄存器的值。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值