Example of how to handle the Modbus Slave RTU protocol using the mbed RTOS. This example can also be used as reference to implement other slow serial protocols.

Dependencies:   MessageQueue ModbusSlaveRTU SerialPortHandler mbed-rtos mbed

Committer:
gabrielrivas
Date:
Wed Jan 21 03:00:29 2015 +0000
Revision:
1:544f5f721159
Parent:
0:220ae68e7dd4
Added timer based synchronization to the receiving side tasks.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gabrielrivas 0:220ae68e7dd4 1 #include "mbed.h"
gabrielrivas 0:220ae68e7dd4 2 #include "rtos.h"
gabrielrivas 0:220ae68e7dd4 3 #include "ModbusSlaveRTU.h"
gabrielrivas 0:220ae68e7dd4 4 #include "MessageQueue.h"
gabrielrivas 0:220ae68e7dd4 5 #include "SerialPortHandler.h"
gabrielrivas 0:220ae68e7dd4 6
gabrielrivas 0:220ae68e7dd4 7 DigitalOut led(LED1);
gabrielrivas 0:220ae68e7dd4 8 Serial pc(SERIAL_TX, SERIAL_RX);
gabrielrivas 0:220ae68e7dd4 9 MessageQueue<uint8_t> txQueue(64);
gabrielrivas 0:220ae68e7dd4 10 MessageQueue<uint8_t> rxQueue(64);
gabrielrivas 0:220ae68e7dd4 11 SerialPortHandler sph(&pc, &txQueue, &rxQueue);
gabrielrivas 1:544f5f721159 12 Timer receiveTimer;
gabrielrivas 1:544f5f721159 13 bool isReceiveTimerInitialized = false;
gabrielrivas 0:220ae68e7dd4 14 ModbusSlaveRTU* mbus;
gabrielrivas 0:220ae68e7dd4 15 Thread* modbus_process_thread;
gabrielrivas 0:220ae68e7dd4 16 Thread* data_send_thread;
gabrielrivas 1:544f5f721159 17 Thread* receive_timer_check_thread;
gabrielrivas 0:220ae68e7dd4 18
gabrielrivas 0:220ae68e7dd4 19 uint8_t cRegs[] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0};
gabrielrivas 0:220ae68e7dd4 20 uint8_t inRegs[] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0};
gabrielrivas 0:220ae68e7dd4 21 uint8_t hRegs[] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0};
gabrielrivas 0:220ae68e7dd4 22
gabrielrivas 0:220ae68e7dd4 23 ThreadSafeArray_t hR;
gabrielrivas 0:220ae68e7dd4 24 ThreadSafeArray_t cR;
gabrielrivas 0:220ae68e7dd4 25 ThreadSafeArray_t iR;
gabrielrivas 0:220ae68e7dd4 26
gabrielrivas 0:220ae68e7dd4 27 void rx_interrupt(void);
gabrielrivas 0:220ae68e7dd4 28
gabrielrivas 0:220ae68e7dd4 29 void modbus_process (void const *args) {
gabrielrivas 0:220ae68e7dd4 30
gabrielrivas 0:220ae68e7dd4 31 while (true) {
gabrielrivas 0:220ae68e7dd4 32 mbus->FSM();
gabrielrivas 0:220ae68e7dd4 33 Thread::wait(10);
gabrielrivas 0:220ae68e7dd4 34 }
gabrielrivas 0:220ae68e7dd4 35 }
gabrielrivas 0:220ae68e7dd4 36
gabrielrivas 0:220ae68e7dd4 37 void data_send_process(void const *args)
gabrielrivas 0:220ae68e7dd4 38 {
gabrielrivas 0:220ae68e7dd4 39 while (true) {
gabrielrivas 0:220ae68e7dd4 40 if (!txQueue.isEmpty())
gabrielrivas 0:220ae68e7dd4 41 {
gabrielrivas 0:220ae68e7dd4 42 sph.transmitPacket();
gabrielrivas 0:220ae68e7dd4 43 txQueue.reset();
gabrielrivas 0:220ae68e7dd4 44 }
gabrielrivas 0:220ae68e7dd4 45 Thread::wait(500);
gabrielrivas 0:220ae68e7dd4 46 }
gabrielrivas 0:220ae68e7dd4 47 }
gabrielrivas 0:220ae68e7dd4 48
gabrielrivas 1:544f5f721159 49 void timer_check(void const *args)
gabrielrivas 1:544f5f721159 50 {
gabrielrivas 1:544f5f721159 51 while(true) {
gabrielrivas 1:544f5f721159 52 if (receiveTimer.read_ms() >= 1) {
gabrielrivas 1:544f5f721159 53 mbus->trigger();
gabrielrivas 1:544f5f721159 54 isReceiveTimerInitialized = false;
gabrielrivas 1:544f5f721159 55 receiveTimer.reset();
gabrielrivas 1:544f5f721159 56 receiveTimer.stop();
gabrielrivas 1:544f5f721159 57 }
gabrielrivas 1:544f5f721159 58 /*Waits for 5 ms*/
gabrielrivas 1:544f5f721159 59 Thread::wait(5);
gabrielrivas 1:544f5f721159 60 }
gabrielrivas 1:544f5f721159 61 }
gabrielrivas 1:544f5f721159 62
gabrielrivas 0:220ae68e7dd4 63 int main (void) {
gabrielrivas 0:220ae68e7dd4 64 pc.attach(&rx_interrupt);
gabrielrivas 0:220ae68e7dd4 65
gabrielrivas 0:220ae68e7dd4 66 hR.length = 20;
gabrielrivas 0:220ae68e7dd4 67 hR.data = hRegs;
gabrielrivas 0:220ae68e7dd4 68
gabrielrivas 0:220ae68e7dd4 69 cR.length = 20;
gabrielrivas 0:220ae68e7dd4 70 cR.data = cRegs;
gabrielrivas 0:220ae68e7dd4 71
gabrielrivas 0:220ae68e7dd4 72 iR.length = 20;
gabrielrivas 0:220ae68e7dd4 73 iR.data = inRegs;
gabrielrivas 0:220ae68e7dd4 74
gabrielrivas 0:220ae68e7dd4 75 mbus = new ModbusSlaveRTU(0x01, &txQueue, &rxQueue, &cR, &iR, &hR);
gabrielrivas 0:220ae68e7dd4 76 modbus_process_thread = new Thread(modbus_process);
gabrielrivas 0:220ae68e7dd4 77 data_send_thread= new Thread(data_send_process);
gabrielrivas 1:544f5f721159 78 receive_timer_check_thread = new Thread(timer_check);
gabrielrivas 0:220ae68e7dd4 79 while(true)
gabrielrivas 0:220ae68e7dd4 80 {
gabrielrivas 0:220ae68e7dd4 81 Thread::wait(1000);
gabrielrivas 0:220ae68e7dd4 82 led = !led;
gabrielrivas 0:220ae68e7dd4 83 }
gabrielrivas 0:220ae68e7dd4 84 }
gabrielrivas 0:220ae68e7dd4 85
gabrielrivas 0:220ae68e7dd4 86 void rx_interrupt(void) {
gabrielrivas 1:544f5f721159 87 if (!isReceiveTimerInitialized)
gabrielrivas 1:544f5f721159 88 {
gabrielrivas 1:544f5f721159 89 isReceiveTimerInitialized = true;
gabrielrivas 1:544f5f721159 90 receiveTimer.start();
gabrielrivas 1:544f5f721159 91 }
gabrielrivas 1:544f5f721159 92 else
gabrielrivas 1:544f5f721159 93 {
gabrielrivas 1:544f5f721159 94 receiveTimer.reset();
gabrielrivas 1:544f5f721159 95 }
gabrielrivas 0:220ae68e7dd4 96 sph.receivePacket();
gabrielrivas 0:220ae68e7dd4 97 return;
gabrielrivas 0:220ae68e7dd4 98 }