转载自:
libmodbus协议栈3—— Linux下 modbus RTU 从机 开发案例
https://blog.csdn.net/u012351051/article/details/89194839
基于libmodbus 开发RTU Slave端测试程序
https://blog.csdn.net/u013422297/article/details/99673488
https://blog.csdn.net/u010168781/article/details/73924748 — good
https://blog.csdn.net/u012351051/article/details/89194839
http://libmodbus.org/download/
ubuntu下使用libmodbus
https://blog.csdn.net/u013074298/article/details/86583417
【modbus】libmodbus库的移植与使用
https://blog.csdn.net/u010168781/article/details/73924974
pip install pylibmodbus
pylibmodbus 0.5.0
https://pypi.org/project/pylibmodbus/
Python Interface for libmodbus written with CFFI.
This libmodbus wrapper is compatible with Python 2 and Python 3.
This wrapper is only compatible with libmodbus v3.1.2 and above.
Required packages:
- python-dev and libffi-dev
- libmodbus and libmodbus-dev
Licensed under BSD 3-Clause (see LICENSE file for details).
Tests
Before running the test suite, you need to launch a TCP server.
You can use the server provided by libmodbus in tests
directory::
$ ./tests/bandwidth-server-many-up
Once this server is running, you can launch the Python tests with::
$ python -m tests
Keywords: python libmodbus
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
/home/sama5d2/buildroot/buildroot-2017.02.2/output/host/usr/bin
2to3 arm-linux-gcc-ar glib-gettextize msggrep
aclocal arm-linux-gcc.br_real glib-mkenums msginit
aclocal-1.15 arm-linux-gcc-nm gobject-query msgmerge
amuFormat.sh arm-linux-gcc-ranlib gresource msgunfmt
arm-buildroot-linux-uclibcgnueabihf-addr2line arm-linux-gcov gsettings msguniq
arm-buildroot-linux-uclibcgnueabihf-ar arm-linux-gcov-tool gtester mshortname
arm-buildroot-linux-uclibcgnueabihf-as arm-linux-gprof gtester-report mshowfat
arm-buildroot-linux-uclibcgnueabihf-c++ arm-linux-ld ifnames mtools
arm-buildroot-linux-uclibcgnueabihf-c++.br_real arm-linux-ld.bfd infocmp mtoolstest
arm-buildroot-linux-uclibcgnueabihf-cc arm-linux-ldconfig infotocap mtype
arm-buildroot-linux-uclibcgnueabihf-cc.br_real arm-linux-ldd kmod mxtar
arm-buildroot-linux-uclibcgnueabihf-c++filt arm-linux-nm ldconfig mzip
arm-buildroot-linux-uclibcgnueabihf-cpp arm-linux-objcopy ldd ncurses5-config
arm-buildroot-linux-uclibcgnueabihf-cpp.br_real arm-linux-objdump libtool pcre-config
arm-buildroot-linux-uclibcgnueabihf-elfedit arm-linux-ranlib libtoolize pcregrep
arm-buildroot-linux-uclibcgnueabihf-g++ arm-linux-readelf linux-dtc pcretest
arm-buildroot-linux-uclibcgnueabihf-g++.br_real arm-linux-size lsattr pkgconf
arm-buildroot-linux-uclibcgnueabihf-gcc arm-linux-strings lz pkg-config
arm-buildroot-linux-uclibcgnueabihf-gcc-5.4.0 arm-linux-strip lzip pydoc
arm-buildroot-linux-uclibcgnueabihf-gcc-5.4.0.br_real attr m4 python
arm-buildroot-linux-uclibcgnueabihf-gcc-ar autoconf makedevs python2
arm-buildroot-linux-uclibcgnueabihf-gcc.br_real autoheader mattrib python2.7
arm-buildroot-linux-uclibcgnueabihf-gcc-nm autom4te mbadblocks python2.7-config
arm-buildroot-linux-uclibcgnueabihf-gcc-ranlib automake mcat python2-config
arm-buildroot-linux-uclibcgnueabihf-gcov automake-1.15 mcd python-config
arm-buildroot-linux-uclibcgnueabihf-gcov-tool autopoint mcheck recode-sr-latin
arm-buildroot-linux-uclibcgnueabihf-gprof autoreconf mclasserase reset
arm-buildroot-linux-uclibcgnueabihf-ld autoscan mcomp rst2html.py
arm-buildroot-linux-uclibcgnueabihf-ld.bfd autoupdate mcopy rst2latex.py
arm-buildroot-linux-uclibcgnueabihf-ldconfig bison mdel rst2man.py
arm-buildroot-linux-uclibcgnueabihf-ldd captoinfo mdeltree rst2odt_prepstyles.py
arm-buildroot-linux-uclibcgnueabihf-nm chattr mdir rst2odt.py
arm-buildroot-linux-uclibcgnueabihf-objcopy clear mdu rst2pseudoxml.py
arm-buildroot-linux-uclibcgnueabihf-objdump compile_et mformat rst2s5.py
arm-buildroot-linux-uclibcgnueabihf-ranlib dtc minfo rst2xetex.py
arm-buildroot-linux-uclibcgnueabihf-readelf easy_install mk_cmds rst2xml.py
arm-buildroot-linux-uclibcgnueabihf-size easy_install-2.7 mke2img rstpep2html.py
arm-buildroot-linux-uclibcgnueabihf-strings faked mkmanifest setfattr
arm-buildroot-linux-uclibcgnueabihf-strip fakeroot mkpasswd smtpd.py
arm-linux-addr2line flex mlabel tabs
arm-linux-ar flex++ mmd tgz
arm-linux-as floppyd mmount tic
arm-linux-c++ floppyd_installtest mmove toe
arm-linux-c++.br_real gapplication mpartition toolchain-wrapper
arm-linux-cc gdbus mrd tput
arm-linux-cc.br_real gdbus-codegen mren tset
arm-linux-c++filt genext2fs msgattrib uuidgen
arm-linux-cpp genimage msgcat uz
arm-linux-cpp.br_real getfattr msgcmp xgettext
arm-linux-elfedit gettextize msgcomm xml2-config
arm-linux-g++ gio msgconv xmlcatalog
arm-linux-g++.br_real gio-querymodules msgen xmllint
arm-linux-gcc glib-compile-resources msgexec xmlwf
arm-linux-gcc-5.4.0 glib-compile-schemas msgfilter yacc
arm-linux-gcc-5.4.0.br_real glib-genmarshal msgfmt
/home/sama5d2/buildroot/buildroot-2017.02.2/output/host/usr/bin
export PATH=$PATH:/home/sama5d2/buildroot/buildroot-2017.02.2/output/host/usr/bin
arm-buildroot-linux-uclibcgnueabihf-gcc -o testaa test.c -L …/install/lib/ -lmodbus -I …/install/include/modbus/
arm-buildroot-linux-uclibcgnueabihf-gcc -o testaa test.c -static -L ../install/lib/ -lmodbus -I ../install/include/modbus/
arm-buildroot-linux-uclibcgnueabihf-gcc -o testaa test.c -static -L …/install/lib/ -lmodbus -I …/install/include/modbus/
#include<stdio.h>
#include<stdlib.h>
#include"modbus.h"
int main(void)
{
modbus_t *mb;
uint16_t tab_reg[32]={0};
mb = modbus_new_rtu("/dev/ttySAC2",19200,'N',8,1);//open port
modbus_set_slave(mb,1);//set slave address
modbus_connect(mb);
struct timeval t;
t.tv_sec=0;
t.tv_usec=1000000;//set modbus time 1000ms
modbus_set_response_timeout(mb,&t);
int regs=modbus_read_registers(mb, 0, 20, tab_reg);
printf("%d %d %d %d %d\n",regs,tab_reg[0],tab_reg[1],tab_reg[2],tab_reg[3]);
modbus_close(mb);
modbus_free(mb);
return 0;
}
程序理解
/home/sama5d2/multi-serial/compile_c/libmodbus-3.0.6/tests/
unit-test.h.in
unit-test-server.c ----- 作为一个 modbus slave 设备
unit-test-client.c ----- 作为一个 modbus master 设备
README
unit-test-server
unit-test-client
----------------
By default, this program sends some queries with the values defined in
unit-test.h and checks the responses. These programs are useful to
test the protocol implementation.
unit-test.h.in
#ifndef _UNIT_TEST_H_
#define _UNIT_TEST_H_
/* Constants defined by configure.ac */
#define HAVE_INTTYPES_H @HAVE_INTTYPES_H@
#define HAVE_STDINT_H @HAVE_STDINT_H@
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
# ifndef _MSC_VER
# include <stdint.h>
# else
# include "stdint.h"
# endif
#endif
#define SERVER_ID 17
#define INVALID_SERVER_ID 18
const uint16_t UT_BITS_ADDRESS = 0x13;
const uint16_t UT_BITS_NB = 0x25;
const uint8_t UT_BITS_TAB[] = { 0xCD, 0x6B, 0xB2, 0x0E, 0x1B };
const uint16_t UT_INPUT_BITS_ADDRESS = 0xC4;
const uint16_t UT_INPUT_BITS_NB = 0x16;
const uint8_t UT_INPUT_BITS_TAB[] = { 0xAC, 0xDB, 0x35 };
const uint16_t UT_REGISTERS_ADDRESS = 0x6B;
/* Raise a manual exception when this adress is used for the first byte */
const uint16_t UT_REGISTERS_ADDRESS_SPECIAL = 0x6C;
const uint16_t UT_REGISTERS_NB = 0x3;
const uint16_t UT_REGISTERS_TAB[] = { 0x022B, 0x0001, 0x0064 };
/* If the following value is used, a bad response is sent.
It's better to test with a lower value than
UT_REGISTERS_NB_POINTS to try to raise a segfault. */
const uint16_t UT_REGISTERS_NB_SPECIAL = 0x2;
const uint16_t UT_INPUT_REGISTERS_ADDRESS = 0x08;
const uint16_t UT_INPUT_REGISTERS_NB = 0x1;
const uint16_t UT_INPUT_REGISTERS_TAB[] = { 0x000A };
const float UT_REAL = 916.540649;
const uint32_t UT_IREAL = 0x4465229a;
#endif /* _UNIT_TEST_H_ */
MODBUS软件开发实战指南.pdf
/* Examples from PI_MODBUS_300.pdf.
Only the read-only input values are assigned. */
modbus RTU Slave ----- 其中 寄存器的起始地址 是 怎么确定的 ?
代码如下:
/*
*----------------------------------------
*
* modbus-rtu-slave.c
*
*----------------------------------------
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <modbus.h>
int main(int argc, char *argv[])
{
int s = -1;
modbus_t *ctx = NULL;
modbus_mapping_t *mb_mapping = NULL;
int rc;
int use_backend;
//初始化modbus rtu
ctx = modbus_new_rtu("/dev/ttyS3", 57600, 'N', 8, 1);
//设定从设备地址
modbus_set_slave(ctx, 203);
//modbus连接
modbus_connect(ctx);
//寄存器map初始化
#if 0
MODBUS_MAX_READ_BITS = 2000
MODBUS_MAX_READ_REGISTERS = 125
MODBUS_TCP_MAX_ADU_LENGTH = 260
#endif
printf("MODBUS_MAX_READ_BITS = %d\n",MODBUS_MAX_READ_BITS) ;
printf("MODBUS_MAX_READ_REGISTERS = %d\n",MODBUS_MAX_READ_REGISTERS) ;
printf("MODBUS_TCP_MAX_ADU_LENGTH = %d\n",MODBUS_TCP_MAX_ADU_LENGTH) ;
mb_mapping = modbus_mapping_new(MODBUS_MAX_READ_BITS, 10,
MODBUS_MAX_READ_REGISTERS, 10);
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;
//循环
while( 1 ){
uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
//轮询接收数据,并做相应处理
rc = modbus_receive(ctx, query);
if (rc > 0) {
modbus_reply(ctx, query, rc, mb_mapping);
printf("*\n");
} else if (rc == -1) {
/* Connection closed by the client or error */
printf("#\n");
//break;
}else{
printf("rc=%d\n",rc);
}
}
printf("Quit the loop: %s\n", modbus_strerror(errno));
modbus_mapping_free(mb_mapping);
if (s != -1) {
close(s);
}
/* For RTU, skipped by TCP (no TCP connect) */
modbus_close(ctx);
modbus_free(ctx);
return 0;
}