bandwidth-client.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * Copyright © 2008-2010 Stéphane Raimbault <stephane.raimbault@gmail.com>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <stdio.h>
  18. #ifndef _MSC_VER
  19. #include <unistd.h>
  20. #include <sys/time.h>
  21. #endif
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <time.h>
  25. #include <errno.h>
  26. #include <modbus.h>
  27. #define G_MSEC_PER_SEC 1000
  28. uint32_t gettime_ms(void)
  29. {
  30. struct timeval tv;
  31. #if !defined(_MSC_VER)
  32. gettimeofday (&tv, NULL);
  33. #else
  34. SYSTEMTIME st;
  35. GetLocalTime(&st);
  36. tv.tv_sec = st.wSecond;
  37. tv.tv_usec = st.wMilliseconds * 1000;
  38. #endif
  39. return (uint32_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
  40. }
  41. enum {
  42. TCP,
  43. RTU
  44. };
  45. /* Tests based on PI-MBUS-300 documentation */
  46. int main(int argc, char *argv[])
  47. {
  48. uint8_t *tab_bit;
  49. uint16_t *tab_reg;
  50. modbus_t *ctx;
  51. int i;
  52. int nb_points;
  53. double elapsed;
  54. uint32_t start;
  55. uint32_t end;
  56. uint32_t bytes;
  57. uint32_t rate;
  58. int rc;
  59. int n_loop;
  60. int use_backend;
  61. if (argc > 1) {
  62. if (strcmp(argv[1], "tcp") == 0) {
  63. use_backend = TCP;
  64. n_loop = 100000;
  65. } else if (strcmp(argv[1], "rtu") == 0) {
  66. use_backend = RTU;
  67. n_loop = 100;
  68. } else {
  69. printf("Usage:\n %s [tcp|rtu] - Modbus client to measure data bandwith\n\n", argv[0]);
  70. exit(1);
  71. }
  72. } else {
  73. /* By default */
  74. use_backend = TCP;
  75. n_loop = 100000;
  76. }
  77. if (use_backend == TCP) {
  78. ctx = modbus_new_tcp("127.0.0.1", 1502);
  79. } else {
  80. ctx = modbus_new_rtu("/dev/ttyUSB1", 115200, 'N', 8, 1);
  81. modbus_set_slave(ctx, 1);
  82. }
  83. if (modbus_connect(ctx) == -1) {
  84. fprintf(stderr, "Connexion failed: %s\n",
  85. modbus_strerror(errno));
  86. modbus_free(ctx);
  87. return -1;
  88. }
  89. /* Allocate and initialize the memory to store the status */
  90. tab_bit = (uint8_t *) malloc(MODBUS_MAX_READ_BITS * sizeof(uint8_t));
  91. memset(tab_bit, 0, MODBUS_MAX_READ_BITS * sizeof(uint8_t));
  92. /* Allocate and initialize the memory to store the registers */
  93. tab_reg = (uint16_t *) malloc(MODBUS_MAX_READ_REGISTERS * sizeof(uint16_t));
  94. memset(tab_reg, 0, MODBUS_MAX_READ_REGISTERS * sizeof(uint16_t));
  95. printf("READ BITS\n\n");
  96. nb_points = MODBUS_MAX_READ_BITS;
  97. start = gettime_ms();
  98. for (i=0; i<n_loop; i++) {
  99. rc = modbus_read_bits(ctx, 0, nb_points, tab_bit);
  100. if (rc == -1) {
  101. fprintf(stderr, "%s\n", modbus_strerror(errno));
  102. return -1;
  103. }
  104. }
  105. end = gettime_ms();
  106. elapsed = end - start;
  107. rate = (n_loop * nb_points) * G_MSEC_PER_SEC / (end - start);
  108. printf("Transfert rate in points/seconds:\n");
  109. printf("* %d points/s\n", rate);
  110. 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");
  118. /* TCP: Query and reponse header and values */
  119. bytes = 12 + 9 + (nb_points / 8) + ((nb_points % 8) ? 1 : 0);
  120. printf("Values and TCP Modbus overhead:\n");
  121. printf("* %d x %d bytes\n", n_loop, bytes);
  122. bytes = n_loop * bytes;
  123. rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
  124. printf("* %.3f ms for %d bytes\n", elapsed, bytes);
  125. printf("* %d KiB/s\n", rate);
  126. printf("\n\n");
  127. printf("READ REGISTERS\n\n");
  128. nb_points = MODBUS_MAX_READ_REGISTERS;
  129. start = gettime_ms();
  130. for (i=0; i<n_loop; i++) {
  131. rc = modbus_read_registers(ctx, 0, nb_points, tab_reg);
  132. if (rc == -1) {
  133. fprintf(stderr, "%s\n", modbus_strerror(errno));
  134. return -1;
  135. }
  136. }
  137. end = gettime_ms();
  138. elapsed = end - start;
  139. rate = (n_loop * nb_points) * G_MSEC_PER_SEC / (end - start);
  140. printf("Transfert rate in points/seconds:\n");
  141. printf("* %d registers/s\n", rate);
  142. printf("\n");
  143. bytes = n_loop * nb_points * sizeof(uint16_t);
  144. rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
  145. printf("Values:\n");
  146. printf("* %d x %d values\n", n_loop, nb_points);
  147. printf("* %.3f ms for %d bytes\n", elapsed, bytes);
  148. printf("* %d KiB/s\n", rate);
  149. printf("\n");
  150. /* TCP:Query and reponse header and values */
  151. bytes = 12 + 9 + (nb_points * sizeof(uint16_t));
  152. printf("Values and TCP Modbus overhead:\n");
  153. printf("* %d x %d bytes\n", n_loop, bytes);
  154. bytes = n_loop * bytes;
  155. rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
  156. printf("* %.3f ms for %d bytes\n", elapsed, bytes);
  157. printf("* %d KiB/s\n", rate);
  158. printf("\n\n");
  159. printf("READ AND WRITE REGISTERS\n\n");
  160. nb_points = MODBUS_MAX_RW_WRITE_REGISTERS;
  161. start = gettime_ms();
  162. for (i=0; i<n_loop; i++) {
  163. rc = modbus_write_and_read_registers(ctx,
  164. 0, nb_points, tab_reg,
  165. 0, nb_points, tab_reg);
  166. if (rc == -1) {
  167. fprintf(stderr, "%s\n", modbus_strerror(errno));
  168. return -1;
  169. }
  170. }
  171. end = gettime_ms();
  172. elapsed = end - start;
  173. rate = (n_loop * nb_points) * G_MSEC_PER_SEC / (end - start);
  174. printf("Transfert rate in points/seconds:\n");
  175. printf("* %d registers/s\n", rate);
  176. printf("\n");
  177. bytes = n_loop * nb_points * sizeof(uint16_t);
  178. rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
  179. printf("Values:\n");
  180. printf("* %d x %d values\n", n_loop, nb_points);
  181. printf("* %.3f ms for %d bytes\n", elapsed, bytes);
  182. printf("* %d KiB/s\n", rate);
  183. printf("\n");
  184. /* TCP:Query and reponse header and values */
  185. bytes = 12 + 9 + (nb_points * sizeof(uint16_t));
  186. printf("Values and TCP Modbus overhead:\n");
  187. printf("* %d x %d bytes\n", n_loop, bytes);
  188. bytes = n_loop * bytes;
  189. rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
  190. printf("* %.3f ms for %d bytes\n", elapsed, bytes);
  191. printf("* %d KiB/s\n", rate);
  192. printf("\n");
  193. /* Free the memory */
  194. free(tab_bit);
  195. free(tab_reg);
  196. /* Close the connection */
  197. modbus_close(ctx);
  198. modbus_free(ctx);
  199. return 0;
  200. }