Commit 52ab1bbea760ed8eaca184f7d875a2f52a116d0f

Authored by Michael Heimpold
Committed by Stéphane Raimbault
1 parent 1776a350

Introduce offsets in modbus mappings

This allows to place the coils/registers at any virtual
start address, not only at address 0. This can be useful e.g.
when the server has to fulfill a specification in which
registers are expected at predefined locations.

Signed-off-by: Michael Heimpold <mhei@heimpold.de>
doc/Makefile.am
... ... @@ -12,6 +12,7 @@ TXT3 = \
12 12 modbus_get_socket.txt \
13 13 modbus_mapping_free.txt \
14 14 modbus_mapping_new.txt \
  15 + modbus_mapping_offset_new.txt \
15 16 modbus_mask_write_register.txt \
16 17 modbus_new_rtu.txt \
17 18 modbus_new_tcp_pi.txt \
... ...
doc/modbus_mapping_new.txt
... ... @@ -18,6 +18,9 @@ The *modbus_mapping_new()* function shall allocate four arrays to store bits,
18 18 input bits, registers and inputs registers. The pointers are stored in
19 19 modbus_mapping_t structure. All values of the arrays are initialized to zero.
20 20  
  21 +This function is equivalent to a call of the _modbus_mapping_offset_new()_ function
  22 +with all offsets set to zero.
  23 +
21 24 If it isn't necessary to allocate an array for a specific type of data, you can
22 25 pass the zero value in argument, the associated pointer will be NULL.
23 26  
... ... @@ -40,7 +43,7 @@ EXAMPLE
40 43 -------
41 44 [source,c]
42 45 -------------------
43   -/* The fist value of each array is accessible from the 0 address. */
  46 +/* The first value of each array is accessible from the 0 address. */
44 47 mb_mapping = modbus_mapping_new(BITS_ADDRESS + BITS_NB,
45 48 INPUT_BITS_ADDRESS + INPUT_BITS_NB,
46 49 REGISTERS_ADDRESS + REGISTERS_NB,
... ...
doc/modbus_mapping_offset_new.txt 0 → 100644
  1 +modbus_mapping_offset_new(3)
  2 +============================
  3 +
  4 +
  5 +NAME
  6 +----
  7 +modbus_mapping_offset_new - allocate four arrays of bits and registers
  8 +
  9 +
  10 +SYNOPSIS
  11 +--------
  12 +*modbus_mapping_t* modbus_mapping_new(int 'nb_bits', int 'offset_bits',
  13 + int 'nb_input_bits', int 'offset_input_bits',
  14 + int 'nb_registers', int 'offset_registers',
  15 + int 'nb_input_registers', int 'offset_input_registers');*
  16 +
  17 +
  18 +DESCRIPTION
  19 +-----------
  20 +The _modbus_mapping_offset_new()_ function shall allocate four arrays to store bits,
  21 +input bits, registers and inputs registers. The pointers are stored in
  22 +modbus_mapping_t structure. All values of the arrays are initialized to zero.
  23 +
  24 +The different offsets make it possible to place the mapping at any address in
  25 +each address space.
  26 +
  27 +If it isn't necessary to allocate an array for a specific type of data, you can
  28 +pass the zero value in argument, the associated pointer will be NULL.
  29 +
  30 +This function is convenient to handle requests in a Modbus server/slave.
  31 +
  32 +
  33 +RETURN VALUE
  34 +------------
  35 +The _modbus_mapping_offset_new()_ function shall return the new allocated structure if
  36 +successful. Otherwise it shall return NULL and set errno.
  37 +
  38 +
  39 +ERRORS
  40 +------
  41 +ENOMEM::
  42 +Not enough memory
  43 +
  44 +
  45 +EXAMPLE
  46 +-------
  47 +[source,c]
  48 +-------------------
  49 +/* The first value of each array is accessible at address 4. */
  50 +mb_mapping = modbus_mapping_offset_new(BITS_ADDRESS + BITS_NB, 4,
  51 + INPUT_BITS_ADDRESS + INPUT_BITS_NB, 4,
  52 + REGISTERS_ADDRESS + REGISTERS_NB, 4,
  53 + INPUT_REGISTERS_ADDRESS + INPUT_REGISTERS_NB, 4);
  54 +if (mb_mapping == NULL) {
  55 + fprintf(stderr, "Failed to allocate the mapping: %s\n",
  56 + modbus_strerror(errno));
  57 + modbus_free(ctx);
  58 + return -1;
  59 +}
  60 +-------------------
  61 +
  62 +SEE ALSO
  63 +--------
  64 +linkmb:modbus_mapping_free[3]
  65 +
  66 +
  67 +AUTHORS
  68 +-------
  69 +The libmodbus documentation was written by Stéphane Raimbault
  70 +<stephane.raimbault@gmail.com>
... ...
src/modbus.c
... ... @@ -706,6 +706,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
706 706 switch (function) {
707 707 case MODBUS_FC_READ_COILS: {
708 708 int nb = (req[offset + 3] << 8) + req[offset + 4];
  709 + int addr = address - mb_mapping->offset_bits;
709 710  
710 711 if (nb < 1 || MODBUS_MAX_READ_BITS < nb) {
711 712 if (ctx->debug) {
... ... @@ -718,10 +719,10 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
718 719 rsp_length = response_exception(
719 720 ctx, &sft,
720 721 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
721   - } else if ((address + nb) > mb_mapping->nb_bits) {
  722 + } else if (address < mb_mapping->offset_bits || (addr + nb) > mb_mapping->nb_bits) {
722 723 if (ctx->debug) {
723 724 fprintf(stderr, "Illegal data address 0x%0X in read_bits\n",
724   - address + nb);
  725 + address < mb_mapping->offset_bits ? address : address + nb);
725 726 }
726 727 rsp_length = response_exception(
727 728 ctx, &sft,
... ... @@ -729,7 +730,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
729 730 } else {
730 731 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
731 732 rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
732   - rsp_length = response_io_status(address, nb,
  733 + rsp_length = response_io_status(addr, nb,
733 734 mb_mapping->tab_bits,
734 735 rsp, rsp_length);
735 736 }
... ... @@ -739,6 +740,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
739 740 /* Similar to coil status (but too many arguments to use a
740 741 * function) */
741 742 int nb = (req[offset + 3] << 8) + req[offset + 4];
  743 + int addr = address - mb_mapping->offset_input_bits;
742 744  
743 745 if (nb < 1 || MODBUS_MAX_READ_BITS < nb) {
744 746 if (ctx->debug) {
... ... @@ -751,10 +753,10 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
751 753 rsp_length = response_exception(
752 754 ctx, &sft,
753 755 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
754   - } else if ((address + nb) > mb_mapping->nb_input_bits) {
  756 + } else if (address < mb_mapping->offset_input_bits || (addr + nb) > mb_mapping->nb_input_bits) {
755 757 if (ctx->debug) {
756 758 fprintf(stderr, "Illegal data address 0x%0X in read_input_bits\n",
757   - address + nb);
  759 + address < mb_mapping->offset_input_bits ? address : address + nb);
758 760 }
759 761 rsp_length = response_exception(
760 762 ctx, &sft,
... ... @@ -762,7 +764,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
762 764 } else {
763 765 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
764 766 rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
765   - rsp_length = response_io_status(address, nb,
  767 + rsp_length = response_io_status(addr, nb,
766 768 mb_mapping->tab_input_bits,
767 769 rsp, rsp_length);
768 770 }
... ... @@ -770,6 +772,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
770 772 break;
771 773 case MODBUS_FC_READ_HOLDING_REGISTERS: {
772 774 int nb = (req[offset + 3] << 8) + req[offset + 4];
  775 + int addr = address - mb_mapping->offset_registers;
773 776  
774 777 if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) {
775 778 if (ctx->debug) {
... ... @@ -782,10 +785,10 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
782 785 rsp_length = response_exception(
783 786 ctx, &sft,
784 787 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
785   - } else if ((address + nb) > mb_mapping->nb_registers) {
  788 + } else if (address < mb_mapping->offset_registers || (addr + nb) > mb_mapping->nb_registers) {
786 789 if (ctx->debug) {
787 790 fprintf(stderr, "Illegal data address 0x%0X in read_registers\n",
788   - address + nb);
  791 + address < mb_mapping->offset_registers ? address : address + nb);
789 792 }
790 793 rsp_length = response_exception(
791 794 ctx, &sft,
... ... @@ -795,7 +798,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
795 798  
796 799 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
797 800 rsp[rsp_length++] = nb << 1;
798   - for (i = address; i < address + nb; i++) {
  801 + for (i = addr; i < addr + nb; i++) {
799 802 rsp[rsp_length++] = mb_mapping->tab_registers[i] >> 8;
800 803 rsp[rsp_length++] = mb_mapping->tab_registers[i] & 0xFF;
801 804 }
... ... @@ -806,6 +809,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
806 809 /* Similar to holding registers (but too many arguments to use a
807 810 * function) */
808 811 int nb = (req[offset + 3] << 8) + req[offset + 4];
  812 + int addr = address - mb_mapping->offset_input_registers;
809 813  
810 814 if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) {
811 815 if (ctx->debug) {
... ... @@ -818,10 +822,10 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
818 822 rsp_length = response_exception(
819 823 ctx, &sft,
820 824 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
821   - } else if ((address + nb) > mb_mapping->nb_input_registers) {
  825 + } else if (address < mb_mapping->offset_input_registers || (addr + nb) > mb_mapping->nb_input_registers) {
822 826 if (ctx->debug) {
823 827 fprintf(stderr, "Illegal data address 0x%0X in read_input_registers\n",
824   - address + nb);
  828 + address < mb_mapping->offset_input_registers ? address : address + nb);
825 829 }
826 830 rsp_length = response_exception(
827 831 ctx, &sft,
... ... @@ -831,15 +835,17 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
831 835  
832 836 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
833 837 rsp[rsp_length++] = nb << 1;
834   - for (i = address; i < address + nb; i++) {
  838 + for (i = addr; i < addr + nb; i++) {
835 839 rsp[rsp_length++] = mb_mapping->tab_input_registers[i] >> 8;
836 840 rsp[rsp_length++] = mb_mapping->tab_input_registers[i] & 0xFF;
837 841 }
838 842 }
839 843 }
840 844 break;
841   - case MODBUS_FC_WRITE_SINGLE_COIL:
842   - if (address >= mb_mapping->nb_bits) {
  845 + case MODBUS_FC_WRITE_SINGLE_COIL: {
  846 + int addr = address - mb_mapping->offset_bits;
  847 +
  848 + if (address < mb_mapping->offset_bits || addr >= mb_mapping->nb_bits) {
843 849 if (ctx->debug) {
844 850 fprintf(stderr,
845 851 "Illegal data address 0x%0X in write_bit\n",
... ... @@ -852,7 +858,7 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
852 858 int data = (req[offset + 3] << 8) + req[offset + 4];
853 859  
854 860 if (data == 0xFF00 || data == 0x0) {
855   - mb_mapping->tab_bits[address] = (data) ? ON : OFF;
  861 + mb_mapping->tab_bits[addr] = (data) ? ON : OFF;
856 862 memcpy(rsp, req, req_length);
857 863 rsp_length = req_length;
858 864 } else {
... ... @@ -866,9 +872,12 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
866 872 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
867 873 }
868 874 }
  875 + }
869 876 break;
870   - case MODBUS_FC_WRITE_SINGLE_REGISTER:
871   - if (address >= mb_mapping->nb_registers) {
  877 + case MODBUS_FC_WRITE_SINGLE_REGISTER: {
  878 + int addr = address - mb_mapping->offset_registers;
  879 +
  880 + if (address < mb_mapping->offset_registers || addr >= mb_mapping->nb_registers) {
872 881 if (ctx->debug) {
873 882 fprintf(stderr, "Illegal data address 0x%0X in write_register\n",
874 883 address);
... ... @@ -879,13 +888,15 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
879 888 } else {
880 889 int data = (req[offset + 3] << 8) + req[offset + 4];
881 890  
882   - mb_mapping->tab_registers[address] = data;
  891 + mb_mapping->tab_registers[addr] = data;
883 892 memcpy(rsp, req, req_length);
884 893 rsp_length = req_length;
885 894 }
  895 + }
886 896 break;
887 897 case MODBUS_FC_WRITE_MULTIPLE_COILS: {
888 898 int nb = (req[offset + 3] << 8) + req[offset + 4];
  899 + int addr = address - mb_mapping->offset_bits;
889 900  
890 901 if (nb < 1 || MODBUS_MAX_WRITE_BITS < nb) {
891 902 if (ctx->debug) {
... ... @@ -901,17 +912,17 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
901 912 rsp_length = response_exception(
902 913 ctx, &sft,
903 914 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
904   - } else if ((address + nb) > mb_mapping->nb_bits) {
  915 + } else if (address < mb_mapping->offset_bits || (addr + nb) > mb_mapping->nb_bits) {
905 916 if (ctx->debug) {
906 917 fprintf(stderr, "Illegal data address 0x%0X in write_bits\n",
907   - address + nb);
  918 + address < mb_mapping->offset_bits ? address : address + nb);
908 919 }
909 920 rsp_length = response_exception(
910 921 ctx, &sft,
911 922 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
912 923 } else {
913 924 /* 6 = byte count */
914   - modbus_set_bits_from_bytes(mb_mapping->tab_bits, address, nb, &req[offset + 6]);
  925 + modbus_set_bits_from_bytes(mb_mapping->tab_bits, addr, nb, &req[offset + 6]);
915 926  
916 927 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
917 928 /* 4 to copy the bit address (2) and the quantity of bits */
... ... @@ -922,6 +933,8 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
922 933 break;
923 934 case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: {
924 935 int nb = (req[offset + 3] << 8) + req[offset + 4];
  936 + int addr = address - mb_mapping->offset_registers;
  937 +
925 938 if (nb < 1 || MODBUS_MAX_WRITE_REGISTERS < nb) {
926 939 if (ctx->debug) {
927 940 fprintf(stderr,
... ... @@ -936,17 +949,17 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
936 949 rsp_length = response_exception(
937 950 ctx, &sft,
938 951 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
939   - } else if ((address + nb) > mb_mapping->nb_registers) {
  952 + } else if (address < mb_mapping->offset_registers || (addr + nb) > mb_mapping->nb_registers) {
940 953 if (ctx->debug) {
941 954 fprintf(stderr, "Illegal data address 0x%0X in write_registers\n",
942   - address + nb);
  955 + address < mb_mapping->offset_registers ? address : address + nb);
943 956 }
944 957 rsp_length = response_exception(
945 958 ctx, &sft,
946 959 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
947 960 } else {
948 961 int i, j;
949   - for (i = address, j = 6; i < address + nb; i++, j += 2) {
  962 + for (i = addr, j = 6; i < addr + nb; i++, j += 2) {
950 963 /* 6 and 7 = first value */
951 964 mb_mapping->tab_registers[i] =
952 965 (req[offset + j] << 8) + req[offset + j + 1];
... ... @@ -983,8 +996,10 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
983 996 errno = ENOPROTOOPT;
984 997 return -1;
985 998 break;
986   - case MODBUS_FC_MASK_WRITE_REGISTER:
987   - if (address >= mb_mapping->nb_registers) {
  999 + case MODBUS_FC_MASK_WRITE_REGISTER: {
  1000 + int addr = address - mb_mapping->offset_registers;
  1001 +
  1002 + if (address < mb_mapping->offset_registers || addr >= mb_mapping->nb_registers) {
988 1003 if (ctx->debug) {
989 1004 fprintf(stderr, "Illegal data address 0x%0X in write_register\n",
990 1005 address);
... ... @@ -993,21 +1008,24 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
993 1008 ctx, &sft,
994 1009 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
995 1010 } else {
996   - uint16_t data = mb_mapping->tab_registers[address];
  1011 + uint16_t data = mb_mapping->tab_registers[addr];
997 1012 uint16_t and = (req[offset + 3] << 8) + req[offset + 4];
998 1013 uint16_t or = (req[offset + 5] << 8) + req[offset + 6];
999 1014  
1000 1015 data = (data & and) | (or & (~and));
1001   - mb_mapping->tab_registers[address] = data;
  1016 + mb_mapping->tab_registers[addr] = data;
1002 1017 memcpy(rsp, req, req_length);
1003 1018 rsp_length = req_length;
1004 1019 }
  1020 + }
1005 1021 break;
1006 1022 case MODBUS_FC_WRITE_AND_READ_REGISTERS: {
1007 1023 int nb = (req[offset + 3] << 8) + req[offset + 4];
1008 1024 uint16_t address_write = (req[offset + 5] << 8) + req[offset + 6];
1009 1025 int nb_write = (req[offset + 7] << 8) + req[offset + 8];
1010 1026 int nb_write_bytes = req[offset + 9];
  1027 + int addr = address - mb_mapping->offset_registers;
  1028 + int addr_write = address_write - mb_mapping->offset_registers;
1011 1029  
1012 1030 if (nb_write < 1 || MODBUS_MAX_WR_WRITE_REGISTERS < nb_write ||
1013 1031 nb < 1 || MODBUS_MAX_WR_READ_REGISTERS < nb ||
... ... @@ -1023,12 +1041,15 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
1023 1041 rsp_length = response_exception(
1024 1042 ctx, &sft,
1025 1043 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, rsp);
1026   - } else if ((address + nb) > mb_mapping->nb_registers ||
1027   - (address_write + nb_write) > mb_mapping->nb_registers) {
  1044 + } else if (address < mb_mapping->offset_registers ||
  1045 + (addr + nb) > mb_mapping->nb_registers ||
  1046 + address_write < mb_mapping->offset_registers ||
  1047 + (addr_write + nb_write) > mb_mapping->nb_registers) {
1028 1048 if (ctx->debug) {
1029 1049 fprintf(stderr,
1030 1050 "Illegal data read address 0x%0X or write address 0x%0X write_and_read_registers\n",
1031   - address + nb, address_write + nb_write);
  1051 + address < mb_mapping->offset_registers ? address : address + nb,
  1052 + address_write < mb_mapping->offset_registers ? address_write : address_write + nb_write);
1032 1053 }
1033 1054 rsp_length = response_exception(ctx, &sft,
1034 1055 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, rsp);
... ... @@ -1039,13 +1060,13 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
1039 1060  
1040 1061 /* Write first.
1041 1062 10 and 11 are the offset of the first values to write */
1042   - for (i = address_write, j = 10; i < address_write + nb_write; i++, j += 2) {
  1063 + for (i = addr_write, j = 10; i < addr_write + nb_write; i++, j += 2) {
1043 1064 mb_mapping->tab_registers[i] =
1044 1065 (req[offset + j] << 8) + req[offset + j + 1];
1045 1066 }
1046 1067  
1047 1068 /* and read the data for the response */
1048   - for (i = address; i < address + nb; i++) {
  1069 + for (i = addr; i < addr + nb; i++) {
1049 1070 rsp[rsp_length++] = mb_mapping->tab_registers[i] >> 8;
1050 1071 rsp[rsp_length++] = mb_mapping->tab_registers[i] & 0xFF;
1051 1072 }
... ... @@ -1786,10 +1807,12 @@ int modbus_set_debug(modbus_t *ctx, int flag)
1786 1807 /* Allocates 4 arrays to store bits, input bits, registers and inputs
1787 1808 registers. The pointers are stored in modbus_mapping structure.
1788 1809  
1789   - The modbus_mapping_new() function shall return the new allocated structure if
  1810 + The modbus_mapping_offset_new() function shall return the new allocated structure if
1790 1811 successful. Otherwise it shall return NULL and set errno to ENOMEM. */
1791   -modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
1792   - int nb_registers, int nb_input_registers)
  1812 +modbus_mapping_t* modbus_mapping_offset_new(int nb_bits, int offset_bits,
  1813 + int nb_input_bits, int offset_input_bits,
  1814 + int nb_registers, int offset_registers,
  1815 + int nb_input_registers, int offset_input_registers)
1793 1816 {
1794 1817 modbus_mapping_t *mb_mapping;
1795 1818  
... ... @@ -1800,6 +1823,7 @@ modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
1800 1823  
1801 1824 /* 0X */
1802 1825 mb_mapping->nb_bits = nb_bits;
  1826 + mb_mapping->offset_bits = offset_bits;
1803 1827 if (nb_bits == 0) {
1804 1828 mb_mapping->tab_bits = NULL;
1805 1829 } else {
... ... @@ -1815,6 +1839,7 @@ modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
1815 1839  
1816 1840 /* 1X */
1817 1841 mb_mapping->nb_input_bits = nb_input_bits;
  1842 + mb_mapping->offset_input_bits = offset_input_bits;
1818 1843 if (nb_input_bits == 0) {
1819 1844 mb_mapping->tab_input_bits = NULL;
1820 1845 } else {
... ... @@ -1830,6 +1855,7 @@ modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
1830 1855  
1831 1856 /* 4X */
1832 1857 mb_mapping->nb_registers = nb_registers;
  1858 + mb_mapping->offset_registers = offset_registers;
1833 1859 if (nb_registers == 0) {
1834 1860 mb_mapping->tab_registers = NULL;
1835 1861 } else {
... ... @@ -1846,6 +1872,7 @@ modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
1846 1872  
1847 1873 /* 3X */
1848 1874 mb_mapping->nb_input_registers = nb_input_registers;
  1875 + mb_mapping->offset_input_registers = offset_input_registers;
1849 1876 if (nb_input_registers == 0) {
1850 1877 mb_mapping->tab_input_registers = NULL;
1851 1878 } else {
... ... @@ -1865,6 +1892,12 @@ modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
1865 1892 return mb_mapping;
1866 1893 }
1867 1894  
  1895 +modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
  1896 + int nb_registers, int nb_input_registers)
  1897 +{
  1898 + return modbus_mapping_offset_new(nb_bits, 0, nb_input_bits, 0, nb_registers, 0, nb_input_registers, 0);
  1899 +}
  1900 +
1868 1901 /* Frees the 4 arrays */
1869 1902 void modbus_mapping_free(modbus_mapping_t *mb_mapping)
1870 1903 {
... ...
src/modbus.h
... ... @@ -156,9 +156,13 @@ typedef struct _modbus modbus_t;
156 156  
157 157 typedef struct {
158 158 int nb_bits;
  159 + int offset_bits;
159 160 int nb_input_bits;
  161 + int offset_input_bits;
160 162 int nb_input_registers;
  163 + int offset_input_registers;
161 164 int nb_registers;
  165 + int offset_registers;
162 166 uint8_t *tab_bits;
163 167 uint8_t *tab_input_bits;
164 168 uint16_t *tab_input_registers;
... ... @@ -209,6 +213,10 @@ MODBUS_API int modbus_write_and_read_registers(modbus_t *ctx, int write_addr, in
209 213 uint16_t *dest);
210 214 MODBUS_API int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest);
211 215  
  216 +MODBUS_API modbus_mapping_t* modbus_mapping_offset_new(int nb_bits, int offset_bits,
  217 + int nb_input_bits, int offset_input_bits,
  218 + int nb_registers, int offset_registers,
  219 + int nb_input_registers, int offset_input_registers);
212 220 MODBUS_API modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits,
213 221 int nb_registers, int nb_input_registers);
214 222 MODBUS_API void modbus_mapping_free(modbus_mapping_t *mb_mapping);
... ...