Эх сурвалжийг харах

New programs to benchmark the transfert rate.
The results are really interesting!
- bench-bandwidth-slave.c
- bench-bandwidth-master.c

Stéphane Raimbault 17 жил өмнө
parent
commit
2b83af9e87

+ 9 - 1
tests/Makefile.am

@@ -1,7 +1,9 @@
 noinst_PROGRAMS = \
 	unit-test-master \
 	unit-test-slave \
-	test-master-random
+	test-master-random \
+	bench-bandwidth-slave \
+	bench-bandwidth-master
 
 common_ldflags = \
 	$(top_builddir)/modbus/libmodbus.la
@@ -15,5 +17,11 @@ unit_test_slave_LDADD = $(common_ldflags)
 test_master_random_SOURCES = test-master-random.c
 test_master_random_LDADD = $(common_ldflags)
 
+bench_bandwidth_slave_SOURCES = bench-bandwidth-slave.c
+bench_bandwidth_slave_LDADD = $(common_ldflags)
+
+bench_bandwidth_master_SOURCES = bench-bandwidth-master.c
+bench_bandwidth_master_LDADD = $(common_ldflags)
+
 INCLUDES = -I$(top_srcdir)
 CLEANFILES = *~

+ 141 - 0
tests/bench-bandwidth-master.c

@@ -0,0 +1,141 @@
+/*
+ * Copyright © 2008 Stéphane Raimbault <stephane.raimbault@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include <modbus/modbus.h>
+
+/* Tests based on PI-MBUS-300 documentation */
+#define SLAVE     0x11
+#define NB_LOOPS  1000
+
+#define G_USEC_PER_SEC 1000000
+uint32_t gettime(void)
+{
+        struct timeval tv;
+        gettimeofday (&tv, NULL);
+        
+        return (uint32_t) tv.tv_sec * G_USEC_PER_SEC + tv.tv_usec;
+}
+
+int main(void)
+{
+        uint8_t *tab_rp_status;
+        uint16_t *tab_rp_registers;
+        modbus_param_t mb_param;
+        int i;
+        int ret;
+        int nb_points;
+        double elapsed;
+        uint32_t start;
+        uint32_t end;
+        uint32_t bytes;
+        uint32_t rate;
+
+        /* TCP */
+        modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
+      
+        modbus_connect(&mb_param);
+
+        /* Allocate and initialize the memory to store the status */
+        tab_rp_status = (uint8_t *) malloc(MAX_STATUS * sizeof(uint8_t));
+        memset(tab_rp_status, 0, MAX_STATUS * sizeof(uint8_t));
+        
+        /* Allocate and initialize the memory to store the registers */
+        tab_rp_registers = (uint16_t *) malloc(MAX_REGISTERS * sizeof(uint16_t));
+        memset(tab_rp_registers, 0, MAX_REGISTERS * sizeof(uint16_t));
+
+        printf("READ COIL STATUS\n\n");
+
+        nb_points = MAX_STATUS;
+        start = gettime();
+        for (i=0; i<NB_LOOPS; i++) {
+                ret = read_coil_status(&mb_param, SLAVE, 0, nb_points, tab_rp_status);
+        }
+        end = gettime();
+        elapsed = (end - start) / 1000;
+
+        rate = (NB_LOOPS * nb_points) * G_USEC_PER_SEC / (end - start);
+        printf("Transfert rate in points/seconds:\n");
+        printf("* %'d points/s\n", rate); 
+        printf("\n");
+
+        bytes = NB_LOOPS * (nb_points / 8) + ((nb_points % 8) ? 1 : 0);
+        rate = bytes / 1024 * G_USEC_PER_SEC / (end - start);
+        printf("Values:\n");
+        printf("* %d x %d values\n", NB_LOOPS, nb_points);
+        printf("* %.3f ms for %d bytes\n", elapsed, bytes);
+        printf("* %'d KiB/s\n", rate);
+        printf("\n");
+        
+        /* TCP: Query and reponse header and values */
+        bytes = 12 + 9 + (nb_points / 8) + ((nb_points % 8) ? 1 : 0);
+        printf("Values and TCP Modbus overhead:\n");
+        printf("* %d x %d bytes\n", NB_LOOPS, bytes);
+        bytes = NB_LOOPS * bytes;
+        rate = bytes / 1024 * G_USEC_PER_SEC / (end - start);
+        printf("* %.3f ms for %d bytes\n", elapsed, bytes);
+        printf("* %'d KiB/s\n", rate);
+        printf("\n\n");
+
+        printf("READ HOLDING REGISTERS\n\n");
+
+        nb_points = MAX_REGISTERS;
+        start = gettime();
+        for (i=0; i<NB_LOOPS; i++) {
+                ret = read_holding_registers(&mb_param, SLAVE, 0, nb_points, tab_rp_registers);
+        }
+        end = gettime();
+        elapsed = (end - start) / 1000;
+
+        rate = (NB_LOOPS * nb_points) * G_USEC_PER_SEC / (end - start);
+        printf("Transfert rate in points/seconds:\n");
+        printf("* %'d registers/s\n", rate); 
+        printf("\n");
+
+        bytes = NB_LOOPS * nb_points * sizeof(uint16_t);
+        rate = bytes / 1024 * G_USEC_PER_SEC / (end - start);
+        printf("Values:\n");
+        printf("* %d x %d values\n", NB_LOOPS, nb_points);
+        printf("* %.3f ms for %d bytes\n", elapsed, bytes);
+        printf("* %'d KiB/s\n", rate);
+        printf("\n");
+        
+        /* TCP:Query and reponse header and values */
+        bytes = 12 + 9 + (nb_points * sizeof(uint16_t));
+        printf("Values and TCP Modbus overhead:\n");
+        printf("* %d x %d bytes\n", NB_LOOPS, bytes);
+        bytes = NB_LOOPS * bytes;
+        rate = bytes / 1024 * G_USEC_PER_SEC / (end - start);
+        printf("* %.3f ms for %d bytes\n", elapsed, bytes);
+        printf("* %'d KiB/s\n", rate);
+        printf("\n");
+
+        /* Free the memory */
+        free(tab_rp_status);                                           
+        free(tab_rp_registers);
+
+        /* Close the connection */
+        modbus_close(&mb_param);
+        
+        return 0;
+}

+ 63 - 0
tests/bench-bandwidth-slave.c

@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2008 Stéphane Raimbault <stephane.raimbault@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <modbus/modbus.h>
+
+int main(void)
+{
+        int socket;
+        modbus_param_t mb_param;
+        modbus_mapping_t mb_mapping;
+        int ret;
+
+        modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
+
+        ret = modbus_mapping_new(&mb_mapping,  MAX_STATUS, 0, MAX_REGISTERS, 0);
+        if (ret == FALSE) {
+                printf("Memory allocation failed\n");
+                exit(1);
+        }
+
+        socket = modbus_init_listen_tcp(&mb_param);
+        
+        while (1) {
+                uint8_t query[MAX_MESSAGE_LENGTH];
+                int query_size;
+                
+                ret = modbus_listen(&mb_param, query, &query_size);
+                if (ret == 0) {
+                        manage_query(&mb_param, query, query_size, &mb_mapping);
+                } else if (ret == CONNECTION_CLOSED) {
+                        /* Connection closed by the client, end of server */
+                        break;
+                } else {
+                        printf("Error in modbus_listen (%d)\n", ret);
+                }
+        }
+
+        close(socket);
+        modbus_mapping_free(&mb_mapping);
+        modbus_close(&mb_param);
+        
+        return 0;
+}
+        

+ 14 - 0
tests/wscript

@@ -19,3 +19,17 @@ def build(bld):
     obj.uselib_local = 'modbus'
     obj.target = 'test-master-random'
     obj.inst_var = 0
+
+    obj = bld.create_obj('cc', 'program')
+    obj.source = 'bench-bandwidth-slave.c'
+    obj.includes = '. ..'
+    obj.uselib_local = 'modbus'
+    obj.target = 'bench-bandwidth-slave'
+    obj.inst_var = 0
+
+    obj = bld.create_obj('cc', 'program')
+    obj.source = 'bench-bandwidth-master.c'
+    obj.includes = '. ..'
+    obj.uselib_local = 'modbus'
+    obj.target = 'bench-bandwidth-master'
+    obj.inst_var = 0