FreeMODBUS - A Modbus ASCII/RTU and TCP implementation |
latest release v1.5 - 6 June 2010
|
|
This is a simple example showing how to use the Modbus protocol stack. It is nearly the same as the example simple2.c for the FreeRTOS/STR71x demo application with some parts removed for presentation purposes.
In this example we map four 16bit input registers at the register address 1000. The first register counts the number of times the main polling loop was cycled. The second and third registers hold the current RTOS ticks counter and the fourth register holds a constant.
/* ----------------------- Defines ------------------------------------------*/
#define REG_INPUT_START 1000
#define REG_INPUT_NREGS 4
/* ----------------------- Static variables ---------------------------------*/
static unsigned short usRegInputStart = REG_INPUT_START;
static unsigned short usRegInputBuf[REG_INPUT_NREGS];
...
static void
vModbusTask( void *pvParameters )
{
portTickType xLastWakeTime;
/* Select either ASCII or RTU Mode. */
( void )eMBInit( MB_RTU, 0x0A, 38400, MB_PAR_EVEN );
/* Enable the Modbus Protocol Stack. */
( void )eMBEnable( );
for( ;; )
{
/* Call the main polling loop of the Modbus protocol stack. */
( void )eMBPoll( );
/* Application specific actions. Count the number of poll cycles. */
usRegInputBuf[0]++;
/* Hold the current FreeRTOS ticks. */
xLastWakeTime = xTaskGetTickCount( );
usRegInputBuf[1] = ( unsigned portSHORT )( xLastWakeTime >> 16UL );
usRegInputBuf[2] = ( unsigned portSHORT )( xLastWakeTime & 0xFFFFUL );
/* The constant value. */
usRegInputBuf[3] = 33;
}
}
Most of the work is done in the main polling loop. Internally it works by waiting for an event posted to a queue (See footnote [1]). Such a event is for example the reception of a Modbus frame. These events are posted to the event queue by the interrupt driven receiver and transmitter state machines. After a frame is received the FRAME_RECEIVED event is posted and one loop iteration is executed. Following the receive event an EXECUTION event is created internally. Because there is such a special event for the time after frame reception and before the response is sent the current register values can be updated. After execution the resulting frame is transmitted and a FRAME_SENT event is raised.But where does the Modbus stack hold the actual register values? In this case the actual buffer is provided by the callback function eMBRegInputCB. Again the implementation of such a function is quite simple.
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
eMBErrorCode eStatus = MB_ENOERR;
int iRegIndex;
if( ( usAddress >= REG_INPUT_START )
&& ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
{
iRegIndex = ( int )( usAddress - usRegInputStart );
while( usNRegs > 0 )
{
*pucRegBuffer++ =
( unsigned char )( usRegInputBuf[iRegIndex] >> 8 );
*pucRegBuffer++ =
( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF );
iRegIndex++;
usNRegs--;
}
}
else
{
eStatus = MB_ENOREG;
}
return eStatus;
}
Using this code and a Modbus test utility we get the following output in a console window:
Z:\home\wolti\devel\privat\arm\freemodbus\tools>modpoll.exe -m rtu -a 10 -r 10 00 -c 4 -t 3 -b 38400 -d 8 -p even COM4 modpoll - FieldTalk(tm) Modbus(R) Polling Utility Copyright (c) 2002-2004 FOCUS Software Engineering Pty Ltd Getopt Library Copyright (C) 1987-1997 Free Software Foundation, Inc. Protocol configuration: Modbus ASCII Slave configuration: Address = 10, start reference = 1000, count = 4 Serial port configuration: COM4, 9600, 7, 1, even Data type: 16-bit register, input register table Protocol opened successfully. Polling slave (Ctrl-C to stop) ... [1000]: 467 [1001]: 3 [1002]: 18547 [1003]: 33 Polling slave (Ctrl-C to stop) ... [1000]: 470 [1001]: 3 [1002]: 19544 [1003]: 33 Polling slave (Ctrl-C to stop) ...
[1]: Without an operating systems there are normally no queues available. In this case the application would look like our example and the queue receiving and sending functions would be implemented by simple global variables which are set if events are posted to the queue. The queue receive function would check the state of the variables and would return
|
| FreeMODBUS library and web page maintained by Christian Walter [wolti at sil dot at] |
|
| FreeMODBUS is sponsored and provided by embedded solutions |
|
| Low on development resources? Try freelancer and find new skilled people for your projects. |
|