移植libmodbus到ARM开发板总结

(一)背景

       项目需要采集RTU设备(工业仪表)的数据,其中涉及Modbus协议及数据转换,因为之前没接触过这块内容,所以准备在Linux环境下移植第三方库 -- libmodbus到开发板,以节省开发时间成本。

(二)调试工具

       Modbus Poll、Modbus Slave、Configure Virtual Serial Port Driver(虚拟串口工具)。

使用说明参见:https://blog.csdn.net/echoszf/article/details/77702599

(三)移植步骤

      主要说明ARM开发板移植部分,这部分自己遇到的问题比较多,虚拟机中Linux移植部分参考比较多,自己主要参考了以下文档:https://blog.csdn.net/u010168781/article/details/73924748          https://blog.csdn.net/zgkxzx/article/details/78231171

1、在移植libmodbus到ARM开发板过程中,copy(编译好的、且适用于ARM平台的)动态库(lib*.so*)到/usr/lib目录时,执行cp libmodbus.so* /usr/lib(常用的动态链接库,存放在该目录下)会出现无法创建的问题(cannot create /usr/lib/libmodbus.so*: Read-only file system)。

      解决方法:执行 wr cp libmodbus* /usr/lib  (wr的作用不是太了解只是在一个技术群里面看到的

2、在使用libmodbus库时,只需要libmodbus.so、libmodbus.so.5、libmodbus.so.5.0.5这3个动态库文件,故只copy上述3个文件至ARM开发板的/usr/lib目录即可。

3、编译应用程序

    (1)在虚拟机共享文件夹share下编辑应用程序modbus-rtu-test.c,在虚拟机Linux终端/mnt/hgfs/share目录copy至/home/liuxu/libmodbus/libmodbus-3.0.6/tests/目录;

      注:个人没有使用Samba服务器;libmodbus库下载、交叉编译、测试见上面链接。

    (2)交叉编译,终端执行arm-fsl-linux-gnueabi-gcc -o modbus-rtu-test modbus-rtu-test.c -L ../../install/lib/ -lmodbus -I ../../install/include/modbus/ 即可生成(ARM)可执行文件modbus-tcp-test(其中,在libmodbus目录下有install和libmodbus-3.0.6两个目录)

      注:可能出现arm-fsl-linux-gnueabi-gcc命令未找到的的问题,原因是安装交叉编译器时,环境变量设置的问题。

      解决方案:(临时设置)添加工具链路径,虚拟机Linux终端执行export PATH=$PATH:/opt/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin/。                                        验证方法:终端执行echo $PATH, 查看PATH的值,如若看到/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin/ 即可解决交叉编译命令找不到的问题。更多见文档《ZLG开发指南》,我这里使用的是一款ZLG的开发板)

      (3)copy可执行文件至 /nfsroot 目录,再至ARM开发板 /mnt 目录,执行 ./modbus-tcp-test 即可运行应用程序。借助调试助手Modbus Slave测试结果如下图

(四)测试程序

/*************************
**
** modbus-rtu-test.c 
** 移植libmodbus库到ZLG开发板,并测试成功
**
**************************/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <modbus.h> //modbus动态库文件

#include "unit-test.h"

int main(int argc, char *argv[])
{
	uint16_t tab_reg[64] = {0}; //定义存放数据的数组
    modbus_t *ctx = NULL;
 
    int rc;
	int i;
							        //以串口的方式创建libmobus实例,并设置参数
	ctx = modbus_new_rtu("/dev/ttySP1", 115200, 'N', 8, 1);					
	if (ctx == NULL)                //使用UART1,对应的设备描述符为ttySP1
	{
    	fprintf(stderr, "Unable to allocate libmodbus contex\n");
    	return -1;
	}
	
	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;
	}
	
	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(3000000);
	}
    modbus_close(ctx);  //关闭modbus连接
	modbus_free(ctx);   //释放modbus资源,使用完libmodbus需要释放掉

	return 0;
}

猜你喜欢

转载自blog.csdn.net/liuxu324/article/details/81747961