forked from m0Ray/modbus-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodbus-id.c
148 lines (136 loc) · 3.94 KB
/
modbus-id.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <error.h>
#include <modbus/modbus.h>
#include <modbus/modbus-rtu.h>
#include "modbustools.h"
void usage(char* self, int e) {
fprintf(stderr, "Usage: %s [-d /dev/ttyX] [-r baudrate] [-b databits] [-p (N|E|O)] [-s stopbits] [-n retries] [-v] <bus_address>\n", self);
fprintf(stderr, "Options description:\n\
-d: UART device (default %s)\n\
-r: UART baud rate: 9600, 19200, 57600, 115200 etc (default %d)\n\
-b: UART data bits: 5-8 (default %d)\n\
-p: UART parity check: None, Even, Odd (default %c)\n\
-b: UART stop bits: 1-2 (default %d)\n\
-n: retry count (default %d)\n\
-v: verbose debug on stderr\n", MODBUSTOOLS_DEFAULT_UART, MODBUSTOOLS_DEFAULT_BAUDRATE, MODBUSTOOLS_DEFAULT_DATABITS, MODBUSTOOLS_DEFAULT_PARITY, MODBUSTOOLS_DEFAULT_STOPBITS, MODBUSTOOLS_DEFAULT_RETRIES);
exit(e);
}
int main( int argc, char** argv ) {
// Configuration variables and defaults
char* uart = MODBUSTOOLS_DEFAULT_UART;
int uart_baudrate = MODBUSTOOLS_DEFAULT_BAUDRATE;
int uart_databits = MODBUSTOOLS_DEFAULT_DATABITS;
char uart_parity = MODBUSTOOLS_DEFAULT_PARITY;
int uart_stopbits = MODBUSTOOLS_DEFAULT_STOPBITS;
int retry = MODBUSTOOLS_DEFAULT_RETRIES;
int debug=0;
long tmp;
// Parse commandline options
int c;
while ((c = getopt (argc, argv, "hd:r:b:p:s:t:n:v")) != -1) {
switch (c) {
case 'h':
usage(argv[0], 0);
case 'd':
uart=optarg;
break;
case 'r':
tmp=strtol(optarg, NULL, 0);
uart_baudrate=(int)tmp;
break;
case 'b':
tmp=strtol(optarg, NULL, 0);
if(tmp>=5 && tmp<=8) {
uart_databits=(int)tmp;
} else {
fprintf(stderr, "%s: invalid UART data bits setting -- %d\n", argv[0], tmp);
exit(1);
}
break;
case 'p':
switch(*optarg) {
case 'N':
case 'E':
case 'O':
uart_parity=*optarg;
break;
default:
fprintf(stderr, "%s: invalid UART parity setting -- '%s'\n", argv[0], optarg);
exit(1);
}
break;
case 's':
tmp=strtol(optarg, NULL, 0);
if(tmp==1 || tmp==2) {
uart_stopbits=(int)tmp;
} else {
fprintf(stderr, "%s: invalid UART stop bits setting -- %d\n", argv[0], tmp);
exit(1);
}
break;
case 'n':
tmp=strtol(optarg, NULL, 0);
if(tmp>0) {
retry=tmp;
} else {
fprintf(stderr, "%s: invalid retry count -- %d\n", argv[0], tmp);
exit(1);
}
break;
case 'v':
debug=1;
break;
}
}
// Determine bus address
int addr;
if((argc-optind)>0) {
long addrl=strtol(argv[optind], NULL, 0);
if( (addrl>=0) && (addrl<=247) ) {
addr=(int)addrl;
} else {
fprintf(stderr, "%s: invalid bus address -- %d, MODBUS allows from 1 to 247 and 0 for broadcast\n", argv[0], addrl);
exit(1);
}
} else {
fprintf(stderr, "%s: not enough arguments\n", argv[0]);
usage(argv[0], 1);
}
// Check UART settings
struct stat info;
if(stat(uart, &info)==0) {
if(!S_ISCHR(info.st_mode)) {
fprintf(stderr, "%s: given UART device is not a character device -- '%s'\n", argv[0], uart);
exit(1);
}
} else {
error(1, errno, "cannot stat UART device '%s'", uart);
}
// Debug output
if(debug) {
printf("Device: %s %d %d/%c/%d\n", uart, uart_baudrate, uart_databits, uart_parity, uart_stopbits);
printf("Bus address: %d\n", addr);
}
// Do real work (at last!)
modbus_t* modbus=modbus_new_rtu(uart, uart_baudrate, uart_parity, uart_databits, uart_stopbits);
if (modbus == NULL) {
fprintf(stderr, "%s: unable to create the libmodbus context\n", argv[0]);
exit(2);
}
modbus_rtu_set_serial_mode(modbus, MODBUS_RTU_RS485); // Make configurable!
if (modbus_connect(modbus) == -1) {
fprintf(stderr, "%s: MODBUS connection failed: %s\n", argv[0], modbus_strerror(errno));
modbus_free(modbus);
exit(2);
}
// Do it!
uint8_t id_rq[] = { 0x00, 0x2B, 0x0E, 0x00, 0x00};
// ^addr ^read device id ^read id code (?) ^object id
modbus_close(modbus);
modbus_free(modbus);
}