Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Figure 7-1 shows a flow diagram of receive model.


Panel
borderWidth0
titleFigure 7-1 - µC/Modbus Rx Tasking Model.

Image Added


Panel
bgColor#f0f0f0

(1) µC/Modbus uses a single task to receive packets from any channel. The ‘Modbus Rx Task’ simply waits for a Modbus packet from any channel. Assuming µC/OS-II as the RTOS, a message queue is used for this purpose. For µC/OS-III, the message queue is built into the task. When a packet is received, a pointer to the channel that received the packet is posted to the message queue indicating to the ‘Modbus Rx Task’ which channel received the packet. The ‘Modbus Rx Task’ then simply parses the packet and formulates a response that will be forwarded appropriately.

(2) We assume that byte reception from a UART is interrupt driven. Received bytes are placed in a receive buffer until a complete packet is received. If the channel is configured for Modbus ASCII, an end of packet is signaled by a line feed character (i.e. 0x0A). If the channel is configured for Modbus RTU then the end of a packet is signaled by not receiving bytes for at least the time it takes to send 3.5 bytes (see Modbus RTU specification).

(3) Assuming Modbus ASCII, the end of a packet is signaled by calling MB_OS_RxSignal() and specifying a pointer to the channel on which a packet was received.

(4) If your product needs to support the Modbus RTU mode, you will need to provide a timer that interrupts the CPU in order to keep track of end of packets. Basically, when bytes are received on a channel, an RTU counter for that channel is reset to a value based on the baud rate of the channel (see the table below).

Baud Rate

RTU Timeout

(Time for 3.5 Bytes)

RTU Timeout

(Counts at 1 KHz)

9,600

3646 µS

5

19,200

1823 µS

3

38,400

911 µS

2

76,800

456 µS

2

115,200

304 µS

2

256,000

137 µS

2

For example, if a channel is configured for 19,200 Baud then, an end of packet (in RTU mode) is assumed to occur when no bytes are received after 1800 µS (microseconds). If your RTU timer is setup to interrupt every millisecond then you would need roughly two such interrupts before you conclude that a packet was received. We decided to assume that a packet is received after at least the time it would take to receive 5.0 bytes instead of 3.5 bytes. Also, because of the asynchronous feature of the timer with respect to received bytes, we decided to count at least TWO RTU interrupts to conclude that a packet was received.

You can have better granularity for the timeout if you increase the RTU timer interrupt rate. However, this also increases the amount of overhead you are placing on your CPU.

(5) When the RTU timer interrupt occurs, the timeout counter for each of the channels that are configured for RTU mode are decremented. When a counter reaches 0, a signal is set to the ‘Modbus Rx Task’ for that channel. This tells the ‘Modbus Rx Task’ that a packet was received on that channel and needs to be processed. The signal is also performed by calling MB_OS_RxSignal().

In order to provide the RTOS functionality described above, you need to define three functions in a file called MB_OS.C:

MB_OS_Init()

MB_OS_Exit()

MB_OS_RxSignal()

MB_OS_RxWait()



MB_OS_Init()

This function is called by µC/Modbusto initialize the RTOS interface for the RTOS you are using. You would typically create the ‘Modbus Rx Task’ and setup the mechanism needed to signal this task when a packet is received or an RTU timeout occurred for the channel.

...