Commit 8941a84ceeca75e25e393986f5b6633daaef6057
1 parent
349b6ded
Export Modbus function codes supported by libmodbus
Showing
5 changed files
with
91 additions
and
78 deletions
doc/modbus_send_raw_request.txt
| @@ -21,6 +21,10 @@ message, the header or CRC of the selected backend, so 'raw_req' must start and | @@ -21,6 +21,10 @@ message, the header or CRC of the selected backend, so 'raw_req' must start and | ||
| 21 | contain at least a slave/unit identifier and a function code. This function can | 21 | contain at least a slave/unit identifier and a function code. This function can |
| 22 | be used to send request not handled by the library. | 22 | be used to send request not handled by the library. |
| 23 | 23 | ||
| 24 | +The public header of libmodbus provides a list of supported Modbus functions | ||
| 25 | +codes, prefixed by `MODBUS_FC_` (eg. MODBUS_FC_READ_HOLDING_REGISTERS), to help | ||
| 26 | +build of raw requests. | ||
| 27 | + | ||
| 24 | 28 | ||
| 25 | RETURN VALUE | 29 | RETURN VALUE |
| 26 | ------------ | 30 | ------------ |
| @@ -35,7 +39,7 @@ EXAMPLE | @@ -35,7 +39,7 @@ EXAMPLE | ||
| 35 | ------------------- | 39 | ------------------- |
| 36 | modbus_t *ctx; | 40 | modbus_t *ctx; |
| 37 | /* Read 5 holding registers from address 1 */ | 41 | /* Read 5 holding registers from address 1 */ |
| 38 | -uint8_t raw_req[] = { 0xFF, 0x03, 0x00, 0x01, 0x0, 0x05 }; | 42 | +uint8_t raw_req[] = { 0xFF, MODBUS_FC_READ_HOLDING_REGISTERS, 0x00, 0x01, 0x0, 0x05 }; |
| 39 | int req_length; | 43 | int req_length; |
| 40 | uint8_t rsp[MODBUS_TCP_MAX_ADU_LENGTH]; | 44 | uint8_t rsp[MODBUS_TCP_MAX_ADU_LENGTH]; |
| 41 | 45 |
src/modbus-private.h
| @@ -51,20 +51,6 @@ MODBUS_BEGIN_DECLS | @@ -51,20 +51,6 @@ MODBUS_BEGIN_DECLS | ||
| 51 | #define _RESPONSE_TIMEOUT 500000 | 51 | #define _RESPONSE_TIMEOUT 500000 |
| 52 | #define _BYTE_TIMEOUT 500000 | 52 | #define _BYTE_TIMEOUT 500000 |
| 53 | 53 | ||
| 54 | -/* Function codes */ | ||
| 55 | -#define _FC_READ_COILS 0x01 | ||
| 56 | -#define _FC_READ_DISCRETE_INPUTS 0x02 | ||
| 57 | -#define _FC_READ_HOLDING_REGISTERS 0x03 | ||
| 58 | -#define _FC_READ_INPUT_REGISTERS 0x04 | ||
| 59 | -#define _FC_WRITE_SINGLE_COIL 0x05 | ||
| 60 | -#define _FC_WRITE_SINGLE_REGISTER 0x06 | ||
| 61 | -#define _FC_READ_EXCEPTION_STATUS 0x07 | ||
| 62 | -#define _FC_WRITE_MULTIPLE_COILS 0x0F | ||
| 63 | -#define _FC_WRITE_MULTIPLE_REGISTERS 0x10 | ||
| 64 | -#define _FC_REPORT_SLAVE_ID 0x11 | ||
| 65 | -#define _FC_MASK_WRITE_REGISTER 0x16 | ||
| 66 | -#define _FC_WRITE_AND_READ_REGISTERS 0x17 | ||
| 67 | - | ||
| 68 | typedef enum { | 54 | typedef enum { |
| 69 | _MODBUS_BACKEND_TYPE_RTU=0, | 55 | _MODBUS_BACKEND_TYPE_RTU=0, |
| 70 | _MODBUS_BACKEND_TYPE_TCP | 56 | _MODBUS_BACKEND_TYPE_TCP |
src/modbus.c
| @@ -141,27 +141,27 @@ static unsigned int compute_response_length_from_request(modbus_t *ctx, uint8_t | @@ -141,27 +141,27 @@ static unsigned int compute_response_length_from_request(modbus_t *ctx, uint8_t | ||
| 141 | const int offset = ctx->backend->header_length; | 141 | const int offset = ctx->backend->header_length; |
| 142 | 142 | ||
| 143 | switch (req[offset]) { | 143 | switch (req[offset]) { |
| 144 | - case _FC_READ_COILS: | ||
| 145 | - case _FC_READ_DISCRETE_INPUTS: { | 144 | + case MODBUS_FC_READ_COILS: |
| 145 | + case MODBUS_FC_READ_DISCRETE_INPUTS: { | ||
| 146 | /* Header + nb values (code from write_bits) */ | 146 | /* Header + nb values (code from write_bits) */ |
| 147 | int nb = (req[offset + 3] << 8) | req[offset + 4]; | 147 | int nb = (req[offset + 3] << 8) | req[offset + 4]; |
| 148 | length = 2 + (nb / 8) + ((nb % 8) ? 1 : 0); | 148 | length = 2 + (nb / 8) + ((nb % 8) ? 1 : 0); |
| 149 | } | 149 | } |
| 150 | break; | 150 | break; |
| 151 | - case _FC_WRITE_AND_READ_REGISTERS: | ||
| 152 | - case _FC_READ_HOLDING_REGISTERS: | ||
| 153 | - case _FC_READ_INPUT_REGISTERS: | 151 | + case MODBUS_FC_WRITE_AND_READ_REGISTERS: |
| 152 | + case MODBUS_FC_READ_HOLDING_REGISTERS: | ||
| 153 | + case MODBUS_FC_READ_INPUT_REGISTERS: | ||
| 154 | /* Header + 2 * nb values */ | 154 | /* Header + 2 * nb values */ |
| 155 | length = 2 + 2 * (req[offset + 3] << 8 | req[offset + 4]); | 155 | length = 2 + 2 * (req[offset + 3] << 8 | req[offset + 4]); |
| 156 | break; | 156 | break; |
| 157 | - case _FC_READ_EXCEPTION_STATUS: | 157 | + case MODBUS_FC_READ_EXCEPTION_STATUS: |
| 158 | length = 3; | 158 | length = 3; |
| 159 | break; | 159 | break; |
| 160 | - case _FC_REPORT_SLAVE_ID: | 160 | + case MODBUS_FC_REPORT_SLAVE_ID: |
| 161 | /* The response is device specific (the header provides the | 161 | /* The response is device specific (the header provides the |
| 162 | length) */ | 162 | length) */ |
| 163 | return MSG_LENGTH_UNDEFINED; | 163 | return MSG_LENGTH_UNDEFINED; |
| 164 | - case _FC_MASK_WRITE_REGISTER: | 164 | + case MODBUS_FC_MASK_WRITE_REGISTER: |
| 165 | length = 7; | 165 | length = 7; |
| 166 | break; | 166 | break; |
| 167 | default: | 167 | default: |
| @@ -262,29 +262,29 @@ static uint8_t compute_meta_length_after_function(int function, | @@ -262,29 +262,29 @@ static uint8_t compute_meta_length_after_function(int function, | ||
| 262 | int length; | 262 | int length; |
| 263 | 263 | ||
| 264 | if (msg_type == MSG_INDICATION) { | 264 | if (msg_type == MSG_INDICATION) { |
| 265 | - if (function <= _FC_WRITE_SINGLE_REGISTER) { | 265 | + if (function <= MODBUS_FC_WRITE_SINGLE_REGISTER) { |
| 266 | length = 4; | 266 | length = 4; |
| 267 | - } else if (function == _FC_WRITE_MULTIPLE_COILS || | ||
| 268 | - function == _FC_WRITE_MULTIPLE_REGISTERS) { | 267 | + } else if (function == MODBUS_FC_WRITE_MULTIPLE_COILS || |
| 268 | + function == MODBUS_FC_WRITE_MULTIPLE_REGISTERS) { | ||
| 269 | length = 5; | 269 | length = 5; |
| 270 | - } else if (function == _FC_MASK_WRITE_REGISTER) { | 270 | + } else if (function == MODBUS_FC_MASK_WRITE_REGISTER) { |
| 271 | length = 6; | 271 | length = 6; |
| 272 | - } else if (function == _FC_WRITE_AND_READ_REGISTERS) { | 272 | + } else if (function == MODBUS_FC_WRITE_AND_READ_REGISTERS) { |
| 273 | length = 9; | 273 | length = 9; |
| 274 | } else { | 274 | } else { |
| 275 | - /* _FC_READ_EXCEPTION_STATUS, _FC_REPORT_SLAVE_ID */ | 275 | + /* MODBUS_FC_READ_EXCEPTION_STATUS, MODBUS_FC_REPORT_SLAVE_ID */ |
| 276 | length = 0; | 276 | length = 0; |
| 277 | } | 277 | } |
| 278 | } else { | 278 | } else { |
| 279 | /* MSG_CONFIRMATION */ | 279 | /* MSG_CONFIRMATION */ |
| 280 | switch (function) { | 280 | switch (function) { |
| 281 | - case _FC_WRITE_SINGLE_COIL: | ||
| 282 | - case _FC_WRITE_SINGLE_REGISTER: | ||
| 283 | - case _FC_WRITE_MULTIPLE_COILS: | ||
| 284 | - case _FC_WRITE_MULTIPLE_REGISTERS: | 281 | + case MODBUS_FC_WRITE_SINGLE_COIL: |
| 282 | + case MODBUS_FC_WRITE_SINGLE_REGISTER: | ||
| 283 | + case MODBUS_FC_WRITE_MULTIPLE_COILS: | ||
| 284 | + case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: | ||
| 285 | length = 4; | 285 | length = 4; |
| 286 | break; | 286 | break; |
| 287 | - case _FC_MASK_WRITE_REGISTER: | 287 | + case MODBUS_FC_MASK_WRITE_REGISTER: |
| 288 | length = 6; | 288 | length = 6; |
| 289 | break; | 289 | break; |
| 290 | default: | 290 | default: |
| @@ -304,11 +304,11 @@ static int compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg, | @@ -304,11 +304,11 @@ static int compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg, | ||
| 304 | 304 | ||
| 305 | if (msg_type == MSG_INDICATION) { | 305 | if (msg_type == MSG_INDICATION) { |
| 306 | switch (function) { | 306 | switch (function) { |
| 307 | - case _FC_WRITE_MULTIPLE_COILS: | ||
| 308 | - case _FC_WRITE_MULTIPLE_REGISTERS: | 307 | + case MODBUS_FC_WRITE_MULTIPLE_COILS: |
| 308 | + case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: | ||
| 309 | length = msg[ctx->backend->header_length + 5]; | 309 | length = msg[ctx->backend->header_length + 5]; |
| 310 | break; | 310 | break; |
| 311 | - case _FC_WRITE_AND_READ_REGISTERS: | 311 | + case MODBUS_FC_WRITE_AND_READ_REGISTERS: |
| 312 | length = msg[ctx->backend->header_length + 9]; | 312 | length = msg[ctx->backend->header_length + 9]; |
| 313 | break; | 313 | break; |
| 314 | default: | 314 | default: |
| @@ -316,9 +316,9 @@ static int compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg, | @@ -316,9 +316,9 @@ static int compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg, | ||
| 316 | } | 316 | } |
| 317 | } else { | 317 | } else { |
| 318 | /* MSG_CONFIRMATION */ | 318 | /* MSG_CONFIRMATION */ |
| 319 | - if (function <= _FC_READ_INPUT_REGISTERS || | ||
| 320 | - function == _FC_REPORT_SLAVE_ID || | ||
| 321 | - function == _FC_WRITE_AND_READ_REGISTERS) { | 319 | + if (function <= MODBUS_FC_READ_INPUT_REGISTERS || |
| 320 | + function == MODBUS_FC_REPORT_SLAVE_ID || | ||
| 321 | + function == MODBUS_FC_WRITE_AND_READ_REGISTERS) { | ||
| 322 | length = msg[ctx->backend->header_length + 1]; | 322 | length = msg[ctx->backend->header_length + 1]; |
| 323 | } else { | 323 | } else { |
| 324 | length = 0; | 324 | length = 0; |
| @@ -570,8 +570,8 @@ static int check_confirmation(modbus_t *ctx, uint8_t *req, | @@ -570,8 +570,8 @@ static int check_confirmation(modbus_t *ctx, uint8_t *req, | ||
| 570 | 570 | ||
| 571 | /* Check the number of values is corresponding to the request */ | 571 | /* Check the number of values is corresponding to the request */ |
| 572 | switch (function) { | 572 | switch (function) { |
| 573 | - case _FC_READ_COILS: | ||
| 574 | - case _FC_READ_DISCRETE_INPUTS: | 573 | + case MODBUS_FC_READ_COILS: |
| 574 | + case MODBUS_FC_READ_DISCRETE_INPUTS: | ||
| 575 | /* Read functions, 8 values in a byte (nb | 575 | /* Read functions, 8 values in a byte (nb |
| 576 | * of values in the request and byte count in | 576 | * of values in the request and byte count in |
| 577 | * the response. */ | 577 | * the response. */ |
| @@ -579,20 +579,20 @@ static int check_confirmation(modbus_t *ctx, uint8_t *req, | @@ -579,20 +579,20 @@ static int check_confirmation(modbus_t *ctx, uint8_t *req, | ||
| 579 | req_nb_value = (req_nb_value / 8) + ((req_nb_value % 8) ? 1 : 0); | 579 | req_nb_value = (req_nb_value / 8) + ((req_nb_value % 8) ? 1 : 0); |
| 580 | rsp_nb_value = rsp[offset + 1]; | 580 | rsp_nb_value = rsp[offset + 1]; |
| 581 | break; | 581 | break; |
| 582 | - case _FC_WRITE_AND_READ_REGISTERS: | ||
| 583 | - case _FC_READ_HOLDING_REGISTERS: | ||
| 584 | - case _FC_READ_INPUT_REGISTERS: | 582 | + case MODBUS_FC_WRITE_AND_READ_REGISTERS: |
| 583 | + case MODBUS_FC_READ_HOLDING_REGISTERS: | ||
| 584 | + case MODBUS_FC_READ_INPUT_REGISTERS: | ||
| 585 | /* Read functions 1 value = 2 bytes */ | 585 | /* Read functions 1 value = 2 bytes */ |
| 586 | req_nb_value = (req[offset + 3] << 8) + req[offset + 4]; | 586 | req_nb_value = (req[offset + 3] << 8) + req[offset + 4]; |
| 587 | rsp_nb_value = (rsp[offset + 1] / 2); | 587 | rsp_nb_value = (rsp[offset + 1] / 2); |
| 588 | break; | 588 | break; |
| 589 | - case _FC_WRITE_MULTIPLE_COILS: | ||
| 590 | - case _FC_WRITE_MULTIPLE_REGISTERS: | 589 | + case MODBUS_FC_WRITE_MULTIPLE_COILS: |
| 590 | + case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: | ||
| 591 | /* N Write functions */ | 591 | /* N Write functions */ |
| 592 | req_nb_value = (req[offset + 3] << 8) + req[offset + 4]; | 592 | req_nb_value = (req[offset + 3] << 8) + req[offset + 4]; |
| 593 | rsp_nb_value = (rsp[offset + 3] << 8) | rsp[offset + 4]; | 593 | rsp_nb_value = (rsp[offset + 3] << 8) | rsp[offset + 4]; |
| 594 | break; | 594 | break; |
| 595 | - case _FC_REPORT_SLAVE_ID: | 595 | + case MODBUS_FC_REPORT_SLAVE_ID: |
| 596 | /* Report slave ID (bytes received) */ | 596 | /* Report slave ID (bytes received) */ |
| 597 | req_nb_value = rsp_nb_value = rsp[offset + 1]; | 597 | req_nb_value = rsp_nb_value = rsp[offset + 1]; |
| 598 | break; | 598 | break; |
| @@ -703,7 +703,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -703,7 +703,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 703 | sft.t_id = ctx->backend->prepare_response_tid(req, &req_length); | 703 | sft.t_id = ctx->backend->prepare_response_tid(req, &req_length); |
| 704 | 704 | ||
| 705 | switch (function) { | 705 | switch (function) { |
| 706 | - case _FC_READ_COILS: { | 706 | + case MODBUS_FC_READ_COILS: { |
| 707 | int nb = (req[offset + 3] << 8) + req[offset + 4]; | 707 | int nb = (req[offset + 3] << 8) + req[offset + 4]; |
| 708 | 708 | ||
| 709 | if (nb < 1 || MODBUS_MAX_READ_BITS < nb) { | 709 | if (nb < 1 || MODBUS_MAX_READ_BITS < nb) { |
| @@ -732,7 +732,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -732,7 +732,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 732 | } | 732 | } |
| 733 | } | 733 | } |
| 734 | break; | 734 | break; |
| 735 | - case _FC_READ_DISCRETE_INPUTS: { | 735 | + case MODBUS_FC_READ_DISCRETE_INPUTS: { |
| 736 | /* Similar to coil status (but too many arguments to use a | 736 | /* Similar to coil status (but too many arguments to use a |
| 737 | * function) */ | 737 | * function) */ |
| 738 | int nb = (req[offset + 3] << 8) + req[offset + 4]; | 738 | int nb = (req[offset + 3] << 8) + req[offset + 4]; |
| @@ -763,7 +763,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -763,7 +763,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 763 | } | 763 | } |
| 764 | } | 764 | } |
| 765 | break; | 765 | break; |
| 766 | - case _FC_READ_HOLDING_REGISTERS: { | 766 | + case MODBUS_FC_READ_HOLDING_REGISTERS: { |
| 767 | int nb = (req[offset + 3] << 8) + req[offset + 4]; | 767 | int nb = (req[offset + 3] << 8) + req[offset + 4]; |
| 768 | 768 | ||
| 769 | if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) { | 769 | if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) { |
| @@ -795,7 +795,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -795,7 +795,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 795 | } | 795 | } |
| 796 | } | 796 | } |
| 797 | break; | 797 | break; |
| 798 | - case _FC_READ_INPUT_REGISTERS: { | 798 | + case MODBUS_FC_READ_INPUT_REGISTERS: { |
| 799 | /* Similar to holding registers (but too many arguments to use a | 799 | /* Similar to holding registers (but too many arguments to use a |
| 800 | * function) */ | 800 | * function) */ |
| 801 | int nb = (req[offset + 3] << 8) + req[offset + 4]; | 801 | int nb = (req[offset + 3] << 8) + req[offset + 4]; |
| @@ -829,7 +829,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -829,7 +829,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 829 | } | 829 | } |
| 830 | } | 830 | } |
| 831 | break; | 831 | break; |
| 832 | - case _FC_WRITE_SINGLE_COIL: | 832 | + case MODBUS_FC_WRITE_SINGLE_COIL: |
| 833 | if (address >= mb_mapping->nb_bits) { | 833 | if (address >= mb_mapping->nb_bits) { |
| 834 | if (ctx->debug) { | 834 | if (ctx->debug) { |
| 835 | fprintf(stderr, | 835 | fprintf(stderr, |
| @@ -858,7 +858,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -858,7 +858,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 858 | } | 858 | } |
| 859 | } | 859 | } |
| 860 | break; | 860 | break; |
| 861 | - case _FC_WRITE_SINGLE_REGISTER: | 861 | + case MODBUS_FC_WRITE_SINGLE_REGISTER: |
| 862 | if (address >= mb_mapping->nb_registers) { | 862 | if (address >= mb_mapping->nb_registers) { |
| 863 | if (ctx->debug) { | 863 | if (ctx->debug) { |
| 864 | fprintf(stderr, "Illegal data address %0X in write_register\n", | 864 | fprintf(stderr, "Illegal data address %0X in write_register\n", |
| @@ -875,7 +875,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -875,7 +875,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 875 | rsp_length = req_length; | 875 | rsp_length = req_length; |
| 876 | } | 876 | } |
| 877 | break; | 877 | break; |
| 878 | - case _FC_WRITE_MULTIPLE_COILS: { | 878 | + case MODBUS_FC_WRITE_MULTIPLE_COILS: { |
| 879 | int nb = (req[offset + 3] << 8) + req[offset + 4]; | 879 | int nb = (req[offset + 3] << 8) + req[offset + 4]; |
| 880 | 880 | ||
| 881 | if ((address + nb) > mb_mapping->nb_bits) { | 881 | if ((address + nb) > mb_mapping->nb_bits) { |
| @@ -897,7 +897,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -897,7 +897,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 897 | } | 897 | } |
| 898 | } | 898 | } |
| 899 | break; | 899 | break; |
| 900 | - case _FC_WRITE_MULTIPLE_REGISTERS: { | 900 | + case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: { |
| 901 | int nb = (req[offset + 3] << 8) + req[offset + 4]; | 901 | int nb = (req[offset + 3] << 8) + req[offset + 4]; |
| 902 | 902 | ||
| 903 | if ((address + nb) > mb_mapping->nb_registers) { | 903 | if ((address + nb) > mb_mapping->nb_registers) { |
| @@ -923,7 +923,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -923,7 +923,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 923 | } | 923 | } |
| 924 | } | 924 | } |
| 925 | break; | 925 | break; |
| 926 | - case _FC_REPORT_SLAVE_ID: { | 926 | + case MODBUS_FC_REPORT_SLAVE_ID: { |
| 927 | int str_len; | 927 | int str_len; |
| 928 | int byte_count_pos; | 928 | int byte_count_pos; |
| 929 | 929 | ||
| @@ -940,14 +940,14 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -940,14 +940,14 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 940 | rsp[byte_count_pos] = rsp_length - byte_count_pos - 1; | 940 | rsp[byte_count_pos] = rsp_length - byte_count_pos - 1; |
| 941 | } | 941 | } |
| 942 | break; | 942 | break; |
| 943 | - case _FC_READ_EXCEPTION_STATUS: | 943 | + case MODBUS_FC_READ_EXCEPTION_STATUS: |
| 944 | if (ctx->debug) { | 944 | if (ctx->debug) { |
| 945 | fprintf(stderr, "FIXME Not implemented\n"); | 945 | fprintf(stderr, "FIXME Not implemented\n"); |
| 946 | } | 946 | } |
| 947 | errno = ENOPROTOOPT; | 947 | errno = ENOPROTOOPT; |
| 948 | return -1; | 948 | return -1; |
| 949 | break; | 949 | break; |
| 950 | - case _FC_MASK_WRITE_REGISTER: | 950 | + case MODBUS_FC_MASK_WRITE_REGISTER: |
| 951 | if (address >= mb_mapping->nb_registers) { | 951 | if (address >= mb_mapping->nb_registers) { |
| 952 | if (ctx->debug) { | 952 | if (ctx->debug) { |
| 953 | fprintf(stderr, "Illegal data address %0X in write_register\n", | 953 | fprintf(stderr, "Illegal data address %0X in write_register\n", |
| @@ -967,7 +967,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -967,7 +967,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 967 | rsp_length = req_length; | 967 | rsp_length = req_length; |
| 968 | } | 968 | } |
| 969 | break; | 969 | break; |
| 970 | - case _FC_WRITE_AND_READ_REGISTERS: { | 970 | + case MODBUS_FC_WRITE_AND_READ_REGISTERS: { |
| 971 | int nb = (req[offset + 3] << 8) + req[offset + 4]; | 971 | int nb = (req[offset + 3] << 8) + req[offset + 4]; |
| 972 | uint16_t address_write = (req[offset + 5] << 8) + req[offset + 6]; | 972 | uint16_t address_write = (req[offset + 5] << 8) + req[offset + 6]; |
| 973 | int nb_write = (req[offset + 7] << 8) + req[offset + 8]; | 973 | int nb_write = (req[offset + 7] << 8) + req[offset + 8]; |
| @@ -1121,7 +1121,7 @@ int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest) | @@ -1121,7 +1121,7 @@ int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest) | ||
| 1121 | return -1; | 1121 | return -1; |
| 1122 | } | 1122 | } |
| 1123 | 1123 | ||
| 1124 | - rc = read_io_status(ctx, _FC_READ_COILS, addr, nb, dest); | 1124 | + rc = read_io_status(ctx, MODBUS_FC_READ_COILS, addr, nb, dest); |
| 1125 | 1125 | ||
| 1126 | if (rc == -1) | 1126 | if (rc == -1) |
| 1127 | return -1; | 1127 | return -1; |
| @@ -1150,7 +1150,7 @@ int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest) | @@ -1150,7 +1150,7 @@ int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest) | ||
| 1150 | return -1; | 1150 | return -1; |
| 1151 | } | 1151 | } |
| 1152 | 1152 | ||
| 1153 | - rc = read_io_status(ctx, _FC_READ_DISCRETE_INPUTS, addr, nb, dest); | 1153 | + rc = read_io_status(ctx, MODBUS_FC_READ_DISCRETE_INPUTS, addr, nb, dest); |
| 1154 | 1154 | ||
| 1155 | if (rc == -1) | 1155 | if (rc == -1) |
| 1156 | return -1; | 1156 | return -1; |
| @@ -1225,7 +1225,7 @@ int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest) | @@ -1225,7 +1225,7 @@ int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest) | ||
| 1225 | return -1; | 1225 | return -1; |
| 1226 | } | 1226 | } |
| 1227 | 1227 | ||
| 1228 | - status = read_registers(ctx, _FC_READ_HOLDING_REGISTERS, | 1228 | + status = read_registers(ctx, MODBUS_FC_READ_HOLDING_REGISTERS, |
| 1229 | addr, nb, dest); | 1229 | addr, nb, dest); |
| 1230 | return status; | 1230 | return status; |
| 1231 | } | 1231 | } |
| @@ -1249,7 +1249,7 @@ int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, | @@ -1249,7 +1249,7 @@ int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, | ||
| 1249 | return -1; | 1249 | return -1; |
| 1250 | } | 1250 | } |
| 1251 | 1251 | ||
| 1252 | - status = read_registers(ctx, _FC_READ_INPUT_REGISTERS, | 1252 | + status = read_registers(ctx, MODBUS_FC_READ_INPUT_REGISTERS, |
| 1253 | addr, nb, dest); | 1253 | addr, nb, dest); |
| 1254 | 1254 | ||
| 1255 | return status; | 1255 | return status; |
| @@ -1293,7 +1293,7 @@ int modbus_write_bit(modbus_t *ctx, int addr, int status) | @@ -1293,7 +1293,7 @@ int modbus_write_bit(modbus_t *ctx, int addr, int status) | ||
| 1293 | return -1; | 1293 | return -1; |
| 1294 | } | 1294 | } |
| 1295 | 1295 | ||
| 1296 | - return write_single(ctx, _FC_WRITE_SINGLE_COIL, addr, | 1296 | + return write_single(ctx, MODBUS_FC_WRITE_SINGLE_COIL, addr, |
| 1297 | status ? 0xFF00 : 0); | 1297 | status ? 0xFF00 : 0); |
| 1298 | } | 1298 | } |
| 1299 | 1299 | ||
| @@ -1305,7 +1305,7 @@ int modbus_write_register(modbus_t *ctx, int addr, int value) | @@ -1305,7 +1305,7 @@ int modbus_write_register(modbus_t *ctx, int addr, int value) | ||
| 1305 | return -1; | 1305 | return -1; |
| 1306 | } | 1306 | } |
| 1307 | 1307 | ||
| 1308 | - return write_single(ctx, _FC_WRITE_SINGLE_REGISTER, addr, value); | 1308 | + return write_single(ctx, MODBUS_FC_WRITE_SINGLE_REGISTER, addr, value); |
| 1309 | } | 1309 | } |
| 1310 | 1310 | ||
| 1311 | /* Write the bits of the array in the remote device */ | 1311 | /* Write the bits of the array in the remote device */ |
| @@ -1334,7 +1334,7 @@ int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src) | @@ -1334,7 +1334,7 @@ int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src) | ||
| 1334 | } | 1334 | } |
| 1335 | 1335 | ||
| 1336 | req_length = ctx->backend->build_request_basis(ctx, | 1336 | req_length = ctx->backend->build_request_basis(ctx, |
| 1337 | - _FC_WRITE_MULTIPLE_COILS, | 1337 | + MODBUS_FC_WRITE_MULTIPLE_COILS, |
| 1338 | addr, nb, req); | 1338 | addr, nb, req); |
| 1339 | byte_count = (nb / 8) + ((nb % 8) ? 1 : 0); | 1339 | byte_count = (nb / 8) + ((nb % 8) ? 1 : 0); |
| 1340 | req[req_length++] = byte_count; | 1340 | req[req_length++] = byte_count; |
| @@ -1396,7 +1396,7 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src) | @@ -1396,7 +1396,7 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src) | ||
| 1396 | } | 1396 | } |
| 1397 | 1397 | ||
| 1398 | req_length = ctx->backend->build_request_basis(ctx, | 1398 | req_length = ctx->backend->build_request_basis(ctx, |
| 1399 | - _FC_WRITE_MULTIPLE_REGISTERS, | 1399 | + MODBUS_FC_WRITE_MULTIPLE_REGISTERS, |
| 1400 | addr, nb, req); | 1400 | addr, nb, req); |
| 1401 | byte_count = nb * 2; | 1401 | byte_count = nb * 2; |
| 1402 | req[req_length++] = byte_count; | 1402 | req[req_length++] = byte_count; |
| @@ -1426,7 +1426,9 @@ int modbus_mask_write_register(modbus_t *ctx, int addr, uint16_t and_mask, uint1 | @@ -1426,7 +1426,9 @@ int modbus_mask_write_register(modbus_t *ctx, int addr, uint16_t and_mask, uint1 | ||
| 1426 | int req_length; | 1426 | int req_length; |
| 1427 | uint8_t req[_MIN_REQ_LENGTH]; | 1427 | uint8_t req[_MIN_REQ_LENGTH]; |
| 1428 | 1428 | ||
| 1429 | - req_length = ctx->backend->build_request_basis(ctx, _FC_MASK_WRITE_REGISTER, addr, 0, req); | 1429 | + req_length = ctx->backend->build_request_basis(ctx, |
| 1430 | + MODBUS_FC_MASK_WRITE_REGISTER, | ||
| 1431 | + addr, 0, req); | ||
| 1430 | 1432 | ||
| 1431 | /* HACKISH, count is not used */ | 1433 | /* HACKISH, count is not used */ |
| 1432 | req_length -=2; | 1434 | req_length -=2; |
| @@ -1454,8 +1456,10 @@ int modbus_mask_write_register(modbus_t *ctx, int addr, uint16_t and_mask, uint1 | @@ -1454,8 +1456,10 @@ int modbus_mask_write_register(modbus_t *ctx, int addr, uint16_t and_mask, uint1 | ||
| 1454 | /* Write multiple registers from src array to remote device and read multiple | 1456 | /* Write multiple registers from src array to remote device and read multiple |
| 1455 | registers from remote device to dest array. */ | 1457 | registers from remote device to dest array. */ |
| 1456 | int modbus_write_and_read_registers(modbus_t *ctx, | 1458 | int modbus_write_and_read_registers(modbus_t *ctx, |
| 1457 | - int write_addr, int write_nb, const uint16_t *src, | ||
| 1458 | - int read_addr, int read_nb, uint16_t *dest) | 1459 | + int write_addr, int write_nb, |
| 1460 | + const uint16_t *src, | ||
| 1461 | + int read_addr, int read_nb, | ||
| 1462 | + uint16_t *dest) | ||
| 1459 | 1463 | ||
| 1460 | { | 1464 | { |
| 1461 | int rc; | 1465 | int rc; |
| @@ -1490,7 +1494,7 @@ int modbus_write_and_read_registers(modbus_t *ctx, | @@ -1490,7 +1494,7 @@ int modbus_write_and_read_registers(modbus_t *ctx, | ||
| 1490 | return -1; | 1494 | return -1; |
| 1491 | } | 1495 | } |
| 1492 | req_length = ctx->backend->build_request_basis(ctx, | 1496 | req_length = ctx->backend->build_request_basis(ctx, |
| 1493 | - _FC_WRITE_AND_READ_REGISTERS, | 1497 | + MODBUS_FC_WRITE_AND_READ_REGISTERS, |
| 1494 | read_addr, read_nb, req); | 1498 | read_addr, read_nb, req); |
| 1495 | 1499 | ||
| 1496 | req[req_length++] = write_addr >> 8; | 1500 | req[req_length++] = write_addr >> 8; |
| @@ -1541,7 +1545,7 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *dest) | @@ -1541,7 +1545,7 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *dest) | ||
| 1541 | return -1; | 1545 | return -1; |
| 1542 | } | 1546 | } |
| 1543 | 1547 | ||
| 1544 | - req_length = ctx->backend->build_request_basis(ctx, _FC_REPORT_SLAVE_ID, | 1548 | + req_length = ctx->backend->build_request_basis(ctx, MODBUS_FC_REPORT_SLAVE_ID, |
| 1545 | 0, 0, req); | 1549 | 0, 0, req); |
| 1546 | 1550 | ||
| 1547 | /* HACKISH, addr and count are not used */ | 1551 | /* HACKISH, addr and count are not used */ |
src/modbus.h
| 1 | /* | 1 | /* |
| 2 | - * Copyright © 2001-2011 Stéphane Raimbault <stephane.raimbault@gmail.com> | 2 | + * Copyright © 2001-2013 Stéphane Raimbault <stephane.raimbault@gmail.com> |
| 3 | * | 3 | * |
| 4 | * This library is free software; you can redistribute it and/or | 4 | * This library is free software; you can redistribute it and/or |
| 5 | * modify it under the terms of the GNU Lesser General Public | 5 | * modify it under the terms of the GNU Lesser General Public |
| @@ -71,6 +71,20 @@ MODBUS_BEGIN_DECLS | @@ -71,6 +71,20 @@ MODBUS_BEGIN_DECLS | ||
| 71 | #define ON 1 | 71 | #define ON 1 |
| 72 | #endif | 72 | #endif |
| 73 | 73 | ||
| 74 | +/* Modbus function codes */ | ||
| 75 | +#define MODBUS_FC_READ_COILS 0x01 | ||
| 76 | +#define MODBUS_FC_READ_DISCRETE_INPUTS 0x02 | ||
| 77 | +#define MODBUS_FC_READ_HOLDING_REGISTERS 0x03 | ||
| 78 | +#define MODBUS_FC_READ_INPUT_REGISTERS 0x04 | ||
| 79 | +#define MODBUS_FC_WRITE_SINGLE_COIL 0x05 | ||
| 80 | +#define MODBUS_FC_WRITE_SINGLE_REGISTER 0x06 | ||
| 81 | +#define MODBUS_FC_READ_EXCEPTION_STATUS 0x07 | ||
| 82 | +#define MODBUS_FC_WRITE_MULTIPLE_COILS 0x0F | ||
| 83 | +#define MODBUS_FC_WRITE_MULTIPLE_REGISTERS 0x10 | ||
| 84 | +#define MODBUS_FC_REPORT_SLAVE_ID 0x11 | ||
| 85 | +#define MODBUS_FC_MASK_WRITE_REGISTER 0x16 | ||
| 86 | +#define MODBUS_FC_WRITE_AND_READ_REGISTERS 0x17 | ||
| 87 | + | ||
| 74 | #define MODBUS_BROADCAST_ADDRESS 0 | 88 | #define MODBUS_BROADCAST_ADDRESS 0 |
| 75 | 89 | ||
| 76 | /* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 1 page 12) | 90 | /* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 1 page 12) |
tests/unit-test-client.c
| @@ -728,14 +728,14 @@ int test_raw_request(modbus_t *ctx, int use_backend) | @@ -728,14 +728,14 @@ int test_raw_request(modbus_t *ctx, int use_backend) | ||
| 728 | /* slave */ | 728 | /* slave */ |
| 729 | (use_backend == RTU) ? SERVER_ID : 0xFF, | 729 | (use_backend == RTU) ? SERVER_ID : 0xFF, |
| 730 | /* function, addr 1, 5 values */ | 730 | /* function, addr 1, 5 values */ |
| 731 | - 0x03, 0x00, 0x01, 0x0, 0x05, | 731 | + MODBUS_FC_READ_HOLDING_REGISTERS, 0x00, 0x01, 0x0, 0x05, |
| 732 | }; | 732 | }; |
| 733 | /* Write and read registers request */ | 733 | /* Write and read registers request */ |
| 734 | uint8_t raw_rw_req[] = { | 734 | uint8_t raw_rw_req[] = { |
| 735 | /* slave */ | 735 | /* slave */ |
| 736 | (use_backend == RTU) ? SERVER_ID : 0xFF, | 736 | (use_backend == RTU) ? SERVER_ID : 0xFF, |
| 737 | /* function, addr to read, nb to read */ | 737 | /* function, addr to read, nb to read */ |
| 738 | - 0x17, | 738 | + MODBUS_FC_WRITE_AND_READ_REGISTERS, |
| 739 | /* Read */ | 739 | /* Read */ |
| 740 | 0, 0, | 740 | 0, 0, |
| 741 | (MODBUS_MAX_WR_READ_REGISTERS + 1) >> 8, | 741 | (MODBUS_MAX_WR_READ_REGISTERS + 1) >> 8, |
| @@ -751,7 +751,12 @@ int test_raw_request(modbus_t *ctx, int use_backend) | @@ -751,7 +751,12 @@ int test_raw_request(modbus_t *ctx, int use_backend) | ||
| 751 | /* See issue #143, test with MAX_WR_WRITE_REGISTERS */ | 751 | /* See issue #143, test with MAX_WR_WRITE_REGISTERS */ |
| 752 | int req_length; | 752 | int req_length; |
| 753 | uint8_t rsp[MODBUS_TCP_MAX_ADU_LENGTH]; | 753 | uint8_t rsp[MODBUS_TCP_MAX_ADU_LENGTH]; |
| 754 | - int tab_function[] = {0x01, 0x02, 0x03, 0x04}; | 754 | + int tab_function[] = { |
| 755 | + MODBUS_FC_READ_COILS, | ||
| 756 | + MODBUS_FC_READ_DISCRETE_INPUTS, | ||
| 757 | + MODBUS_FC_READ_HOLDING_REGISTERS, | ||
| 758 | + MODBUS_FC_READ_INPUT_REGISTERS | ||
| 759 | + }; | ||
| 755 | int tab_nb_max[] = { | 760 | int tab_nb_max[] = { |
| 756 | MODBUS_MAX_READ_BITS + 1, | 761 | MODBUS_MAX_READ_BITS + 1, |
| 757 | MODBUS_MAX_READ_BITS + 1, | 762 | MODBUS_MAX_READ_BITS + 1, |
| @@ -835,7 +840,7 @@ int test_raw_request(modbus_t *ctx, int use_backend) | @@ -835,7 +840,7 @@ int test_raw_request(modbus_t *ctx, int use_backend) | ||
| 835 | 840 | ||
| 836 | /* Modbus write and read multiple registers */ | 841 | /* Modbus write and read multiple registers */ |
| 837 | i = 0; | 842 | i = 0; |
| 838 | - tab_function[i] = 0x17; | 843 | + tab_function[i] = MODBUS_FC_WRITE_AND_READ_REGISTERS; |
| 839 | for (j=0; j<2; j++) { | 844 | for (j=0; j<2; j++) { |
| 840 | if (j == 0) { | 845 | if (j == 0) { |
| 841 | /* Try to read zero values on first iteration */ | 846 | /* Try to read zero values on first iteration */ |