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

Enhanced report slave ID and documentation

Stéphane Raimbault 13 жил өмнө
parent
commit
ad80a6d3cc

+ 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
   before the read. Take care to swap the arguments in the migration process.
 - 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)
 ============================

+ 1 - 0
doc/Makefile.am

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

+ 3 - 2
doc/libmodbus.txt

@@ -139,14 +139,15 @@ Flush a connection::
 Client
 ~~~~~~
 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::
      linkmb:modbus_read_bits[3]
      linkmb:modbus_read_input_bits[3]
      linkmb:modbus_read_registers[3]
      linkmb:modbus_read_input_registers[3]
+     libkmb:modbus_report_slave_id[3]
 
 Write data::
      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_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) */
 #define _RESPONSE_TIMEOUT    500000

+ 14 - 5
src/modbus.c

@@ -842,13 +842,22 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
         }
     }
         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);
-        /* 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;
+        /* 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;
     case _FC_READ_EXCEPTION_STATUS:
         if (ctx->debug) {

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

@@ -562,14 +562,31 @@ int main(int argc, char *argv[])
         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 {
         printf("FAILED\n");
         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 */
     modbus_get_response_timeout(ctx, &old_response_timeout);