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
main.cpp@1:544f5f721159, 2015-01-21 (annotated)
- 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?
User | Revision | Line number | New 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 | } |