Commit ad80a6d3cc2c38989cab0e04e9a2a667f54fc99c
1 parent
78587bdf
Enhanced report slave ID and documentation
Showing
7 changed files
with
98 additions
and
13 deletions
NEWS
| ... | ... | @@ -11,6 +11,8 @@ libmodbus 2.9.5 (2011-06-XX) |
| 11 | 11 | The function name was confusing because the write operation is performed |
| 12 | 12 | before the read. Take care to swap the arguments in the migration process. |
| 13 | 13 | - Documentation of modbus_write_and_read_registers, modbus_mapping_new/free |
| 14 | + and report_slave_id. | |
| 15 | +- Enhanced report slave ID | |
| 14 | 16 | |
| 15 | 17 | libmodbus 2.9.4 (2011-06-05) |
| 16 | 18 | ============================ | ... | ... |
doc/Makefile.am
doc/libmodbus.txt
| ... | ... | @@ -139,14 +139,15 @@ Flush a connection:: |
| 139 | 139 | Client |
| 140 | 140 | ~~~~~~ |
| 141 | 141 | The Modbus protocol defines different data types and functions to read and write |
| 142 | -them from/to remote devices. The following functions are used by the clients to send | |
| 143 | -Modbus requests: | |
| 142 | +them from/to remote devices. The following functions are used by the clients to | |
| 143 | +send Modbus requests: | |
| 144 | 144 | |
| 145 | 145 | Read data:: |
| 146 | 146 | linkmb:modbus_read_bits[3] |
| 147 | 147 | linkmb:modbus_read_input_bits[3] |
| 148 | 148 | linkmb:modbus_read_registers[3] |
| 149 | 149 | linkmb:modbus_read_input_registers[3] |
| 150 | + libkmb:modbus_report_slave_id[3] | |
| 150 | 151 | |
| 151 | 152 | Write data:: |
| 152 | 153 | linkmb:modbus_write_bit[3] | ... | ... |
doc/modbus_report_slave_id.txt
0 → 100644
| 1 | +modbus_report_slave_id(3) | |
| 2 | +========================= | |
| 3 | + | |
| 4 | + | |
| 5 | +NAME | |
| 6 | +---- | |
| 7 | +modbus_report_slave_id - returns a description of the controller | |
| 8 | + | |
| 9 | + | |
| 10 | +SYNOPSIS | |
| 11 | +-------- | |
| 12 | +*int modbus_report_slave_id(modbus_t *'ctx', uint8_t *'dest')* | |
| 13 | + | |
| 14 | + | |
| 15 | +DESCRIPTION | |
| 16 | +----------- | |
| 17 | +The _modbus_report_slave_id()_ function shall send a request to the controller | |
| 18 | +to obtain a description of the controller. | |
| 19 | + | |
| 20 | +The response stored in 'dest' contains: | |
| 21 | + | |
| 22 | +* the byte count of the response | |
| 23 | +* the slave ID, this unique ID is in reality not unique at all so it's not | |
| 24 | + possible to depend on it to know how the information are packed in the | |
| 25 | + response. | |
| 26 | +* the run indicator status (0x00 = OFF, 0xFF = ON) | |
| 27 | +* additional data specific to each controller. For example, libmodbus returns | |
| 28 | + the version of the library as a string. | |
| 29 | + | |
| 30 | + | |
| 31 | +RETURN VALUE | |
| 32 | +------------ | |
| 33 | +The _modbus_report_slave_id()_ function shall return the number of read data if | |
| 34 | +successful. Otherwise it shall return -1 and set errno. | |
| 35 | + | |
| 36 | + | |
| 37 | +EXAMPLE | |
| 38 | +------- | |
| 39 | +[source,c] | |
| 40 | +------------------- | |
| 41 | +uint8_t *tab_bytes; | |
| 42 | + | |
| 43 | +... | |
| 44 | + | |
| 45 | +rc = modbus_report_slave_id(ctx, tab_bytes); | |
| 46 | +if (rc > 1) { | |
| 47 | + printf("Run Status Indicator: %s\n", tab_bytes[1] ? "ON" : "OFF"); | |
| 48 | +} | |
| 49 | +------------------- | |
| 50 | + | |
| 51 | + | |
| 52 | +AUTHORS | |
| 53 | +------- | |
| 54 | +The libmodbus documentation was written by Stéphane Raimbault | |
| 55 | +<stephane.raimbault@gmail.com> | ... | ... |
src/modbus-private.h
| ... | ... | @@ -40,11 +40,11 @@ MODBUS_BEGIN_DECLS |
| 40 | 40 | * - HEADER_LENGTH_TCP (7) + function (1) + address (2) + number (2) |
| 41 | 41 | * - HEADER_LENGTH_RTU (1) + function (1) + address (2) + number (2) + CRC (2) |
| 42 | 42 | */ |
| 43 | -#define _MIN_REQ_LENGTH 12 | |
| 43 | +#define _MIN_REQ_LENGTH 12 | |
| 44 | 44 | |
| 45 | -#define _REPORT_SLAVE_ID_LENGTH 75 | |
| 45 | +#define _REPORT_SLAVE_ID 180 | |
| 46 | 46 | |
| 47 | -#define _MODBUS_EXCEPTION_RSP_LENGTH 5 | |
| 47 | +#define _MODBUS_EXCEPTION_RSP_LENGTH 5 | |
| 48 | 48 | |
| 49 | 49 | /* Timeouts in microsecond (0.5 s) */ |
| 50 | 50 | #define _RESPONSE_TIMEOUT 500000 | ... | ... |
src/modbus.c
| ... | ... | @@ -842,13 +842,22 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, |
| 842 | 842 | } |
| 843 | 843 | } |
| 844 | 844 | break; |
| 845 | - case _FC_REPORT_SLAVE_ID: | |
| 845 | + case _FC_REPORT_SLAVE_ID: { | |
| 846 | + int str_len; | |
| 847 | + int byte_count_pos; | |
| 848 | + | |
| 846 | 849 | rsp_length = ctx->backend->build_response_basis(&sft, rsp); |
| 847 | - /* 2 bytes */ | |
| 848 | - rsp[rsp_length++] = 2; | |
| 849 | - rsp[rsp_length++] = ctx->slave; | |
| 850 | - /* Slave is ON */ | |
| 850 | + /* Skip byte count for now */ | |
| 851 | + byte_count_pos = rsp_length++; | |
| 852 | + rsp[rsp_length++] = _REPORT_SLAVE_ID; | |
| 853 | + /* Run indicator status to ON */ | |
| 851 | 854 | rsp[rsp_length++] = 0xFF; |
| 855 | + /* LMB + length of LIBMODBUS_VERSION_STRING */ | |
| 856 | + str_len = 3 + strlen(LIBMODBUS_VERSION_STRING); | |
| 857 | + memcpy(rsp + rsp_length, "LMB" LIBMODBUS_VERSION_STRING, str_len); | |
| 858 | + rsp_length += str_len; | |
| 859 | + rsp[byte_count_pos] = rsp_length - byte_count_pos - 1; | |
| 860 | + } | |
| 852 | 861 | break; |
| 853 | 862 | case _FC_READ_EXCEPTION_STATUS: |
| 854 | 863 | if (ctx->debug) { | ... | ... |
tests/unit-test-client.c
| ... | ... | @@ -562,14 +562,31 @@ int main(int argc, char *argv[]) |
| 562 | 562 | goto close; |
| 563 | 563 | } |
| 564 | 564 | |
| 565 | - if (((use_backend == RTU) && (tab_rp_bits[0] == SERVER_ID)) | |
| 566 | - || tab_rp_bits[0] == 0xFF) { | |
| 567 | - printf("OK\n"); | |
| 565 | + /* Slave ID is an arbitraty number for libmodbus */ | |
| 566 | + if (rc > 0) { | |
| 567 | + printf("OK Slave ID is %d\n", tab_rp_bits[0]); | |
| 568 | 568 | } else { |
| 569 | 569 | printf("FAILED\n"); |
| 570 | 570 | goto close; |
| 571 | 571 | } |
| 572 | 572 | |
| 573 | + /* Run status indicator */ | |
| 574 | + if (rc > 1 && tab_rp_bits[1] == 0xFF) { | |
| 575 | + printf("OK Run Status Indicator is %s\n", tab_rp_bits[1] ? "ON" : "OFF"); | |
| 576 | + } else { | |
| 577 | + printf("FAILED\n"); | |
| 578 | + goto close; | |
| 579 | + } | |
| 580 | + | |
| 581 | + /* Print additional data as string */ | |
| 582 | + if (rc > 2) { | |
| 583 | + printf("Additional data: "); | |
| 584 | + for (i=2; i < rc; i++) { | |
| 585 | + printf("%c", tab_rp_bits[i]); | |
| 586 | + } | |
| 587 | + printf("\n"); | |
| 588 | + } | |
| 589 | + | |
| 573 | 590 | /* Save original timeout */ |
| 574 | 591 | modbus_get_response_timeout(ctx, &old_response_timeout); |
| 575 | 592 | ... | ... |