Bläddra i källkod

Enhanced report slave ID and documentation

Stéphane Raimbault 14 år sedan
förälder
incheckning
ad80a6d3cc
7 ändrade filer med 98 tillägg och 13 borttagningar
  1. 2 0
      NEWS
  2. 1 0
      doc/Makefile.am
  3. 3 2
      doc/libmodbus.txt
  4. 55 0
      doc/modbus_report_slave_id.txt
  5. 3 3
      src/modbus-private.h
  6. 14 5
      src/modbus.c
  7. 20 3
      tests/unit-test-client.c

+ 2 - 0
NEWS

@@ -11,6 +11,8 @@ libmodbus 2.9.5 (2011-06-XX)
   The function name was confusing because the write operation is performed
   The function name was confusing because the write operation is performed
   before the read. Take care to swap the arguments in the migration process.
   before the read. Take care to swap the arguments in the migration process.
 - Documentation of modbus_write_and_read_registers, modbus_mapping_new/free
 - Documentation of modbus_write_and_read_registers, modbus_mapping_new/free
+  and report_slave_id.
+- Enhanced report slave ID
 
 
 libmodbus 2.9.4 (2011-06-05)
 libmodbus 2.9.4 (2011-06-05)
 ============================
 ============================

+ 1 - 0
doc/Makefile.am

@@ -18,6 +18,7 @@ MAN3 = \
         modbus_read_registers.3 \
         modbus_read_registers.3 \
         modbus_receive.3 \
         modbus_receive.3 \
         modbus_receive_confirmation.3 \
         modbus_receive_confirmation.3 \
+        modbus_report_slave_id.3 \
         modbus_rtu_get_serial_mode.3 \
         modbus_rtu_get_serial_mode.3 \
         modbus_rtu_set_serial_mode.3 \
         modbus_rtu_set_serial_mode.3 \
         modbus_send_raw_request.3 \
         modbus_send_raw_request.3 \

+ 3 - 2
doc/libmodbus.txt

@@ -139,14 +139,15 @@ Flush a connection::
 Client
 Client
 ~~~~~~
 ~~~~~~
 The Modbus protocol defines different data types and functions to read and write
 The Modbus protocol defines different data types and functions to read and write
-them from/to remote devices. The following functions are used by the clients to send
-Modbus requests:
+them from/to remote devices. The following functions are used by the clients to
+send Modbus requests:
 
 
 Read data::
 Read data::
      linkmb:modbus_read_bits[3]
      linkmb:modbus_read_bits[3]
      linkmb:modbus_read_input_bits[3]
      linkmb:modbus_read_input_bits[3]
      linkmb:modbus_read_registers[3]
      linkmb:modbus_read_registers[3]
      linkmb:modbus_read_input_registers[3]
      linkmb:modbus_read_input_registers[3]
+     libkmb:modbus_report_slave_id[3]
 
 
 Write data::
 Write data::
      linkmb:modbus_write_bit[3]
      linkmb:modbus_write_bit[3]

+ 55 - 0
doc/modbus_report_slave_id.txt

@@ -0,0 +1,55 @@
+modbus_report_slave_id(3)
+=========================
+
+
+NAME
+----
+modbus_report_slave_id - returns a description of the controller
+
+
+SYNOPSIS
+--------
+*int modbus_report_slave_id(modbus_t *'ctx', uint8_t *'dest')*
+
+
+DESCRIPTION
+-----------
+The _modbus_report_slave_id()_ function shall send a request to the controller
+to obtain a description of the controller.
+
+The response stored in 'dest' contains:
+
+* the byte count of the response
+* the slave ID, this unique ID is in reality not unique at all so it's not
+  possible to depend on it to know how the information are packed in the
+  response.
+* the run indicator status (0x00 = OFF, 0xFF = ON)
+* additional data specific to each controller. For example, libmodbus returns
+  the version of the library as a string.
+
+
+RETURN VALUE
+------------
+The _modbus_report_slave_id()_ function shall return the number of read data if
+successful. Otherwise it shall return -1 and set errno.
+
+
+EXAMPLE
+-------
+[source,c]
+-------------------
+uint8_t *tab_bytes;
+
+...
+
+rc = modbus_report_slave_id(ctx, tab_bytes);
+if (rc > 1) {
+    printf("Run Status Indicator: %s\n", tab_bytes[1] ? "ON" : "OFF");
+}
+-------------------
+
+
+AUTHORS
+-------
+The libmodbus documentation was written by Stéphane Raimbault
+<stephane.raimbault@gmail.com>

+ 3 - 3
src/modbus-private.h

@@ -40,11 +40,11 @@ MODBUS_BEGIN_DECLS
  * - HEADER_LENGTH_TCP (7) + function (1) + address (2) + number (2)
  * - HEADER_LENGTH_TCP (7) + function (1) + address (2) + number (2)
  * - HEADER_LENGTH_RTU (1) + function (1) + address (2) + number (2) + CRC (2)
  * - HEADER_LENGTH_RTU (1) + function (1) + address (2) + number (2) + CRC (2)
  */
  */
-#define _MIN_REQ_LENGTH           12
+#define _MIN_REQ_LENGTH 12
 
 
-#define _REPORT_SLAVE_ID_LENGTH   75
+#define _REPORT_SLAVE_ID 180
 
 
-#define _MODBUS_EXCEPTION_RSP_LENGTH  5
+#define _MODBUS_EXCEPTION_RSP_LENGTH 5
 
 
 /* Timeouts in microsecond (0.5 s) */
 /* Timeouts in microsecond (0.5 s) */
 #define _RESPONSE_TIMEOUT    500000
 #define _RESPONSE_TIMEOUT    500000

+ 14 - 5
src/modbus.c

@@ -842,13 +842,22 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
         }
         }
     }
     }
         break;
         break;
-    case _FC_REPORT_SLAVE_ID:
+    case _FC_REPORT_SLAVE_ID: {
+        int str_len;
+        int byte_count_pos;
+
         rsp_length = ctx->backend->build_response_basis(&sft, rsp);
         rsp_length = ctx->backend->build_response_basis(&sft, rsp);
-        /* 2 bytes */
-        rsp[rsp_length++] = 2;
-        rsp[rsp_length++] = ctx->slave;
-        /* Slave is ON */
+        /* Skip byte count for now */
+        byte_count_pos = rsp_length++;
+        rsp[rsp_length++] = _REPORT_SLAVE_ID;
+        /* Run indicator status to ON */
         rsp[rsp_length++] = 0xFF;
         rsp[rsp_length++] = 0xFF;
+        /* LMB + length of LIBMODBUS_VERSION_STRING */
+        str_len = 3 + strlen(LIBMODBUS_VERSION_STRING);
+        memcpy(rsp + rsp_length, "LMB" LIBMODBUS_VERSION_STRING, str_len);
+        rsp_length += str_len;
+        rsp[byte_count_pos] = rsp_length - byte_count_pos - 1;
+    }
         break;
         break;
     case _FC_READ_EXCEPTION_STATUS:
     case _FC_READ_EXCEPTION_STATUS:
         if (ctx->debug) {
         if (ctx->debug) {

+ 20 - 3
tests/unit-test-client.c

@@ -562,14 +562,31 @@ int main(int argc, char *argv[])
         goto close;
         goto close;
     }
     }
 
 
-    if (((use_backend == RTU) && (tab_rp_bits[0] == SERVER_ID))
-        || tab_rp_bits[0] == 0xFF) {
-        printf("OK\n");
+    /* Slave ID is an arbitraty number for libmodbus */
+    if (rc > 0) {
+        printf("OK Slave ID is %d\n", tab_rp_bits[0]);
     } else {
     } else {
         printf("FAILED\n");
         printf("FAILED\n");
         goto close;
         goto close;
     }
     }
 
 
+    /* Run status indicator */
+    if (rc > 1 && tab_rp_bits[1] == 0xFF) {
+        printf("OK Run Status Indicator is %s\n", tab_rp_bits[1] ? "ON" : "OFF");
+    } else {
+        printf("FAILED\n");
+        goto close;
+    }
+
+    /* Print additional data as string */
+    if (rc > 2) {
+        printf("Additional data: ");
+        for (i=2; i < rc; i++) {
+            printf("%c", tab_rp_bits[i]);
+        }
+        printf("\n");
+    }
+
     /* Save original timeout */
     /* Save original timeout */
     modbus_get_response_timeout(ctx, &old_response_timeout);
     modbus_get_response_timeout(ctx, &old_response_timeout);