|
|
 |
|
|
 |
Data Provider
Detailed Description
A Data Provider acts as an agent between your Application and the Server Engine.
After instantiating a Server Engine class of any protocol flavour, you have to associate it with a Data Provider by calling addDataTable and passing a pointer to the Data Provider object.
To create an application specific Data Provider derive a new class from MbusDataTableInterface and override the required data access methods.
A minimal Data Provider which realises a Modbus slave with read access to holding registers would be:
|
Classes |
| class | MbusDataTableInterface |
| | This class defines the interface between a Modbus slave Server Engine and your application. Descendants of this class are referred to as Data Providers. More...
|
Data Access Methods for Table 4:00000 (Holding Registers) |
| Data Access Methods to support read and write of output registers (holding registers) in table 4:00000.
This table is accessed by the following Modbus functions:
- Modbus function 16 (10 hex), Preset Multiple Registers/Write Multiple Registers
- Modbus function 3 (03 hex), Read Holding Registers/Read Multiple Registers
- Modbus function 6 (06 hex), Preset Single Register/Write Single Register.
- Modbus function 22 (16 hex), Mask Write Register.
- Modbus function 23 (17 hex), Read/Write Registers.
|
| virtual int | MbusDataTableInterface::readHoldingRegistersTable (int startRef, short regArr[], int refCnt) |
| | Override this method to implement a Data Provider function to read Holding Registers.
|
| virtual int | MbusDataTableInterface::writeHoldingRegistersTable (int startRef, const short regArr[], int refCnt) |
| | Override this method to implement a Data Provider function to write Holding Registers.
|
Data Access Methods for Table 3:00000 (Input Registers) |
| Data Access Methods to support read of input registers in table 3:00000.
This table is accessed by the following Modbus functions:
- Modbus function 4 (04 hex), Read Input Registers.
- Note:
- Input registers cannot be written
|
| virtual int | MbusDataTableInterface::readInputRegistersTable (int startRef, short regArr[], int refCnt) |
| | Override this method to implement a Data Provider function to read Input Registers.
|
Data Access Methods for Table 0:00000 (Coils) |
| Data Access Methods to support read and write of discrete outputs (coils) in table 0:00000.
This table is accessed by the following Modbus functions:
- Modbus function 1 (01 hex), Read Coil Status/Read Coils.
- Modbus function 5 (05 hex), Force Single Coil/Write Coil.
- Modbus function 15 (0F hex), Force Multiple Coils.
|
| virtual int | MbusDataTableInterface::readCoilsTable (int startRef, char bitArr[], int refCnt) |
| | Override this method to implement a Data Provider function to read Coils.
|
| virtual int | MbusDataTableInterface::writeCoilsTable (int startRef, const char bitArr[], int refCnt) |
| | Override this method to implement a Data Provider function to write Coils.
|
Data Access Methods for Table 1:00000 (Input Discretes) |
| Data Access Methods to support read discrete inputs (input status) in table 1:00000.
This table is accessed by the following Modbus functions:
- Modbus function 2 (02 hex), Read Inputs Status/Read Input Discretes.
- Note:
- Input Discretes cannot be written
|
| virtual int | MbusDataTableInterface::readInputDiscretesTable (int startRef, char bitArr[], int refCnt) |
| | Override this method to implement a Data Provider function to read Coils.
|
Data Access Synchronisation Functions |
| Implementation of these functions may only be required in multithreaded applications, if you are running the server loop in a separate thread and in addition require data consistency over a block of Modbus registers.
Data consistency within a single register is always maintained if the code executes on a 16-bit or 32-bit machine, because the CPU is accessing these data types atomically.
|
| virtual void | MbusDataTableInterface::lock () |
| | You can override this method to implement a semaphore locking mechanism to synchronise data access.
|
| virtual void | MbusDataTableInterface::unlock () |
| | You can override this method to implement a semaphore un-locking mechanism to synchronise data access.
|
Auxiliary Functions |
| virtual void | MbusDataTableInterface::timeOutHandler () |
| | Override this method to implement a function to handle master poll time-outs.
|
| virtual char | MbusDataTableInterface::readExceptionStatus () |
| | Override this method to implement a function with reports the eight exception status coils (bits) within the slave device.
|
Function Documentation
| virtual int readHoldingRegistersTable |
( |
int |
startRef, |
|
|
short |
regArr[], |
|
|
int |
refCnt |
|
) |
[virtual, inherited] |
|
|
|
Override this method to implement a Data Provider function to read Holding Registers.
When a slave receives a poll request for the 4:00000 data table he calls this method to retrieve the data.
A simple implementation which holds the application data in an array of shorts (short regData[0x10000]) could be: int readHoldingRegistersTable(int startRef, short regArr[], int refCnt)
{
startRef--;
if (startRef + refCnt > (int) sizeof(regData) / sizeof(short))
return (0);
memcpy(regArr, ®Data[startRef], refCnt * sizeof(short));
return (1);
}
- Parameters:
-
| startRef | Start register (Range: 1 - 0x10000) |
| regArr | Buffer which has to be filled with the reply data |
| refCnt | Number of registers to be retrieved (Range: 0 - 125) |
- Return values:
-
| 1 | Indicate a successful access and that valid reply data is contained in regArr. The Server Engine will reply the data passed in regArr to the master. |
| 0 | Indicate that access has been denied or is out of range. The Server Engine will reply to the master with an exception reply message |
- Required:
- Yes
- Default Implementation:
- Returns 0 which indicates to Server Engine that this address range is unsupported.
|
| virtual int readInputRegistersTable |
( |
int |
startRef, |
|
|
short |
regArr[], |
|
|
int |
refCnt |
|
) |
[virtual, inherited] |
|
|
|
Override this method to implement a Data Provider function to read Input Registers.
When a slave receives a poll request for the 3:00000 data table he calls this method to retrieve the data.
A simple and very common implementation is to map the Input Registers to the same address space than the Holding Registers table:
- Parameters:
-
| startRef | Start register (Range: 1 - 0x10000) |
| regArr | Buffer which has to be filled with the reply data |
| refCnt | Number of registers to be retrieved (Range: 0 - 125) |
- Return values:
-
| 1 | Indicate a successful access and that valid reply data is contained in regArr. The Server Engine will reply the data passed in regArr to the master. |
| 0 | Indicate that access has been denied or is out of range. The Server Engine will reply to the master with an exception reply message |
- Required:
- No
- Default Implementation:
- Returns 0 which indicates to Server Engine that this address range is unsupported.
|
| virtual int readCoilsTable |
( |
int |
startRef, |
|
|
char |
bitArr[], |
|
|
int |
refCnt |
|
) |
[virtual, inherited] |
|
|
|
Override this method to implement a Data Provider function to read Coils.
When a slave receives a poll request for the 0:00000 data table he calls this method to retrieve the data.
A simple implementation which holds the boolean application data in an array of chars (char bitData[2000]) could be: int readCoilsTable(int startRef, char bitArr[], int refCnt)
{
startRef--;
if (startRef + refCnt > (int) sizeof(bitData) / sizeof(char))
return (0);
memcpy(bitArr, &bitData[startRef], refCnt * sizeof(char));
return (1);
}
- Parameters:
-
| startRef | Start register (Range: 1 - 0x10000) |
| bitArr | Buffer which has to be filled with the reply data. Each char represents one coil! |
| refCnt | Number of coils to be retrieved (Range: 0 - 2000) |
- Return values:
-
| 1 | Indicate a successful access and that valid reply data is contained in regArr. The Server Engine will reply the data passed in regArr to the master. |
| 0 | Indicate that access has been denied or is out of range. The Server Engine will reply to the master with an exception reply message |
- Required:
- No
- Default Implementation:
- Returns 0 which indicates to Server Engine that this address range is unsupported.
|
| virtual int readInputDiscretesTable |
( |
int |
startRef, |
|
|
char |
bitArr[], |
|
|
int |
refCnt |
|
) |
[virtual, inherited] |
|
|
|
Override this method to implement a Data Provider function to read Coils.
When a slave receives a poll request for the 0:00000 data table he calls this method to retrieve the data.
A simple and very common implementation is to map the Input Discretes to the same address space than the Coils table:
- Parameters:
-
| startRef | Start register (Range: 1 - 0x10000) |
| bitArr | Buffer which has to be filled with the reply data. Each char repesents one discrete! |
| refCnt | Number of discretes to be retrieved (Range: 0 - 2000) |
- Return values:
-
| 1 | Indicate a successful access and that valid reply data is contained in regArr. The Server Engine will reply the data passed in regArr to the master. |
| 0 | Indicate that access has been denied or is out of range. The Server Engine will reply to the master with an exception reply message |
- Required:
- No
- Default Implementation:
- Returns 0 which indicates to Server Engine that this address range is unsupported.
|
| virtual void lock |
( |
|
) |
[virtual, inherited] |
|
|
|
You can override this method to implement a semaphore locking mechanism to synchronise data access.
This is not needed in single threaded applications but may be necessary in multithreaded applications if you are running the server loop in a separate thread and require data consistency over a block of Modbus registers. Data consistency within a single register is always maintained if the code executes on a 16-bit or 32-bit machine, because the CPU is accessing these data types atomically.
This function is called by the server before calling any data read or write functions.
- Required:
- No
- Default Implementation:
- Empty
|
| virtual void timeOutHandler |
( |
|
) |
[virtual, inherited] |
|
|
|
Override this method to implement a function to handle master poll time-outs.
A master should poll a slave cyclically. If no master is polling within the time-out period this method is called. A slave can take certain actions if the master has lost connection, e.g. go into a fail-safe state.
- Required:
- No
- Default Implementation:
- Empty
|
| virtual int writeHoldingRegistersTable |
( |
int |
startRef, |
|
|
const short |
regArr[], |
|
|
int |
refCnt |
|
) |
[virtual, inherited] |
|
|
|
Override this method to implement a Data Provider function to write Holding Registers.
When a slave receives a write request for the 4:00000 data table he calls this method to pass the data to the application.
A simple implementation which holds the application data in an array of shorts (short regData[0x10000]) could be: int writeHoldingRegistersTable(int startRef, const short regArr[], int refCnt)
{
startRef--;
if (startRef + refCnt > (int) sizeof(regData) / sizeof(short))
return (0);
memcpy(®Data[startRef], regArr, refCnt * sizeof(short));
return (1);
}
- Parameters:
-
| startRef | Start register (Range: 1 - 0x10000) |
| regArr | Buffer which contains the received data |
| refCnt | Number of registers received (Range: 0 - 125) |
- Return values:
-
| 1 | Indicate a successful access. The Server Engine will send a positive reply to the master. |
| 0 | Indicate that access has been denied or is out of range. The Server Engine will reply to the master with an exception reply message |
- Required:
- Yes
- Default Implementation:
- Returns 0 which indicates to Server Engine that this address range is unsupported.
|
| virtual int writeCoilsTable |
( |
int |
startRef, |
|
|
const char |
bitArr[], |
|
|
int |
refCnt |
|
) |
[virtual, inherited] |
|
|
|
Override this method to implement a Data Provider function to write Coils.
When a slave receives a write request for the 0:00000 data table he calls this method to pass the data to the application.
A simple implementation which holds the boolean application data in an array of chars (char bitData[2000]) could be: int writeCoilsTable(int startRef, const char bitArr[], int refCnt)
{
startRef--;
if (startRef + refCnt > (int) sizeof(bitData) / sizeof(char))
return (0);
memcpy(&bitData[startRef], bitArr, refCnt * sizeof(char));
return (1);
}
- Parameters:
-
| startRef | Start register (Range: 1 - 0x10000) |
| bitArr | Buffer which contains the received data. Each char repesents one coil! |
| refCnt | Number of coils received (Range: 0 - 2000) |
- Return values:
-
| 1 | Indicate a successful access. The Server Engine will send a positive reply to the master. |
| 0 | Indicate that access has been denied or is out of range. The Server Engine will reply to the master with an exception reply message |
- Required:
- No
- Default Implementation:
- Returns 0 which indicates to Server Engine that this address range is unsupported.
|
| virtual void unlock |
( |
|
) |
[virtual, inherited] |
|
|
|
You can override this method to implement a semaphore un-locking mechanism to synchronise data access.
This is not needed in single threaded applications but may be necessary in multithreaded applications if you are running the server loop in a separate thread and require data consistency over a block of Modbus registers. Data consistency within a single register is always maintained if the code executes on a 16-bit or 32-bit machine, because the CPU is accessing these data types atomically.
This function is called by the server after calling any data read or write functions.
- Required:
- No
- Default Implementation:
- Empty
|
| virtual char readExceptionStatus |
( |
|
) |
[virtual, inherited] |
|
|
|
Override this method to implement a function with reports the eight exception status coils (bits) within the slave device.
The exception status coils are device specific and usually used to report a device' principal status or a device' major failure codes as a 8-bit word.
- Returns:
- Exception status byte
- Required:
- No
- Default Implementation:
- Returns 0 as exception status byte.
|
|
 |
|