mb_layer1_prototypes.h
author bmakuc <blaz.makuc@smarteh.si>
Wed, 27 Nov 2019 14:53:22 +0100
changeset 4 99009b24d401
parent 0 ae252e0fd9b8
permissions -rw-r--r--
Variables start_addr and count were read from query_packet using function mb_ntoh_safe. It looks like some compilers change the pointer alignment if the first byte starts at an odd address. Because mb_ntoh_safe uses pointers slave address and count (number of registers) were not read correctly from the buffer when several modbus slaves were present in network. In this temporary solution pointer aritmetics is replaced by simple 256 multiplication.
0
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
     1
/*
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
     2
 * Copyright (c) 2002,2016 Mario de Sousa (msousa@fe.up.pt)
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
     3
 *
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
     4
 * This file is part of the Modbus library for Beremiz and matiec.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
     5
 *
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
     6
 * This Modbus library is free software: you can redistribute it and/or modify
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
     7
 * it under the terms of the GNU Lesser General Public License as published by
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
     8
 * the Free Software Foundation, either version 3 of the License, or
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
     9
 * (at your option) any later version.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    10
 *
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    11
 * This program is distributed in the hope that it will be useful, but
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    14
 * General Public License for more details.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    15
 *
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    16
 * You should have received a copy of the GNU Lesser General Public License
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    17
 * along with this Modbus library.  If not, see <http://www.gnu.org/licenses/>.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    18
 *
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    19
 * This code is made available on the understanding that it will not be
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    20
 * used in safety-critical situations without a full and competent review.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    21
 */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    22
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    23
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    24
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    25
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    26
 /* write a modbus frame */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    27
 /* WARNING: when calling this function, the *frame_data buffer
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    28
  *          must be allocated with an extra *extra_bytes
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    29
  *          beyond those required for the frame_length.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    30
  *          This is because the extra bytes will be used
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    31
  *          to store the crc before sending the frame.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    32
  *
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    33
  *          The *extra_bytes value will be returned by the
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    34
  *          modbus_init() function call.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    35
  */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    36
 /* NOTE: calling this function will flush the input stream,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    37
  *       which means any frames that may have arrived
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    38
  *       but have not yet been read using modbus_read()
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    39
  *       will be permanently lost...
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    40
  */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    41
int modbus_write(int    nd,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    42
                 u8    *frame_data,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    43
                 size_t frame_length,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    44
                 u16    transaction_id,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    45
                 const struct timespec *transmit_timeout
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    46
                );
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    47
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    48
 /* read a modbus frame */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    49
/*
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    50
 * The frame is read from:
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    51
 *   -  the node descriptor nd, if nd >= 0
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    52
 *   -  any valid and initialised node descriptor, if nd = -1
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    53
 *      In this case, the node where the data is eventually read from
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    54
 *      is returned in *nd.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    55
 *      NOTE: (only avaliable if using TCP)
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    56
 */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    57
 /* NOTE: calling modbus_write() will flush the input stream,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    58
  *       which means any frames that may have arrived
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    59
  *       but have not yet been read using modbus_read()
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    60
  *       will be permanently lost...
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    61
  *
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    62
  * NOTE: Ususal select semantics for (a: recv_timeout == NULL) and
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    63
  *       (b: *recv_timeout == 0) also apply.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    64
  *       (a) Indefinite timeout
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    65
  *       (b) Try once, and and quit if no data available.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    66
  */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    67
 /* NOTE: send_data and send_length is used to pass to the modbus_read() function
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    68
  *        the frame that was previously sent over the same connection (node).
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    69
  *        This data is then allows the modbus_read() function to ignore any 
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    70
  *        data that is read but identical to the previously sent data. This
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    71
  *        is used when using serial ports that echoes back all the data that is 
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    72
  *        sent out over the same serial port. When using some RS232 to RS485 
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    73
  *        converters, this functionality is essential as not all these converters
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    74
  *        are capable of not echoing back the sent data.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    75
  *       These parameters are ignored when using TCP! 
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    76
  */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    77
 
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    78
 /* RETURNS: number of bytes read
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    79
  *          -1 on read from file/node error
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    80
  *          -2 on timeout
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    81
  */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    82
int modbus_read(int *nd,                /* node descriptor */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    83
                u8 **recv_data_ptr,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    84
                u16 *transaction_id,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    85
                const u8 *send_data,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    86
                int send_length,      
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    87
                const struct timespec *recv_timeout);
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    88
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    89
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    90
 /* init the library */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    91
int modbus_init(int nd_count,        /* maximum number of nodes... */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    92
                optimization_t opt,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    93
                int *extra_bytes);
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    94
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    95
 /* shutdown the library...*/
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    96
int modbus_done(void);
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    97
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    98
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
    99
/* Open a node for master / slave operation.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   100
 * Returns the node descriptor, or -1 on error.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   101
 */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   102
int modbus_connect(node_addr_t node_addr);
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   103
int modbus_listen(node_addr_t node_addr);
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   104
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   105
/* Close a node, needs a node descriptor as argument... */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   106
int modbus_close(int nd);
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   107
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   108
/* Tell the library that the user will probably not be communicating
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   109
 * for some time...
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   110
 * This will allow the library to release any resources it will not
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   111
 * be needing during the silence.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   112
 * NOTE: This is onlyused by the TCP version to close down tcp connections
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   113
 *       when the silence will going to be longer than  second.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   114
 */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   115
int modbus_silence_init(void);
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   116
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   117
 /* determine the minmum acceptable timeout... */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   118
 /* NOTE: timeout values passed to modbus_read() lower than the value returned
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   119
  *       by this function may result in frames being aborted midway, since they
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   120
  *       take at least modbus_get_min_timeout() seconds to transmit.
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   121
  */
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   122
double modbus_get_min_timeout(int baud,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   123
                              int parity,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   124
                              int data_bits,
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   125
                              int stop_bits);
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   126
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   127
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   128
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   129
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   130
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   131
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   132
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   133
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   134
ae252e0fd9b8 Initial commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
diff changeset
   135