Commit 2b83af9e87002b77db85a39125ffa971a843aaa2
1 parent
8d1493f9
New programs to benchmark the transfert rate.
The results are really interesting! - bench-bandwidth-slave.c - bench-bandwidth-master.c
Showing
4 changed files
with
227 additions
and
1 deletions
tests/Makefile.am
| 1 | noinst_PROGRAMS = \ | 1 | noinst_PROGRAMS = \ |
| 2 | unit-test-master \ | 2 | unit-test-master \ |
| 3 | unit-test-slave \ | 3 | unit-test-slave \ |
| 4 | - test-master-random | 4 | + test-master-random \ |
| 5 | + bench-bandwidth-slave \ | ||
| 6 | + bench-bandwidth-master | ||
| 5 | 7 | ||
| 6 | common_ldflags = \ | 8 | common_ldflags = \ |
| 7 | $(top_builddir)/modbus/libmodbus.la | 9 | $(top_builddir)/modbus/libmodbus.la |
| @@ -15,5 +17,11 @@ unit_test_slave_LDADD = $(common_ldflags) | @@ -15,5 +17,11 @@ unit_test_slave_LDADD = $(common_ldflags) | ||
| 15 | test_master_random_SOURCES = test-master-random.c | 17 | test_master_random_SOURCES = test-master-random.c |
| 16 | test_master_random_LDADD = $(common_ldflags) | 18 | test_master_random_LDADD = $(common_ldflags) |
| 17 | 19 | ||
| 20 | +bench_bandwidth_slave_SOURCES = bench-bandwidth-slave.c | ||
| 21 | +bench_bandwidth_slave_LDADD = $(common_ldflags) | ||
| 22 | + | ||
| 23 | +bench_bandwidth_master_SOURCES = bench-bandwidth-master.c | ||
| 24 | +bench_bandwidth_master_LDADD = $(common_ldflags) | ||
| 25 | + | ||
| 18 | INCLUDES = -I$(top_srcdir) | 26 | INCLUDES = -I$(top_srcdir) |
| 19 | CLEANFILES = *~ | 27 | CLEANFILES = *~ |
tests/bench-bandwidth-master.c
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright © 2008 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 | + | ||
| 18 | +#include <stdio.h> | ||
| 19 | +#include <unistd.h> | ||
| 20 | +#include <string.h> | ||
| 21 | +#include <stdlib.h> | ||
| 22 | +#include <time.h> | ||
| 23 | +#include <sys/time.h> | ||
| 24 | + | ||
| 25 | +#include <modbus/modbus.h> | ||
| 26 | + | ||
| 27 | +/* Tests based on PI-MBUS-300 documentation */ | ||
| 28 | +#define SLAVE 0x11 | ||
| 29 | +#define NB_LOOPS 1000 | ||
| 30 | + | ||
| 31 | +#define G_USEC_PER_SEC 1000000 | ||
| 32 | +uint32_t gettime(void) | ||
| 33 | +{ | ||
| 34 | + struct timeval tv; | ||
| 35 | + gettimeofday (&tv, NULL); | ||
| 36 | + | ||
| 37 | + return (uint32_t) tv.tv_sec * G_USEC_PER_SEC + tv.tv_usec; | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +int main(void) | ||
| 41 | +{ | ||
| 42 | + uint8_t *tab_rp_status; | ||
| 43 | + uint16_t *tab_rp_registers; | ||
| 44 | + modbus_param_t mb_param; | ||
| 45 | + int i; | ||
| 46 | + int ret; | ||
| 47 | + int nb_points; | ||
| 48 | + double elapsed; | ||
| 49 | + uint32_t start; | ||
| 50 | + uint32_t end; | ||
| 51 | + uint32_t bytes; | ||
| 52 | + uint32_t rate; | ||
| 53 | + | ||
| 54 | + /* TCP */ | ||
| 55 | + modbus_init_tcp(&mb_param, "127.0.0.1", 1502); | ||
| 56 | + | ||
| 57 | + modbus_connect(&mb_param); | ||
| 58 | + | ||
| 59 | + /* Allocate and initialize the memory to store the status */ | ||
| 60 | + tab_rp_status = (uint8_t *) malloc(MAX_STATUS * sizeof(uint8_t)); | ||
| 61 | + memset(tab_rp_status, 0, MAX_STATUS * sizeof(uint8_t)); | ||
| 62 | + | ||
| 63 | + /* Allocate and initialize the memory to store the registers */ | ||
| 64 | + tab_rp_registers = (uint16_t *) malloc(MAX_REGISTERS * sizeof(uint16_t)); | ||
| 65 | + memset(tab_rp_registers, 0, MAX_REGISTERS * sizeof(uint16_t)); | ||
| 66 | + | ||
| 67 | + printf("READ COIL STATUS\n\n"); | ||
| 68 | + | ||
| 69 | + nb_points = MAX_STATUS; | ||
| 70 | + start = gettime(); | ||
| 71 | + for (i=0; i<NB_LOOPS; i++) { | ||
| 72 | + ret = read_coil_status(&mb_param, SLAVE, 0, nb_points, tab_rp_status); | ||
| 73 | + } | ||
| 74 | + end = gettime(); | ||
| 75 | + elapsed = (end - start) / 1000; | ||
| 76 | + | ||
| 77 | + rate = (NB_LOOPS * nb_points) * G_USEC_PER_SEC / (end - start); | ||
| 78 | + printf("Transfert rate in points/seconds:\n"); | ||
| 79 | + printf("* %'d points/s\n", rate); | ||
| 80 | + printf("\n"); | ||
| 81 | + | ||
| 82 | + bytes = NB_LOOPS * (nb_points / 8) + ((nb_points % 8) ? 1 : 0); | ||
| 83 | + rate = bytes / 1024 * G_USEC_PER_SEC / (end - start); | ||
| 84 | + printf("Values:\n"); | ||
| 85 | + printf("* %d x %d values\n", NB_LOOPS, nb_points); | ||
| 86 | + printf("* %.3f ms for %d bytes\n", elapsed, bytes); | ||
| 87 | + printf("* %'d KiB/s\n", rate); | ||
| 88 | + printf("\n"); | ||
| 89 | + | ||
| 90 | + /* TCP: Query and reponse header and values */ | ||
| 91 | + bytes = 12 + 9 + (nb_points / 8) + ((nb_points % 8) ? 1 : 0); | ||
| 92 | + printf("Values and TCP Modbus overhead:\n"); | ||
| 93 | + printf("* %d x %d bytes\n", NB_LOOPS, bytes); | ||
| 94 | + bytes = NB_LOOPS * bytes; | ||
| 95 | + rate = bytes / 1024 * G_USEC_PER_SEC / (end - start); | ||
| 96 | + printf("* %.3f ms for %d bytes\n", elapsed, bytes); | ||
| 97 | + printf("* %'d KiB/s\n", rate); | ||
| 98 | + printf("\n\n"); | ||
| 99 | + | ||
| 100 | + printf("READ HOLDING REGISTERS\n\n"); | ||
| 101 | + | ||
| 102 | + nb_points = MAX_REGISTERS; | ||
| 103 | + start = gettime(); | ||
| 104 | + for (i=0; i<NB_LOOPS; i++) { | ||
| 105 | + ret = read_holding_registers(&mb_param, SLAVE, 0, nb_points, tab_rp_registers); | ||
| 106 | + } | ||
| 107 | + end = gettime(); | ||
| 108 | + elapsed = (end - start) / 1000; | ||
| 109 | + | ||
| 110 | + rate = (NB_LOOPS * nb_points) * G_USEC_PER_SEC / (end - start); | ||
| 111 | + printf("Transfert rate in points/seconds:\n"); | ||
| 112 | + printf("* %'d registers/s\n", rate); | ||
| 113 | + printf("\n"); | ||
| 114 | + | ||
| 115 | + bytes = NB_LOOPS * nb_points * sizeof(uint16_t); | ||
| 116 | + rate = bytes / 1024 * G_USEC_PER_SEC / (end - start); | ||
| 117 | + printf("Values:\n"); | ||
| 118 | + printf("* %d x %d values\n", NB_LOOPS, nb_points); | ||
| 119 | + printf("* %.3f ms for %d bytes\n", elapsed, bytes); | ||
| 120 | + printf("* %'d KiB/s\n", rate); | ||
| 121 | + printf("\n"); | ||
| 122 | + | ||
| 123 | + /* TCP:Query and reponse header and values */ | ||
| 124 | + bytes = 12 + 9 + (nb_points * sizeof(uint16_t)); | ||
| 125 | + printf("Values and TCP Modbus overhead:\n"); | ||
| 126 | + printf("* %d x %d bytes\n", NB_LOOPS, bytes); | ||
| 127 | + bytes = NB_LOOPS * bytes; | ||
| 128 | + rate = bytes / 1024 * G_USEC_PER_SEC / (end - start); | ||
| 129 | + printf("* %.3f ms for %d bytes\n", elapsed, bytes); | ||
| 130 | + printf("* %'d KiB/s\n", rate); | ||
| 131 | + printf("\n"); | ||
| 132 | + | ||
| 133 | + /* Free the memory */ | ||
| 134 | + free(tab_rp_status); | ||
| 135 | + free(tab_rp_registers); | ||
| 136 | + | ||
| 137 | + /* Close the connection */ | ||
| 138 | + modbus_close(&mb_param); | ||
| 139 | + | ||
| 140 | + return 0; | ||
| 141 | +} |
tests/bench-bandwidth-slave.c
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright © 2008 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 | + | ||
| 18 | +#include <stdio.h> | ||
| 19 | +#include <unistd.h> | ||
| 20 | +#include <string.h> | ||
| 21 | +#include <stdlib.h> | ||
| 22 | + | ||
| 23 | +#include <modbus/modbus.h> | ||
| 24 | + | ||
| 25 | +int main(void) | ||
| 26 | +{ | ||
| 27 | + int socket; | ||
| 28 | + modbus_param_t mb_param; | ||
| 29 | + modbus_mapping_t mb_mapping; | ||
| 30 | + int ret; | ||
| 31 | + | ||
| 32 | + modbus_init_tcp(&mb_param, "127.0.0.1", 1502); | ||
| 33 | + | ||
| 34 | + ret = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0); | ||
| 35 | + if (ret == FALSE) { | ||
| 36 | + printf("Memory allocation failed\n"); | ||
| 37 | + exit(1); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + socket = modbus_init_listen_tcp(&mb_param); | ||
| 41 | + | ||
| 42 | + while (1) { | ||
| 43 | + uint8_t query[MAX_MESSAGE_LENGTH]; | ||
| 44 | + int query_size; | ||
| 45 | + | ||
| 46 | + ret = modbus_listen(&mb_param, query, &query_size); | ||
| 47 | + if (ret == 0) { | ||
| 48 | + manage_query(&mb_param, query, query_size, &mb_mapping); | ||
| 49 | + } else if (ret == CONNECTION_CLOSED) { | ||
| 50 | + /* Connection closed by the client, end of server */ | ||
| 51 | + break; | ||
| 52 | + } else { | ||
| 53 | + printf("Error in modbus_listen (%d)\n", ret); | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + close(socket); | ||
| 58 | + modbus_mapping_free(&mb_mapping); | ||
| 59 | + modbus_close(&mb_param); | ||
| 60 | + | ||
| 61 | + return 0; | ||
| 62 | +} | ||
| 63 | + |
tests/wscript
| @@ -19,3 +19,17 @@ def build(bld): | @@ -19,3 +19,17 @@ def build(bld): | ||
| 19 | obj.uselib_local = 'modbus' | 19 | obj.uselib_local = 'modbus' |
| 20 | obj.target = 'test-master-random' | 20 | obj.target = 'test-master-random' |
| 21 | obj.inst_var = 0 | 21 | obj.inst_var = 0 |
| 22 | + | ||
| 23 | + obj = bld.create_obj('cc', 'program') | ||
| 24 | + obj.source = 'bench-bandwidth-slave.c' | ||
| 25 | + obj.includes = '. ..' | ||
| 26 | + obj.uselib_local = 'modbus' | ||
| 27 | + obj.target = 'bench-bandwidth-slave' | ||
| 28 | + obj.inst_var = 0 | ||
| 29 | + | ||
| 30 | + obj = bld.create_obj('cc', 'program') | ||
| 31 | + obj.source = 'bench-bandwidth-master.c' | ||
| 32 | + obj.includes = '. ..' | ||
| 33 | + obj.uselib_local = 'modbus' | ||
| 34 | + obj.target = 'bench-bandwidth-master' | ||
| 35 | + obj.inst_var = 0 |