msousa@0: /* msousa@0: * Copyright (c) 2001,2016 Mario de Sousa (msousa@fe.up.pt) msousa@0: * msousa@0: * This file is part of the Modbus library for Beremiz and matiec. msousa@0: * msousa@0: * This Modbus library is free software: you can redistribute it and/or modify msousa@0: * it under the terms of the GNU Lesser General Public License as published by msousa@0: * the Free Software Foundation, either version 3 of the License, or msousa@0: * (at your option) any later version. msousa@0: * msousa@0: * This program is distributed in the hope that it will be useful, but msousa@0: * WITHOUT ANY WARRANTY; without even the implied warranty of msousa@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser msousa@0: * General Public License for more details. msousa@0: * msousa@0: * You should have received a copy of the GNU Lesser General Public License msousa@0: * along with this Modbus library. If not, see . msousa@0: * msousa@0: * This code is made available on the understanding that it will not be msousa@0: * used in safety-critical situations without a full and competent review. msousa@0: */ msousa@0: msousa@0: msousa@0: /* mb_slave.h */ msousa@0: msousa@0: msousa@0: #ifndef MODBUS_SLAVE_H msousa@0: #define MODBUS_SLAVE_H msousa@0: msousa@0: #include /* struct timespec data structure */ msousa@0: msousa@0: #include "mb_types.h" /* get the data types */ msousa@0: #include "mb_addr.h" /* get definition of common variable types and error codes */ msousa@0: msousa@0: msousa@0: msousa@0: msousa@0: /* Initialise the Modbus Library to work as Slave/Server only */ msousa@0: int mb_slave_init(int nd_count); msousa@0: /* Shut down the Modbus Library */ msousa@0: int mb_slave_done(void); msousa@0: msousa@0: msousa@0: msousa@0: msousa@0: /* Create a new slave/server... msousa@0: * msousa@0: * This function creates a new node used to: msousa@0: * - accept connection requests (TCP version) msousa@0: * - receive frames from masters (RTU and ASCII versions) msousa@0: * msousa@0: * The type of address (naf_tcp, naf_rtu, naf_ascii) will specify the lower msousa@0: * layer of modbus that will be used by the newly opened node. msousa@0: */ msousa@0: int mb_slave_new(node_addr_t node_addr); msousa@0: /* close a node crreated by mb_slave_new() */ msousa@0: int mb_slave_close(int nd); msousa@0: msousa@0: msousa@0: msousa@0: msousa@0: /***********************************************/ msousa@0: /***********************************************/ msousa@0: /** **/ msousa@0: /** Run the slave **/ msousa@0: /** **/ msousa@0: /***********************************************/ msousa@0: /***********************************************/ msousa@0: msousa@0: msousa@0: /* The following functions must return: msousa@0: * -2 on attempt to read invalid address msousa@0: * -1 on all other errors... msousa@0: * 0 on success. msousa@0: * msousa@0: * Start_addr may start from 0, to 65535! msousa@0: * In other words, we use 0 based addressing! msousa@0: */ msousa@0: typedef struct { msousa@0: int (*read_inbits) (void *arg, u16 start_addr, u16 bit_count, u8 *data_bytes); /* bits are packed into bytes... */ msousa@0: int (*read_outbits) (void *arg, u16 start_addr, u16 bit_count, u8 *data_bytes); /* bits are packed into bytes... */ msousa@0: int (*write_outbits) (void *arg, u16 start_addr, u16 bit_count, u8 *data_bytes); /* bits are packed into bytes... */ msousa@0: int (*read_inwords) (void *arg, u16 start_addr, u16 word_count, u16 *data_words); msousa@0: int (*read_outwords) (void *arg, u16 start_addr, u16 word_count, u16 *data_words); msousa@0: int (*write_outwords)(void *arg, u16 start_addr, u16 word_count, u16 *data_words); msousa@0: void *arg; msousa@0: } mb_slave_callback_t; msousa@0: msousa@0: /* Execute the Slave and process requests coming from masters... msousa@0: * This function enters an infinite loop wating for new connection requests, msousa@0: * and for modbus requests over previoulsy open connections... msousa@0: * msousa@0: * The frames are read from: msousa@0: * - the node descriptor nd, if nd >= 0 msousa@0: * When using TCP, if the referenced node nd was created to listen for new connections msousa@0: * [mb_slave_listen()], then this function will also reply to Modbus data requests arriving msousa@0: * on other nodes that were created as a consequence of accepting connections requests to msousa@0: * the referenced node nd. msousa@0: * All other nodes are ignored! msousa@0: * msousa@0: * - any valid and initialised TCP node descriptor, if nd = -1 msousa@0: * In this case, will also accept connection requests arriving from a previously msousa@0: * created node to listen for new connection requests [mb_slave_listen() ]. msousa@0: * NOTE: (only avaliable if using TCP) msousa@0: * msousa@0: * slaveid identifies the address (RTU and ASCII) or slaveid (TCP) that we implement. msousa@0: * Any requests that we receive sent with a slaveid different msousa@0: * than the one specified, and also different to 0, will be silently ignored! msousa@0: * Whatever the slaveid specified, we always reply to requests msousa@0: * to slaveid 0 (the modbus broadcast address). msousa@0: * Calling this function with a slaveid of 0 means to ignore this msousa@0: * parameter and to reply to all requests (whatever the slaveid msousa@0: * used in the request). This should mostly be used by TCP servers... msousa@0: */ msousa@0: int mb_slave_run(int nd, mb_slave_callback_t callback_functions, u8 slaveid); msousa@0: msousa@0: msousa@0: msousa@0: msousa@0: #endif /* MODBUS_SLAVE_H */ msousa@0: msousa@0: msousa@0: msousa@0: msousa@0: msousa@0: msousa@0: msousa@0: