libmodbus-3.1.6 linux编译动态/静态链接库

libmodbus-3.1.6 linux编译动态/静态链接库,并在c++下使用

既然想到这个库了,那自然应该都清楚其来历和用途了,本文就不再做过多介绍了。本文主要讲解如何将libmodbus-3.1.6源码编译成动态或者静态链接库,以便在项目中使用。

1.源码下载

下载地址:https://github.com/stephane/libmodbus

2.源码提取

解下下载的源码包,创建一个文件夹,文件夹命明随意,将源码包中的src目录下的 .h 和 .c 文件全部拷贝到刚创建的文件夹下,如下图所示:
在这里插入图片描述
当然,嫌麻烦可以去下载我整理好的编译包https://download.csdn.net/download/sf877/88632947

3.编写makefile

在上面创建的目录中新建一个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/

我这里是带了交叉编译环境,如果有交叉编译需要,可以将交叉编译环境改为自己的即可。

4.编译库

新建终端,cd 进入该目录,输入:

make

即可同时编译出动态链接库和静态链接库;

5.编写从站测试

如果直接用我上面的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,正常会看到如下打印信息:
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值