Remove constraints on baud rate values
[libmodbus.git] / tests / bandwidth-client.c
blob842462b596a711bdf2414c4b22b36c4ddfb7e2c1
1 /*
2 * Copyright © Stéphane Raimbault <stephane.raimbault@gmail.com>
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
7 #include <stdio.h>
8 #ifndef _MSC_VER
9 #include <sys/time.h>
10 #include <unistd.h>
11 #endif
12 #include <errno.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <time.h>
17 #include <modbus.h>
19 #define G_MSEC_PER_SEC 1000
21 static uint32_t gettime_ms(void)
23 struct timeval tv;
24 #if !defined(_MSC_VER)
25 gettimeofday(&tv, NULL);
26 return (uint32_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
27 #else
28 return GetTickCount();
29 #endif
32 enum {
33 TCP,
34 RTU
37 /* Tests based on PI-MBUS-300 documentation */
38 int main(int argc, char *argv[])
40 uint8_t *tab_bit;
41 uint16_t *tab_reg;
42 modbus_t *ctx;
43 int i;
44 int nb_points;
45 double elapsed;
46 uint32_t start;
47 uint32_t end;
48 uint32_t bytes;
49 uint32_t rate;
50 int rc;
51 int n_loop;
52 int use_backend;
54 if (argc > 1) {
55 if (strcmp(argv[1], "tcp") == 0) {
56 use_backend = TCP;
57 n_loop = 100000;
58 } else if (strcmp(argv[1], "rtu") == 0) {
59 use_backend = RTU;
60 n_loop = 100;
61 } else {
62 printf("Usage:\n %s [tcp|rtu] - Modbus client to measure data bandwidth\n\n",
63 argv[0]);
64 exit(1);
66 } else {
67 /* By default */
68 use_backend = TCP;
69 n_loop = 100000;
72 if (use_backend == TCP) {
73 ctx = modbus_new_tcp("127.0.0.1", 1502);
74 } else {
75 ctx = modbus_new_rtu("/dev/ttyUSB1", 115200, 'N', 8, 1);
76 modbus_set_slave(ctx, 1);
78 if (modbus_connect(ctx) == -1) {
79 fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
80 modbus_free(ctx);
81 return -1;
84 /* Allocate and initialize the memory to store the status */
85 tab_bit = (uint8_t *) malloc(MODBUS_MAX_READ_BITS * sizeof(uint8_t));
86 memset(tab_bit, 0, MODBUS_MAX_READ_BITS * sizeof(uint8_t));
88 /* Allocate and initialize the memory to store the registers */
89 tab_reg = (uint16_t *) malloc(MODBUS_MAX_READ_REGISTERS * sizeof(uint16_t));
90 memset(tab_reg, 0, MODBUS_MAX_READ_REGISTERS * sizeof(uint16_t));
92 printf("READ BITS\n\n");
94 nb_points = MODBUS_MAX_READ_BITS;
95 start = gettime_ms();
96 for (i = 0; i < n_loop; i++) {
97 rc = modbus_read_bits(ctx, 0, nb_points, tab_bit);
98 if (rc == -1) {
99 fprintf(stderr, "%s\n", modbus_strerror(errno));
100 return -1;
103 end = gettime_ms();
104 elapsed = end - start;
106 rate = (n_loop * nb_points) * G_MSEC_PER_SEC / (end - start);
107 printf("Transfer rate in points/seconds:\n");
108 printf("* %d points/s\n", rate);
109 printf("\n");
111 bytes = n_loop * (nb_points / 8) + ((nb_points % 8) ? 1 : 0);
112 rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
113 printf("Values:\n");
114 printf("* %d x %d values\n", n_loop, nb_points);
115 printf("* %.3f ms for %d bytes\n", elapsed, bytes);
116 printf("* %d KiB/s\n", rate);
117 printf("\n");
119 /* TCP: Query and response header and values */
120 bytes = 12 + 9 + (nb_points / 8) + ((nb_points % 8) ? 1 : 0);
121 printf("Values and TCP Modbus overhead:\n");
122 printf("* %d x %d bytes\n", n_loop, bytes);
123 bytes = n_loop * bytes;
124 rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
125 printf("* %.3f ms for %d bytes\n", elapsed, bytes);
126 printf("* %d KiB/s\n", rate);
127 printf("\n\n");
129 printf("READ REGISTERS\n\n");
131 nb_points = MODBUS_MAX_READ_REGISTERS;
132 start = gettime_ms();
133 for (i = 0; i < n_loop; i++) {
134 rc = modbus_read_registers(ctx, 0, nb_points, tab_reg);
135 if (rc == -1) {
136 fprintf(stderr, "%s\n", modbus_strerror(errno));
137 return -1;
140 end = gettime_ms();
141 elapsed = end - start;
143 rate = (n_loop * nb_points) * G_MSEC_PER_SEC / (end - start);
144 printf("Transfer rate in points/seconds:\n");
145 printf("* %d registers/s\n", rate);
146 printf("\n");
148 bytes = n_loop * nb_points * sizeof(uint16_t);
149 rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
150 printf("Values:\n");
151 printf("* %d x %d values\n", n_loop, nb_points);
152 printf("* %.3f ms for %d bytes\n", elapsed, bytes);
153 printf("* %d KiB/s\n", rate);
154 printf("\n");
156 /* TCP:Query and response header and values */
157 bytes = 12 + 9 + (nb_points * sizeof(uint16_t));
158 printf("Values and TCP Modbus overhead:\n");
159 printf("* %d x %d bytes\n", n_loop, bytes);
160 bytes = n_loop * bytes;
161 rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
162 printf("* %.3f ms for %d bytes\n", elapsed, bytes);
163 printf("* %d KiB/s\n", rate);
164 printf("\n\n");
166 printf("WRITE AND READ REGISTERS\n\n");
168 nb_points = MODBUS_MAX_WR_WRITE_REGISTERS;
169 start = gettime_ms();
170 for (i = 0; i < n_loop; i++) {
171 rc = modbus_write_and_read_registers(
172 ctx, 0, nb_points, tab_reg, 0, nb_points, tab_reg);
173 if (rc == -1) {
174 fprintf(stderr, "%s\n", modbus_strerror(errno));
175 return -1;
178 end = gettime_ms();
179 elapsed = end - start;
181 rate = (n_loop * nb_points) * G_MSEC_PER_SEC / (end - start);
182 printf("Transfer rate in points/seconds:\n");
183 printf("* %d registers/s\n", rate);
184 printf("\n");
186 bytes = n_loop * nb_points * sizeof(uint16_t);
187 rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
188 printf("Values:\n");
189 printf("* %d x %d values\n", n_loop, nb_points);
190 printf("* %.3f ms for %d bytes\n", elapsed, bytes);
191 printf("* %d KiB/s\n", rate);
192 printf("\n");
194 /* TCP:Query and response header and values */
195 bytes = 12 + 9 + (nb_points * sizeof(uint16_t));
196 printf("Values and TCP Modbus overhead:\n");
197 printf("* %d x %d bytes\n", n_loop, bytes);
198 bytes = n_loop * bytes;
199 rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
200 printf("* %.3f ms for %d bytes\n", elapsed, bytes);
201 printf("* %d KiB/s\n", rate);
202 printf("\n");
204 /* Free the memory */
205 free(tab_bit);
206 free(tab_reg);
208 /* Close the connection */
209 modbus_close(ctx);
210 modbus_free(ctx);
212 return 0;