/* Display "Hello, world!" in the centre of the screen, call refresh() to show our changes, and sleep() for a few seconds to get the full screen effect */
아무튼 메모리 1Kb 더 먹고 hostname resolve를 제공한다는 것 같은데(resolution은 또 머야..)
그 기능만 차이가 있다면 굳이 pi를 쓸 이유는 없을 듯
TCP (IPv4) Context
The TCP backend implements a Modbus variant used for communications over TCP/IPv4 networks. It does not require a checksum calculation as lower layer takes care of the same.
The TCP PI (Protocol Indepedent) backend implements a Modbus variant used for communications over TCP IPv4 and IPv6 networks. It does not require a checksum calculation as lower layer takes care of the same.
Contrary to the TCP IPv4 only backend, the TCP PI backend offers hostname resolution but it consumes about 1Kb of additional memory.
/* The first value of each array is accessible from the 0 address. */ mb_mapping = modbus_mapping_new(BITS_ADDRESS + BITS_NB, INPUT_BITS_ADDRESS + INPUT_BITS_NB, REGISTERS_ADDRESS + REGISTERS_NB, INPUT_REGISTERS_ADDRESS + INPUT_REGISTERS_NB);
if (p->revents & POLLIN) { modbus_set_socket(ctx, p->fd); // set the socket to libmodbus answers to the right client
uint8_t query[MODBUS_RTU_MAX_ADU_LENGTH]; int rc = modbus_receive(ctx, query); if (rc <= 0) { // connection has been closed actually by the client ::close(p->fd); p = sockets.erase(p); // remove it from the poll-array continue; }
/* rc is the query size */ rc = modbus_reply_callback(ctx, query, rc); // handle the reply (via the callbacks) if (rc < 0) { // error handling - invalid request ::close(p->fd); // close client p = sockets.erase(p); continue; } }
Usage: modpoll [OPTIONS] SERIALPORT|HOST [WRITEVALUES...] Arguments: SERIALPORT Serial port when using Modbus ASCII or Modbus RTU protocol COM1, COM2 ... on Windows /dev/ttyS0, /dev/ttyS1 ... on Linux HOST Host name or dotted IP address when using MDBUS/TCP protocol WRITEVALUES List of values to be written. If none specified (default) modpoll reads data. General options: -m ascii Modbus ASCII protocol -m rtu Modbus RTU protocol (default if SERIALPORT contains a /) -m tcp MODBUS/TCP protocol (default otherwise) -m udp MODBUS UDP -m enc Encapsulated Modbus RTU over TCP -a # Slave address (1-247 for serial, 0-255 for TCP, 1 is default) -r # Start reference (1-65536, 100 is default) -c # Number of values to read (1-125, 1 is default), optional for writing (use -c 1 to force FC5 or FC6) -t 0 Discrete output (coil) data type -t 1 Discrete input data type -t 3 16-bit input register data type -t 3:hex 16-bit input register data type with hex display -t 3:int 32-bit integer data type in input register table -t 3:mod 32-bit module 10000 data type in input register table -t 3:float 32-bit float data type in input register table -t 4 16-bit output (holding) register data type (default) -t 4:hex 16-bit output (holding) register data type with hex display -t 4:int 32-bit integer data type in output (holding) register table -t 4:mod 32-bit module 10000 type in output (holding) register table -t 4:float 32-bit float data type in output (holding) register table -i Slave operates on big-endian 32-bit integers -f Slave operates on big-endian 32-bit floats -e Use Daniel/Enron single register 32-bit mode (implies -i and -f) -0 First reference is 0 (PDU addressing) instead 1 -1 Poll only once only, otherwise every poll rate interval -l # Poll rate in ms, (1000 is default) -o # Time-out in seconds (0.01 - 10.0, 1.0 s is default) Options for MODBUS/TCP, UDP and RTU over TCP: -p # IP protocol port number (502 is default) Options for Modbus ASCII and Modbus RTU: -b # Baudrate (e.g. 9600, 19200, ...) (19200 is default) -d # Databits (7 or 8 for ASCII protocol, 8 for RTU) -s # Stopbits (1 or 2, 1 is default) -p none No parity -p even Even parity (default) -p odd Odd parity -4 # RS-485 mode, RTS on while transmitting and another # ms after
The Modbus protocol defines different data types and functions to read and write them from/to remote devices. The following functions are used by the clients to send Modbus requests:
The server is waiting for request from clients and must answer when it is concerned by the request. The libmodbus offers the following functions to handle requests:
Themodbus_receive()function shall receive an indication request from the socket of the contextctx. This function is used by Modbus slave/server to receive and analyze indication request sent by the masters/clients.
If you need to use another socket or file descriptor than the one defined in the contextctx, see the functionmodbus_set_socket(3).
Themodbus_reply()function shall send a response to received request. The requestreqgiven in argument is analyzed, a response is then built and sent by using the information of the modbus contextctx.
If the request indicates to read or write a value the operation will done in the modbus mappingmb_mappingaccording to the type of the manipulated data.
If an error occurs, an exception response will be sent.
MODBUS-TCP 통신규격에는 마스터(Client)와 슬레이브(Server)의 역할이 나누어져 있습니다. 슬레이브(Server)는 마스터(Client)가 요청하는 데이터에 대해 응답을 해줍니다. 주로 마스터(Client)에는 산업용터치 HMI 기기, 또는 PC 와 같은 상위 기기가 위치합니다. 그리고 슬레이브(Server)에는 TCPPORT 나 PLC 등이 위치합니다. 슬레이브(Server)는 상위기기에서 요청하는 동작만을 하는 수동적인 위치에 있습니다. 반면 마스터(Client)쪽에서는 원하는 데이터를 읽어오거나, 원하는 데이터를 기입하는 등 적극적으로 슬레이브(Server) 기기를 다루어 주어야 합니다.
mb_mapping = modbus_mapping_new(0, 0, 500, 500); if (mb_mapping == NULL) { fprintf(stderr, "Failed to allocate the mapping: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; }
s = modbus_tcp_listen(ctx, 1); modbus_tcp_accept(ctx, &s);
for (;;) { uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH]; int rc;
rc = modbus_receive(ctx, query); printf("SLAVE: regs[] =\t"); for(i = 1; i != 11; i++) { // looks like 1..n index printf("%d ", mb_mapping->tab_registers[i]); } printf("\n");
if (rc > 0) { /* rc is the query size */ modbus_reply(ctx, query, rc, mb_mapping); } else if (rc == -1) { /* Connection closed by the client or error */ break; } }
printf("Quit the loop: %s\n", modbus_strerror(errno));
if (s != -1) { close(s); } modbus_mapping_free(mb_mapping); modbus_close(ctx); modbus_free(ctx);
-m tcp MODBUS/TCP protocol (default otherwise) -a # Slave address (1-255 for serial, 0-255 for TCP, 1 is default)\n -r # Start reference (1-65536, 1 is default) -c # Number of values to read (1-125, 1 is default), optional for writing (use -c 1 to force FC5 or FC6)
GUI는 아니지만 license가 일반적인 사용에는 완전 free 라서 유용하게 쓸 수 있을 지도 모르겠다