9
0
Fork 0

FreeModBus is now integrated with the Nuttx configuration system

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4961 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-07-21 14:56:21 +00:00
parent 63066af432
commit 38d97ff0b8
24 changed files with 978 additions and 220 deletions

View File

@ -19,6 +19,10 @@ menu "Network Utilities"
source "$APPSDIR/netutils/Kconfig"
endmenu
menu "ModBus"
source "$APPSDIR/modbus/Kconfig"
endmenu
menu "NSH Library"
source "$APPSDIR/nshlib/Kconfig"
endmenu

View File

@ -224,7 +224,7 @@ eMBErrorCode eMBPoll( void );
* \brief Configure the slave id of the device.
*
* This function should be called when the Modbus function <em>Report Slave ID</em>
* is enabled ( By defining MB_FUNC_OTHER_REP_SLAVEID_ENABLED in mbconfig.h ).
* is enabled (By defining CONFIG_MB_FUNC_OTHER_REP_SLAVEID_ENABLED in .config ).
*
* \param ucSlaveID Values is returned in the <em>Slave ID</em> byte of the
* <em>Report Slave ID</em> response.
@ -234,8 +234,8 @@ eMBErrorCode eMBPoll( void );
* bytes of the <em> Report Slave ID</em> response.
* \param usAdditionalLen Length of the buffer <code>pucAdditonal</code>.
*
* \return If the static buffer defined by MB_FUNC_OTHER_REP_SLAVEID_BUF in
* mbconfig.h is to small it returns eMBErrorCode::MB_ENORES. Otherwise
* \return If the static buffer defined by CONFIG_MB_FUNC_OTHER_REP_SLAVEID_BUF
* is too small it returns eMBErrorCode::MB_ENORES. Otherwise
* it returns eMBErrorCode::MB_ENOERR.
*/
eMBErrorCode eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning,
@ -259,7 +259,7 @@ eMBErrorCode eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning,
*
* \return eMBErrorCode::MB_ENOERR if the handler has been installed. If no
* more resources are available it returns eMBErrorCode::MB_ENORES. In this
* case the values in mbconfig.h should be adjusted. If the argument was not
* case the values in config.h should be adjusted. If the argument was not
* valid it returns eMBErrorCode::MB_EINVAL.
*/
eMBErrorCode eMBRegisterCB( UCHAR ucFunctionCode,

View File

@ -1,132 +0,0 @@
/*
* FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
* Copyright (c) 2006 Christian Walter <wolti@sil.at>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* File: $Id: mbconfig.h,v 1.15 2010/06/06 13:54:40 wolti Exp $
*/
#ifndef _MB_CONFIG_H
#define _MB_CONFIG_H
#ifdef __cplusplus
PR_BEGIN_EXTERN_C
#endif
/* ----------------------- Defines ------------------------------------------*/
/*! \defgroup modbus_cfg Modbus Configuration
*
* Most modules in the protocol stack are completly optional and can be
* excluded. This is specially important if target resources are very small
* and program memory space should be saved.<br>
*
* All of these settings are available in the file <code>mbconfig.h</code>
*/
/*! \addtogroup modbus_cfg
* @{
*/
/*! \brief If Modbus ASCII support is enabled. */
#define MB_ASCII_ENABLED ( 1 )
/*! \brief If Modbus RTU support is enabled. */
#define MB_RTU_ENABLED ( 1 )
/*! \brief If Modbus TCP support is enabled. */
#define MB_TCP_ENABLED ( 0 )
/*! \brief The character timeout value for Modbus ASCII.
*
* The character timeout value is not fixed for Modbus ASCII and is therefore
* a configuration option. It should be set to the maximum expected delay
* time of the network.
*/
#define MB_ASCII_TIMEOUT_SEC ( 1 )
/*! \brief Timeout to wait in ASCII prior to enabling transmitter.
*
* If defined the function calls vMBPortSerialDelay with the argument
* MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS to allow for a delay before
* the serial transmitter is enabled. This is required because some
* targets are so fast that there is no time between receiving and
* transmitting the frame. If the master is to slow with enabling its
* receiver then he will not receive the response correctly.
*/
#ifndef MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS
#define MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS ( 0 )
#endif
/*! \brief Maximum number of Modbus functions codes the protocol stack
* should support.
*
* The maximum number of supported Modbus functions must be greater than
* the sum of all enabled functions in this file and custom function
* handlers. If set to small adding more functions will fail.
*/
#define MB_FUNC_HANDLERS_MAX ( 16 )
/*! \brief Number of bytes which should be allocated for the <em>Report Slave ID
* </em>command.
*
* This number limits the maximum size of the additional segment in the
* report slave id function. See eMBSetSlaveID( ) for more information on
* how to set this value. It is only used if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
* is set to <code>1</code>.
*/
#define MB_FUNC_OTHER_REP_SLAVEID_BUF ( 32 )
/*! \brief If the <em>Report Slave ID</em> function should be enabled. */
#define MB_FUNC_OTHER_REP_SLAVEID_ENABLED ( 1 )
/*! \brief If the <em>Read Input Registers</em> function should be enabled. */
#define MB_FUNC_READ_INPUT_ENABLED ( 1 )
/*! \brief If the <em>Read Holding Registers</em> function should be enabled. */
#define MB_FUNC_READ_HOLDING_ENABLED ( 1 )
/*! \brief If the <em>Write Single Register</em> function should be enabled. */
#define MB_FUNC_WRITE_HOLDING_ENABLED ( 1 )
/*! \brief If the <em>Write Multiple registers</em> function should be enabled. */
#define MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED ( 1 )
/*! \brief If the <em>Read Coils</em> function should be enabled. */
#define MB_FUNC_READ_COILS_ENABLED ( 1 )
/*! \brief If the <em>Write Coils</em> function should be enabled. */
#define MB_FUNC_WRITE_COIL_ENABLED ( 1 )
/*! \brief If the <em>Write Multiple Coils</em> function should be enabled. */
#define MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED ( 1 )
/*! \brief If the <em>Read Discrete Inputs</em> function should be enabled. */
#define MB_FUNC_READ_DISCRETE_INPUTS_ENABLED ( 1 )
/*! \brief If the <em>Read/Write Multiple Registers</em> function should be enabled. */
#define MB_FUNC_READWRITE_HOLDING_ENABLED ( 1 )
/*! @} */
#ifdef __cplusplus
PR_END_EXTERN_C
#endif
#endif

View File

@ -34,43 +34,43 @@
#ifdef __cplusplus
PR_BEGIN_EXTERN_C
#endif
#if MB_FUNC_OTHER_REP_SLAVEID_BUF > 0
#ifdef CONFIG_MB_FUNC_OTHER_REP_SLAVEID_BUF
eMBException eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen );
#endif
#if MB_FUNC_READ_INPUT_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_INPUT_ENABLED
eMBException eMBFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen );
#endif
#if MB_FUNC_READ_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_HOLDING_ENABLED
eMBException eMBFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
#endif
#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_HOLDING_ENABLED
eMBException eMBFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
#endif
#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED
eMBException eMBFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
#endif
#if MB_FUNC_READ_COILS_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_COILS_ENABLED
eMBException eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen );
#endif
#if MB_FUNC_WRITE_COIL_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_COIL_ENABLED
eMBException eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen );
#endif
#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED
eMBException eMBFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen );
#endif
#if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_DISCRETE_INPUTS_ENABLED
eMBException eMBFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen );
#endif
#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READWRITE_HOLDING_ENABLED
eMBException eMBFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
#endif

139
apps/modbus/Kconfig Normal file
View File

@ -0,0 +1,139 @@
#
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
comment "FreeModbus"
config MB_ASCII_ENABLED
bool "Modbus ASCII support"
depends on MODBUS
default y
config MB_RTU_ENABLED
bool "Modbus RTU support"
depends on MODBUS
default y
config MB_TCP_ENABLED
bool "Modbus TCP support"
depends on MODBUS
default y
config MB_ASCII_TIMEOUT_SEC
int "Character timeout"
depends on MB_ASCII_ENABLED
default 1
---help---
Character timeout value for Modbus ASCII
The character timeout value is not fixed for Modbus ASCII and is therefore
a configuration option. It should be set to the maximum expected delay
time of the network.
config MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS
int "Timeout to wait before sending"
depends on MB_ASCII_ENABLED
default 0
---help---
Timeout to wait in ASCII prior to enabling transmitter
If defined the function calls vMBPortSerialDelay with the argument
MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS to allow for a delay before
the serial transmitter is enabled. This is required because some
targets are so fast that there is no time between receiving and
transmitting the frame. If the master is to slow with enabling its
receiver then he will not receive the response correctly.
config MB_FUNC_HANDLERS_MAX
int "Maximum number of Modbus functions"
depends on MODBUS
default 16
---help---
Maximum number of Modbus functions codes the protocol stack should support.
The maximum number of supported Modbus functions must be greater than
the sum of all enabled functions in this file and custom function
handlers. If set to small adding more functions will fail.
config MB_FUNC_OTHER_REP_SLAVEID_BUF
int "Size of Slave ID report buffer"
depends on MB_FUNC_OTHER_REP_SLAVEID_ENABLED
default 32
---help---
Number of bytes which should be allocated for the Report Slave ID command.
This number limits the maximum size of the additional segment in the
report slave id function. See eMBSetSlaveID() for more information on
how to set this value. It is only used if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
is set to 1.
config MB_FUNC_OTHER_REP_SLAVEID_ENABLED
bool "Report Slave ID function"
depends on MODBUS
default y
---help---
If the Report Slave ID function should be enabled.
config MB_FUNC_READ_INPUT_ENABLED
bool "Read Input Registers function"
depends on MODBUS
default y
---help---
If the Read Input Registers function should be enabled.
config MB_FUNC_READ_HOLDING_ENABLED
bool "Read Holding Registers function"
depends on MODBUS
default y
---help---
If the Read Holding Registers function should be enabled.
config MB_FUNC_WRITE_HOLDING_ENABLED
bool "Write Single Register function"
depends on MODBUS
default y
---help---
If the Write Single Register function should be enabled.
config MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED
bool "Write Multiple registers function"
depends on MODBUS
default y
---help---
If the Write Multiple registers function should be enabled.
config MB_FUNC_READ_COILS_ENABLED
bool "Read Coils function"
depends on MODBUS
default y
---help---
If the Read Coils function should be enabled.
config MB_FUNC_WRITE_COIL_ENABLED
bool "Write Coils function"
depends on MODBUS
default y
---help---
If the Write Coils function should be enabled.
config MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED
bool "Write Multiple Coils function"
depends on MODBUS
default y
---help---
If the Write Multiple Coils function should be enabled.
config MB_FUNC_READ_DISCRETE_INPUTS_ENABLED
bool "Read Discrete Inputs function"
depends on MODBUS
default y
---help---
If the Read Discrete Inputs function should be enabled.
config MB_FUNC_READWRITE_HOLDING_ENABLED
bool "Read/Write Multiple Registers function"
depends on MODBUS
default y
---help---
If the Read/Write Multiple Registers function should be enabled.

View File

@ -1,14 +1,14 @@
apps/modbus README
==================
This directory contains a port of last open source version of freemodbus
(BSD license). The code in this directory is a subset of freemodbus version
This directory contains a port of last open source version of FreeModBus
(BSD license). The code in this directory is a subset of FreeModBus version
1.5.0 (June 6, 2010) that can be downloaded in its entirety from http://developer.berlios.de/project/showfiles.php?group_id=6120.
Directory Structure/Relation to freemodbus-v1.5.0
-------------------------------------------------
The original freemodbus download consists of several directories. This
The original FreeModBus download consists of several directories. This
subset takes only the contents of one directory, modbus/, that implements
the core modbus logic and integrates that directory into the NuttX build
system. The mapping between freemodbus-v1.5.0 and the nuttx directories
@ -41,14 +41,58 @@ directory except that (1) it may include modifications for the integration
with NuttX and (2) the modbus/include directory was moved to apps/modbus.
The original, unmodified freemodbus-v1.5.0 was checked in as SVN revision
4937
4960.
The other directory here, nuttx/, implements the NuttX modbus interface.
It derives from the freemodbus-v1.5.0/demo/LINUX/port directory.
Configuration Options
=====================
In the original freemodbus-v1.5.0 release, the FreeModBus configuration
was controlled by the header file mbconfig.h. This header file was
eliminated (post revision 4960) and the FreeModBus configuration
was integrated into the NuttX configuration system.
The NuttX-named configuration options that are available include:
CONFIG_MB_ASCII_ENABLED - Modbus ASCII support
CONFIG_MB_RTU_ENABLED - Modbus RTU support
CONFIG_MB_TCP_ENABLED - Modbus TCP support
CONFIG_MB_ASCII_TIMEOUT_SEC - Character timeout value for Modbus ASCII. The
character timeout value is not fixed for Modbus ASCII and is therefore
a configuration option. It should be set to the maximum expected delay
time of the network. Default 1
CONFIG_MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS - Timeout to wait in ASCII prior
to enabling transmitter. If defined the function calls
vMBPortSerialDelay with the argument CONFIG_MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS
to allow for a delay before the serial transmitter is enabled. This is
required because some targets are so fast that there is no time between
receiving and transmitting the frame. If the master is to slow with
enabling its receiver then he will not receive the response correctly.
CONFIG_MB_FUNC_HANDLERS_MAX - Maximum number of Modbus functions codes the
protocol stack should support. The maximum number of supported Modbus
functions must be greater than the sum of all enabled functions in this
file and custom function handlers. If set to small adding more functions
will fail.
CONFIG_MB_FUNC_OTHER_REP_SLAVEID_BUF - Number of bytes which should be allocated for the Report Slave ID command. This number limits the maximum size of the additional segment in the report slave id function. See eMBSetSlaveID() for more information on how to set this value. It is only used if CONFIG_MB_FUNC_OTHER_REP_SLAVEID_ENABLED is set to 1.
CONFIG_MB_FUNC_OTHER_REP_SLAVEID_ENABLED - If the Report Slave ID function should be enabled.
CONFIG_MB_FUNC_READ_INPUT_ENABLED - If the Read Input Registers function should be enabled.
CONFIG_MB_FUNC_READ_HOLDING_ENABLED - If the Read Holding Registers function should be enabled.
CONFIG_MB_FUNC_WRITE_HOLDING_ENABLED - If the Write Single Register function should be enabled.
CONFIG_MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED - If the Write Multiple registers function should be enabled.
CONFIG_MB_FUNC_READ_COILS_ENABLED - If the Read Coils function should be enabled.
CONFIG_MB_FUNC_WRITE_COIL_ENABLED - If the Write Coils function should be enabled.
CONFIG_MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED - If the Write Multiple Coils function should be enabled.
CONFIG_MB_FUNC_READ_DISCRETE_INPUTS_ENABLED - If the Read Discrete Inputs function should be enabled.
CONFIG_MB_FUNC_READWRITE_HOLDING_ENABLED - If the Read/Write Multiple Registers function should be enabled.
Note
====
The developer of freemodbus, Christian Walter, is still developing Modbus
The developer of FreeModBus, Christian Walter, is still developing Modbus
libraries, although they are now commercial. See
http://www.embedded-solutions.at/ for further information.

View File

@ -29,22 +29,22 @@
*/
/* ----------------------- System includes ----------------------------------*/
#include "stdlib.h"
#include "string.h"
#include <nuttx/config.h>
#include <stdlib.h>
#include <string.h>
/* ----------------------- Platform includes --------------------------------*/
#include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbconfig.h"
#include "mbascii.h"
#include "mbframe.h"
#include "mbcrc.h"
#include "mbport.h"
#if MB_ASCII_ENABLED > 0
#ifdef CONFIG_MB_ASCII_ENABLED
/* ----------------------- Defines ------------------------------------------*/
#define MB_ASCII_DEFAULT_CR '\r' /*!< Default CR character for Modbus ASCII. */
@ -117,7 +117,7 @@ eMBASCIIInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eP
{
eStatus = MB_EPORTERR;
}
else if( xMBPortTimersInit( MB_ASCII_TIMEOUT_SEC * 20000UL ) != TRUE )
else if( xMBPortTimersInit( CONFIG_MB_ASCII_TIMEOUT_SEC * 20000UL ) != TRUE )
{
eStatus = MB_EPORTERR;
}

View File

@ -35,7 +35,7 @@
PR_BEGIN_EXTERN_C
#endif
#if MB_ASCII_ENABLED > 0
#ifdef CONFIG_MB_ASCII_ENABLED
eMBErrorCode eMBASCIIInit( UCHAR slaveAddress, UCHAR ucPort,
ULONG ulBaudRate, eMBParity eParity );
void eMBASCIIStart( void );

View File

@ -29,8 +29,9 @@
*/
/* ----------------------- System includes ----------------------------------*/
#include "stdlib.h"
#include "string.h"
#include <nuttx/config.h>
#include <stdlib.h>
#include <string.h>
/* ----------------------- Platform includes --------------------------------*/
#include "port.h"
@ -39,7 +40,6 @@
#include "mb.h"
#include "mbframe.h"
#include "mbproto.h"
#include "mbconfig.h"
/* ----------------------- Defines ------------------------------------------*/
#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF )
@ -63,7 +63,7 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
/* ----------------------- Start implementation -----------------------------*/
#if MB_FUNC_READ_COILS_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_COILS_ENABLED
eMBException
eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
@ -143,7 +143,7 @@ eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
return eStatus;
}
#if MB_FUNC_WRITE_COIL_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_COIL_ENABLED
eMBException
eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
{
@ -197,7 +197,7 @@ eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
#endif
#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED
eMBException
eMBFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen )
{

View File

@ -17,11 +17,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* ----------------------- System includes ----------------------------------*/
#include "stdlib.h"
#include "string.h"
#include <nuttx/config.h>
#include <stdlib.h>
#include <string.h>
/* ----------------------- Platform includes --------------------------------*/
#include "port.h"
@ -30,7 +29,6 @@
#include "mb.h"
#include "mbframe.h"
#include "mbproto.h"
#include "mbconfig.h"
/* ----------------------- Defines ------------------------------------------*/
#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF )
@ -43,7 +41,7 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
/* ----------------------- Start implementation -----------------------------*/
#if MB_FUNC_READ_COILS_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_COILS_ENABLED
eMBException
eMBFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen )

View File

@ -29,8 +29,9 @@
*/
/* ----------------------- System includes ----------------------------------*/
#include "stdlib.h"
#include "string.h"
#include <nuttx/config.h>
#include <stdlib.h>
#include <string.h>
/* ----------------------- Platform includes --------------------------------*/
#include "port.h"
@ -39,7 +40,6 @@
#include "mb.h"
#include "mbframe.h"
#include "mbproto.h"
#include "mbconfig.h"
/* ----------------------- Defines ------------------------------------------*/
#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0)
@ -71,7 +71,7 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
/* ----------------------- Start implementation -----------------------------*/
#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_HOLDING_ENABLED
eMBException
eMBFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
@ -105,7 +105,7 @@ eMBFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
}
#endif
#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED
eMBException
eMBFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
{
@ -164,7 +164,7 @@ eMBFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
}
#endif
#if MB_FUNC_READ_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_HOLDING_ENABLED
eMBException
eMBFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
@ -229,7 +229,7 @@ eMBFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
#endif
#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READWRITE_HOLDING_ENABLED
eMBException
eMBFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )

View File

@ -29,8 +29,9 @@
*/
/* ----------------------- System includes ----------------------------------*/
#include "stdlib.h"
#include "string.h"
#include <nuttx/config.h>
#include <stdlib.h>
#include <string.h>
/* ----------------------- Platform includes --------------------------------*/
#include "port.h"
@ -39,7 +40,6 @@
#include "mb.h"
#include "mbframe.h"
#include "mbproto.h"
#include "mbconfig.h"
/* ----------------------- Defines ------------------------------------------*/
#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF )
@ -53,8 +53,8 @@
eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
/* ----------------------- Start implementation -----------------------------*/
#if MB_FUNC_READ_INPUT_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_INPUT_ENABLED
eMBException
eMBFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )
{

View File

@ -29,8 +29,9 @@
*/
/* ----------------------- System includes ----------------------------------*/
#include "stdlib.h"
#include "string.h"
#include <nuttx/config.h>
#include <stdlib.h>
#include <string.h>
/* ----------------------- Platform includes --------------------------------*/
#include "port.h"
@ -39,12 +40,11 @@
#include "mb.h"
#include "mbframe.h"
#include "mbproto.h"
#include "mbconfig.h"
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0
#ifdef CONFIG_MB_FUNC_OTHER_REP_SLAVEID_ENABLED
/* ----------------------- Static variables ---------------------------------*/
static UCHAR ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF];
static UCHAR ucMBSlaveID[CONFIG_MB_FUNC_OTHER_REP_SLAVEID_BUF];
static USHORT usMBSlaveIDLen;
/* ----------------------- Start implementation -----------------------------*/
@ -58,7 +58,7 @@ eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning,
/* the first byte and second byte in the buffer is reserved for
* the parameter ucSlaveID and the running flag. The rest of
* the buffer is available for additional data. */
if( usAdditionalLen + 2 < MB_FUNC_OTHER_REP_SLAVEID_BUF )
if( usAdditionalLen + 2 < CONFIG_MB_FUNC_OTHER_REP_SLAVEID_BUF )
{
usMBSlaveIDLen = 0;
ucMBSlaveID[usMBSlaveIDLen++] = ucSlaveID;

View File

@ -29,8 +29,9 @@
*/
/* ----------------------- System includes ----------------------------------*/
#include "stdlib.h"
#include "string.h"
#include <nuttx/config.h>
#include <stdlib.h>
#include <string.h>
/* ----------------------- Platform includes --------------------------------*/
#include "port.h"

View File

@ -29,27 +29,27 @@
*/
/* ----------------------- System includes ----------------------------------*/
#include "stdlib.h"
#include "string.h"
#include <nuttx/config.h>
#include <stdlib.h>
#include <string.h>
/* ----------------------- Platform includes --------------------------------*/
#include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbconfig.h"
#include "mbframe.h"
#include "mbproto.h"
#include "mbfunc.h"
#include "mbport.h"
#if MB_RTU_ENABLED == 1
#ifdef CONFIG_MB_RTU_ENABLED
#include "mbrtu.h"
#endif
#if MB_ASCII_ENABLED == 1
#ifdef CONFIG_MB_ASCII_ENABLED
#include "mbascii.h"
#endif
#if MB_TCP_ENABLED == 1
#ifdef CONFIG_MB_TCP_ENABLED
#include "mbtcp.h"
#endif
@ -92,35 +92,35 @@ BOOL( *pxMBFrameCBTransmitFSMCur ) ( void );
/* An array of Modbus functions handlers which associates Modbus function
* codes with implementing functions.
*/
static xMBFunctionHandler xFuncHandlers[MB_FUNC_HANDLERS_MAX] = {
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0
static xMBFunctionHandler xFuncHandlers[CONFIG_MB_FUNC_HANDLERS_MAX] = {
#ifdef CONFIG_MB_FUNC_OTHER_REP_SLAVEID_ENABLED
{MB_FUNC_OTHER_REPORT_SLAVEID, eMBFuncReportSlaveID},
#endif
#if MB_FUNC_READ_INPUT_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_INPUT_ENABLE
{MB_FUNC_READ_INPUT_REGISTER, eMBFuncReadInputRegister},
#endif
#if MB_FUNC_READ_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_HOLDING_ENABLED
{MB_FUNC_READ_HOLDING_REGISTER, eMBFuncReadHoldingRegister},
#endif
#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED
{MB_FUNC_WRITE_MULTIPLE_REGISTERS, eMBFuncWriteMultipleHoldingRegister},
#endif
#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_HOLDING_ENABLED
{MB_FUNC_WRITE_REGISTER, eMBFuncWriteHoldingRegister},
#endif
#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READWRITE_HOLDING_ENABLED
{MB_FUNC_READWRITE_MULTIPLE_REGISTERS, eMBFuncReadWriteMultipleHoldingRegister},
#endif
#if MB_FUNC_READ_COILS_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_COILS_ENABLED
{MB_FUNC_READ_COILS, eMBFuncReadCoils},
#endif
#if MB_FUNC_WRITE_COIL_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_COIL_ENABLED
{MB_FUNC_WRITE_SINGLE_COIL, eMBFuncWriteCoil},
#endif
#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
#ifdef CONFIG_MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED
{MB_FUNC_WRITE_MULTIPLE_COILS, eMBFuncWriteMultipleCoils},
#endif
#if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0
#ifdef CONFIG_MB_FUNC_READ_DISCRETE_INPUTS_ENABLED
{MB_FUNC_READ_DISCRETE_INPUTS, eMBFuncReadDiscreteInputs},
#endif
};
@ -143,7 +143,7 @@ eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eM
switch ( eMode )
{
#if MB_RTU_ENABLED > 0
#ifdef CONFIG_MB_RTU_ENABLED
case MB_RTU:
pvMBFrameStartCur = eMBRTUStart;
pvMBFrameStopCur = eMBRTUStop;
@ -157,7 +157,7 @@ eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eM
eStatus = eMBRTUInit( ucMBAddress, ucPort, ulBaudRate, eParity );
break;
#endif
#if MB_ASCII_ENABLED > 0
#ifdef CONFIG_MB_ASCII_ENABLED
case MB_ASCII:
pvMBFrameStartCur = eMBASCIIStart;
pvMBFrameStopCur = eMBASCIIStop;
@ -192,7 +192,7 @@ eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eM
return eStatus;
}
#if MB_TCP_ENABLED > 0
#ifdef CONFIG_MB_TCP_ENABLED
eMBErrorCode
eMBTCPInit( USHORT ucTCPPort )
{
@ -233,7 +233,7 @@ eMBRegisterCB( UCHAR ucFunctionCode, pxMBFunctionHandler pxHandler )
ENTER_CRITICAL_SECTION( );
if( pxHandler != NULL )
{
for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
for( i = 0; i < CONFIG_MB_FUNC_HANDLERS_MAX; i++ )
{
if( ( xFuncHandlers[i].pxHandler == NULL ) ||
( xFuncHandlers[i].pxHandler == pxHandler ) )
@ -243,11 +243,11 @@ eMBRegisterCB( UCHAR ucFunctionCode, pxMBFunctionHandler pxHandler )
break;
}
}
eStatus = ( i != MB_FUNC_HANDLERS_MAX ) ? MB_ENOERR : MB_ENORES;
eStatus = ( i != CONFIG_MB_FUNC_HANDLERS_MAX ) ? MB_ENOERR : MB_ENORES;
}
else
{
for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
for( i = 0; i < CONFIG_MB_FUNC_HANDLERS_MAX; i++ )
{
if( xFuncHandlers[i].ucFunctionCode == ucFunctionCode )
{
@ -371,7 +371,7 @@ eMBPoll( void )
case EV_EXECUTE:
ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
eException = MB_EX_ILLEGAL_FUNCTION;
for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
for( i = 0; i < CONFIG_MB_FUNC_HANDLERS_MAX; i++ )
{
/* No more function handlers registered. Abort. */
if( xFuncHandlers[i].ucFunctionCode == 0 )
@ -396,9 +396,9 @@ eMBPoll( void )
ucMBFrame[usLength++] = ( UCHAR )( ucFunctionCode | MB_FUNC_ERROR );
ucMBFrame[usLength++] = eException;
}
if( ( eMBCurrentMode == MB_ASCII ) && MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS )
if( ( eMBCurrentMode == MB_ASCII ) && CONFIG_MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS )
{
vMBPortTimersDelay( MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS );
vMBPortTimersDelay( CONFIG_MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS );
}
eStatus = peMBFrameSendCur( ucMBAddress, ucMBFrame, usLength );
}

75
apps/modbus/nuttx/port.h Normal file
View File

@ -0,0 +1,75 @@
/*
* FreeModbus Libary: Linux Port
* Copyright (C) 2006 Christian Walter <wolti@sil.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* File: $Id: port.h,v 1.1 2006/08/01 20:58:49 wolti Exp $
*/
#ifndef _PORT_H
#define _PORT_H
#include <assert.h>
#define INLINE
#define PR_BEGIN_EXTERN_C extern "C" {
#define PR_END_EXTERN_C }
#ifdef __cplusplus
PR_BEGIN_EXTERN_C
#endif
/* ----------------------- Defines ------------------------------------------*/
#define ENTER_CRITICAL_SECTION( ) vMBPortEnterCritical()
#define EXIT_CRITICAL_SECTION( ) vMBPortExitCritical()
#define MB_PORT_HAS_CLOSE 1
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* ----------------------- Type definitions ---------------------------------*/
typedef enum
{
MB_LOG_ERROR = 0,
MB_LOG_WARN = 1,
MB_LOG_INFO = 2,
MB_LOG_DEBUG = 3
} eMBPortLogLevel;
typedef char BOOL;
typedef unsigned char UCHAR;
typedef char CHAR;
typedef unsigned short USHORT;
typedef short SHORT;
typedef unsigned long ULONG;
typedef long LONG;
/* ----------------------- Function prototypes ------------------------------*/
void vMBPortEnterCritical( void );
void vMBPortExitCritical( void );
void vMBPortLog( eMBPortLogLevel eLevel, const CHAR * szModule,
const CHAR * szFmt, ... );
void vMBPortTimerPoll( );
BOOL xMBPortSerialPoll( );
BOOL xMBPortSerialSetTimeout( ULONG dwTimeoutMs );
#ifdef __cplusplus
PR_END_EXTERN_C
#endif
#endif

View File

@ -0,0 +1,72 @@
/*
* FreeModbus Libary: Linux Port
* Copyright (C) 2006 Christian Walter <wolti@sil.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* File: $Id: portevent.c,v 1.1 2006/08/01 20:58:49 wolti Exp $
*/
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
/* ----------------------- Variables ----------------------------------------*/
static eMBEventType eQueuedEvent;
static BOOL xEventInQueue;
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortEventInit( void )
{
xEventInQueue = FALSE;
return TRUE;
}
BOOL
xMBPortEventPost( eMBEventType eEvent )
{
xEventInQueue = TRUE;
eQueuedEvent = eEvent;
return TRUE;
}
BOOL
xMBPortEventGet( eMBEventType * eEvent )
{
BOOL xEventHappened = FALSE;
if( xEventInQueue )
{
*eEvent = eQueuedEvent;
xEventInQueue = FALSE;
xEventHappened = TRUE;
}
else
{
/* Poll the serial device. The serial device timeouts if no
* characters have been received within for t3.5 during an
* active transmission or if nothing happens within a specified
* amount of time. Both timeouts are configured from the timer
* init functions.
*/
( void )xMBPortSerialPoll( );
/* Check if any of the timers have expired. */
vMBPortTimerPoll( );
}
return xEventHappened;
}

View File

@ -0,0 +1,102 @@
/*
* FreeModbus Libary: Linux Port
* Copyright (C) 2006 Christian Walter <wolti@sil.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* File: $Id: portother.c,v 1.1 2006/08/01 20:58:49 wolti Exp $
*/
/* ----------------------- Standard includes --------------------------------*/
#include <nuttx/config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
/* ----------------------- Defines ------------------------------------------*/
#define NELEMS( x ) ( sizeof( ( x ) )/sizeof( ( x )[0] ) )
/* ----------------------- Static variables ---------------------------------*/
static FILE *fLogFile = NULL;
static eMBPortLogLevel eLevelMax = MB_LOG_DEBUG;
static pthread_mutex_t xLock = PTHREAD_MUTEX_INITIALIZER;
/* ----------------------- Start implementation -----------------------------*/
void
vMBPortLogLevel( eMBPortLogLevel eNewLevelMax )
{
eLevelMax = eNewLevelMax;
}
void
vMBPortLogFile( FILE * fNewLogFile )
{
fLogFile = fNewLogFile;
}
void
vMBPortLog( eMBPortLogLevel eLevel, const CHAR * szModule, const CHAR * szFmt, ... )
{
CHAR szBuf[512];
int i;
va_list args;
FILE *fOutput = fLogFile == NULL ? stderr : fLogFile;
static const char *arszLevel2Str[] = { "ERROR", "WARN", "INFO", "DEBUG" };
i = snprintf( szBuf, NELEMS( szBuf ), "%s: %s: ", arszLevel2Str[eLevel], szModule );
if( i != 0 )
{
va_start( args, szFmt );
i += vsnprintf( &szBuf[i], NELEMS( szBuf ) - i, szFmt, args );
va_end( args );
}
if( i != 0 )
{
if( eLevel <= eLevelMax )
{
fputs( szBuf, fOutput );
}
}
}
void
vMBPortEnterCritical( void )
{
if( pthread_mutex_lock( &xLock ) != 0 )
{
vMBPortLog( MB_LOG_ERROR, "OTHER", "Locking primitive failed: %s\n", strerror( errno ) );
}
}
void
vMBPortExitCritical( void )
{
if( pthread_mutex_unlock( &xLock ) != 0 )
{
vMBPortLog( MB_LOG_ERROR, "OTHER", "Locking primitive failed: %s\n", strerror( errno ) );
}
}

View File

@ -0,0 +1,352 @@
/*
* FreeModbus Libary: Linux Port
* Copyright (C) 2006 Christian Walter <wolti@sil.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* File: $Id: portserial.c,v 1.3 2006/10/12 08:35:34 wolti Exp $
*/
/* ----------------------- Standard includes --------------------------------*/
#include <nuttx/config.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
/* ----------------------- Defines -----------------------------------------*/
#ifdef CONFIG_MB_ASCII_ENABLED
#define BUF_SIZE 513 /* must hold a complete ASCII frame. */
#else
#define BUF_SIZE 256 /* must hold a complete RTU frame. */
#endif
/* ----------------------- Static variables ---------------------------------*/
static int iSerialFd = -1;
static BOOL bRxEnabled;
static BOOL bTxEnabled;
static ULONG ulTimeoutMs;
static UCHAR ucBuffer[BUF_SIZE];
static int uiRxBufferPos;
static int uiTxBufferPos;
static struct termios xOldTIO;
/* ----------------------- Function prototypes ------------------------------*/
static BOOL prvbMBPortSerialRead( UCHAR * pucBuffer, USHORT usNBytes, USHORT * usNBytesRead );
static BOOL prvbMBPortSerialWrite( UCHAR * pucBuffer, USHORT usNBytes );
/* ----------------------- Begin implementation -----------------------------*/
void
vMBPortSerialEnable( BOOL bEnableRx, BOOL bEnableTx )
{
/* it is not allowed that both receiver and transmitter are enabled. */
assert( !bEnableRx || !bEnableTx );
if( bEnableRx )
{
( void )tcflush( iSerialFd, TCIFLUSH );
uiRxBufferPos = 0;
bRxEnabled = TRUE;
}
else
{
bRxEnabled = FALSE;
}
if( bEnableTx )
{
bTxEnabled = TRUE;
uiTxBufferPos = 0;
}
else
{
bTxEnabled = FALSE;
}
}
BOOL
xMBPortSerialInit( UCHAR ucPort, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
CHAR szDevice[16];
BOOL bStatus = TRUE;
struct termios xNewTIO;
speed_t xNewSpeed;
snprintf( szDevice, 16, "/dev/ttyS%d", ucPort );
if( ( iSerialFd = open( szDevice, O_RDWR | O_NOCTTY ) ) < 0 )
{
vMBPortLog( MB_LOG_ERROR, "SER-INIT", "Can't open serial port %s: %s\n", szDevice,
strerror( errno ) );
}
else if( tcgetattr( iSerialFd, &xOldTIO ) != 0 )
{
vMBPortLog( MB_LOG_ERROR, "SER-INIT", "Can't get settings from port %s: %s\n", szDevice,
strerror( errno ) );
}
else
{
bzero( &xNewTIO, sizeof( struct termios ) );
xNewTIO.c_iflag |= IGNBRK | INPCK;
xNewTIO.c_cflag |= CREAD | CLOCAL;
switch ( eParity )
{
case MB_PAR_NONE:
break;
case MB_PAR_EVEN:
xNewTIO.c_cflag |= PARENB;
break;
case MB_PAR_ODD:
xNewTIO.c_cflag |= PARENB | PARODD;
break;
default:
bStatus = FALSE;
}
switch ( ucDataBits )
{
case 8:
xNewTIO.c_cflag |= CS8;
break;
case 7:
xNewTIO.c_cflag |= CS7;
break;
default:
bStatus = FALSE;
}
switch ( ulBaudRate )
{
case 9600:
xNewSpeed = B9600;
break;
case 19200:
xNewSpeed = B19200;
break;
case 38400:
xNewSpeed = B38400;
break;
case 57600:
xNewSpeed = B57600;
break;
case 115200:
xNewSpeed = B115200;
break;
default:
bStatus = FALSE;
}
if( bStatus )
{
if( cfsetispeed( &xNewTIO, xNewSpeed ) != 0 )
{
vMBPortLog( MB_LOG_ERROR, "SER-INIT", "Can't set baud rate %ld for port %s: %s\n",
ulBaudRate, strerror( errno ) );
}
else if( cfsetospeed( &xNewTIO, xNewSpeed ) != 0 )
{
vMBPortLog( MB_LOG_ERROR, "SER-INIT", "Can't set baud rate %ld for port %s: %s\n",
ulBaudRate, szDevice, strerror( errno ) );
}
else if( tcsetattr( iSerialFd, TCSANOW, &xNewTIO ) != 0 )
{
vMBPortLog( MB_LOG_ERROR, "SER-INIT", "Can't set settings for port %s: %s\n",
szDevice, strerror( errno ) );
}
else
{
vMBPortSerialEnable( FALSE, FALSE );
bStatus = TRUE;
}
}
}
return bStatus;
}
BOOL
xMBPortSerialSetTimeout( ULONG ulNewTimeoutMs )
{
if( ulNewTimeoutMs > 0 )
{
ulTimeoutMs = ulNewTimeoutMs;
}
else
{
ulTimeoutMs = 1;
}
return TRUE;
}
void
vMBPortClose( void )
{
if( iSerialFd != -1 )
{
( void )tcsetattr( iSerialFd, TCSANOW, &xOldTIO );
( void )close( iSerialFd );
iSerialFd = -1;
}
}
BOOL
prvbMBPortSerialRead( UCHAR * pucBuffer, USHORT usNBytes, USHORT * usNBytesRead )
{
BOOL bResult = TRUE;
ssize_t res;
fd_set rfds;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 50000;
FD_ZERO( &rfds );
FD_SET( iSerialFd, &rfds );
/* Wait until character received or timeout. Recover in case of an
* interrupted read system call. */
do
{
if( select( iSerialFd + 1, &rfds, NULL, NULL, &tv ) == -1 )
{
if( errno != EINTR )
{
bResult = FALSE;
}
}
else if( FD_ISSET( iSerialFd, &rfds ) )
{
if( ( res = read( iSerialFd, pucBuffer, usNBytes ) ) == -1 )
{
bResult = FALSE;
}
else
{
*usNBytesRead = ( USHORT ) res;
break;
}
}
else
{
*usNBytesRead = 0;
break;
}
}
while( bResult == TRUE );
return bResult;
}
BOOL
prvbMBPortSerialWrite( UCHAR * pucBuffer, USHORT usNBytes )
{
ssize_t res;
size_t left = ( size_t ) usNBytes;
size_t done = 0;
while( left > 0 )
{
if( ( res = write( iSerialFd, pucBuffer + done, left ) ) == -1 )
{
if( errno != EINTR )
{
break;
}
/* call write again because of interrupted system call. */
continue;
}
done += res;
left -= res;
}
return left == 0 ? TRUE : FALSE;
}
BOOL
xMBPortSerialPoll( )
{
BOOL bStatus = TRUE;
USHORT usBytesRead;
int i;
while( bRxEnabled )
{
if( prvbMBPortSerialRead( &ucBuffer[0], BUF_SIZE, &usBytesRead ) )
{
if( usBytesRead == 0 )
{
/* timeout with no bytes. */
break;
}
else if( usBytesRead > 0 )
{
for( i = 0; i < usBytesRead; i++ )
{
/* Call the modbus stack and let him fill the buffers. */
( void )pxMBFrameCBByteReceived( );
}
uiRxBufferPos = 0;
}
}
else
{
vMBPortLog( MB_LOG_ERROR, "SER-POLL", "read failed on serial device: %s\n",
strerror( errno ) );</