赞
踩
既然想到这个库了,那自然应该都清楚其来历和用途了,本文就不再做过多介绍了。本文主要讲解如何将libmodbus-3.1.6源码编译成动态或者静态链接库,以便在项目中使用。
下载地址:https://github.com/stephane/libmodbus
解下下载的源码包,创建一个文件夹,文件夹命明随意,将源码包中的src目录下的 .h 和 .c 文件全部拷贝到刚创建的文件夹下,如下图所示:
当然,嫌麻烦可以去下载我整理好的编译包https://download.csdn.net/download/sf877/88632947
在上面创建的目录中新建一个Makefile文件,Makefile内容如下:
TOOL = x86_64 # TOOL = aarch64 ifeq ($(TOOL), aarch64) CC = aarch64-linux-gnu-gcc AR = aarch64-linux-gnu-ar LIB_PATH = ./lib_aarch64 else ifeq ($(TOOL), x86_64) CC = gcc AR = ar LIB_PATH = ./lib_x86_64 endif endif SRC = $(shell find -name '*.c') #查找目录下所有c文件 OBJS = $(SRC:.c=.o) #把.c变成.o STATIC_LIB = libmodbus.a SHARE_LIB = libmodbus.so INSTALL_PATH = libmodbus ARFLAGS = -rc LDFLAGS = -shared -fpic $(warning program is being complied. the PLATFORM is $(PLATFORM)) all : $(STATIC_LIB) $(SHARE_LIB) $(STATIC_LIB) : $(OBJS) $(AR) $(ARFLAGS) -o $(STATIC_LIB) $(OBJS) $(SHARE_LIB) : $(OBJS) $(CC) $(LDFLAGS) -o $(SHARE_LIB) $(SRC) .PHONY: install install: mkdir -p $(INSTALL_PATH)/include/ mkdir -p $(INSTALL_PATH)/$(LIB_PATH)/ cp $(STATIC_LIB) $(INSTALL_PATH)/$(LIB_PATH)/ cp $(SHARE_LIB) $(INSTALL_PATH)/$(LIB_PATH)/ cp *.h $(INSTALL_PATH)/include/ .PHONY: clean clean: rm -f *.o rm -f *.a rm -f *.so rm -rf ./$(INSTALL_PATH) .PHONY: test test: cp $(STATIC_LIB) ./Test/lib/ cp $(SHARE_LIB) ./Test/lib/ cp *.h ./Test/include/
我这里是带了交叉编译环境,如果有交叉编译需要,可以将交叉编译环境改为自己的即可。
新建终端,cd 进入该目录,输入:
make
即可同时编译出动态链接库和静态链接库;
如果直接用我上面的makefile写法,只需要输入make test
即可自动生成一个 Test 目录,在Tese目录中新建一个 main.cpp 文件,测试代码代码如下(注意修改ip和端口号):
main.cpp
#include <iostream> #include <string> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <sys/time.h> extern "C" { #include <modbus.h> } #define ADDRESS_START 0 //读寄存器起始地址 #define ADDRESS_END 50 //读寄存器结束地址 #define WRITE_START 2 //写寄存器起始地址 #define WRITE_END 12 //写寄存器结束地址 int main() { modbus_t* ModbusTcp; uint16_t tab_reg[100]; memset(tab_reg, 0, sizeof(tab_reg)); uint16_t tab_write[100]; memset(tab_write, 0, sizeof(tab_write)); ModbusTcp = modbus_new_tcp("66.66.66.1", 15000); if (NULL == ModbusTcp) { fprintf(stderr, "Error: %s\n", modbus_strerror(errno)); return 1; } else { printf("设置TCP成功\n"); } // modbus_set_debug(ModbusTcp, true); //设置为调试模式,会打印相关通信数据 int ret = modbus_connect(ModbusTcp); //连接从站 if (-1 == ret) { fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); modbus_free(ModbusTcp); return 1; } uint16_t index = 0; unsigned char buff[1024]; memset(buff, 0, sizeof(buff)); while(ModbusTcp != NULL) { int res = modbus_read_registers(ModbusTcp, ADDRESS_START, ADDRESS_END, tab_reg); //从地址0开始,读取50个线圈 std::cout << "Read res = " << res << std::endl; if(res > 0) { for(int i=0; i<res; i++) { printf("%.4X ", tab_reg[i]); // buff[i*2] = tab_reg[i] >> 8; // buff[1 + i*2] = tab_reg[i]; } printf("\n"); // memcpy(buff, tab_reg, res*2); // unsigned short tt = 0; // memcpy(&tt, &buff[2], sizeof(tt)); // for(int i=0; i<res*2; i++) // { // printf("%.2X ", buff[i]); // } // printf(",\t tt = %d\n", tt); } usleep(500 * 1000); for(int i=0; i<(WRITE_END-WRITE_START); i++) { tab_write[i] = index + i; } ret = modbus_write_registers(ModbusTcp, WRITE_START, WRITE_END, tab_write); if (WRITE_END != ret) { printf("Error modbus_write_bit: %d\n", ret); printf("WRITE_START: %d WRITE_END: %d\n", WRITE_START, WRITE_END); } else { printf("modbus_write_registers() OK, index = %d\n", index); index += 1; } usleep(500 * 1000); } modbus_close(ModbusTcp); modbus_free(ModbusTcp); std::cout << "=====================================" << std::endl; return 0; }
当然还需要编译测试工程所需要的 makefile,在Test目录下再新建一个makefile文件,内容如下:
makefile
CCC=g++ OUTPUT = run CXXFLAGS = -std=c++11 -Wall INC_PATH = -I./include LIBS = lib/libmodbus.so SRC_CPP = $(shell find -name '*.cpp') #查找目录下所有cpp文件 OBJS_CPP = main.o #$(SRC_CPP:.cpp=.o) #把.cpp变成.o $(OUTPUT): $(OBJS_CPP) $(CCC) $(OBJS_CPP) $(LIBS) -lm -lpthread -o $(OUTPUT) %.o : %.cpp $(CXX) $(INC_PATH) -c -o $@ $^ $(CXXFLAGS) .PHONY:clean clean: rm $(OBJS_CPP) rm $(OUTPUT)
接下来就可以编译测试工程进行测试了,这里配合测试的工具是Mbslave,正常会看到如下打印信息:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。