A simple wireless protocol to let my examples communicate each other. ssWi stands for Shared Slotted Wireless protocol

Dependents:   rover_car rover_pc supervisor watering_unit ... more

This library aims at implementing a simple communication protocol among nodes, abstracting from the hardware. The name ssWi stands for Shared Slotted Wireless. Wireless is part of the name, even though the library abstracts from the hardware, as the first version was entirely focused on the XBee modules and then the name has not been changed.

The communication channel is represented by ssWiChannel, an abstract class which models the channel that the transceivers access to. The concrete classes must implement the functions: init, read and write. The protocol automatically sends and receives data through the selected channel, exploiting the operting system timers. Addresses are not considered as the communication lays on broadcast transmissions.

The protocol provides the ssWiPort abstraction which is like memory areas shared among all the connected nodes. Reading from one port lets the node retrieve the last written value from the other nodes. Writing on one port means sending such value to other nodes.

Objects instantiated from ssWiSocket are the interface for allowing nodes to access the protocol ports.

/media/uploads/mariob/scheme.png

TODO:

  • improve the parsing of the received messages
  • communication tests with many nodes (so far, only 2 nodes have been tested)
Committer:
mariob
Date:
Wed Mar 06 08:21:41 2013 +0000
Revision:
13:69ff47a83260
Parent:
12:f35f9195d598
Child:
15:fb0f6cbc0ed5
added comments; MB

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mariob 13:69ff47a83260 1 /** \file ssWi.cpp
mariob 13:69ff47a83260 2 * \brief implementation of the internal functions for mananing the protocol
mariob 13:69ff47a83260 3 *
mariob 13:69ff47a83260 4 */
mariob 13:69ff47a83260 5
mariob 13:69ff47a83260 6 #include "ssWiChannel.hpp"
mariob 4:dbbf82c966c2 7 #include "ssWiPort.hpp"
mariob 4:dbbf82c966c2 8 #include "ssWi.hpp"
mariob 4:dbbf82c966c2 9
mariob 4:dbbf82c966c2 10 #include "mbed.h"
mariob 4:dbbf82c966c2 11 #include "rtos.h"
mariob 4:dbbf82c966c2 12
mariob 4:dbbf82c966c2 13 #include <map>
mariob 4:dbbf82c966c2 14
mariob 13:69ff47a83260 15
mariob 13:69ff47a83260 16
mariob 13:69ff47a83260 17 /** \brief first byte of the header
mariob 13:69ff47a83260 18 *
mariob 13:69ff47a83260 19 * The header is composed of 3 bytes
mariob 13:69ff47a83260 20 */
mariob 13:69ff47a83260 21 #define START_0 255
mariob 13:69ff47a83260 22
mariob 13:69ff47a83260 23 /** \brief second byte of the header
mariob 13:69ff47a83260 24 *
mariob 13:69ff47a83260 25 * The header is composed of 3 bytes
mariob 13:69ff47a83260 26 */
mariob 13:69ff47a83260 27 #define START_1 130
mariob 13:69ff47a83260 28
mariob 13:69ff47a83260 29 /** \brief third byte of the header
mariob 13:69ff47a83260 30 *
mariob 13:69ff47a83260 31 * The header is composed of 3 bytes
mariob 13:69ff47a83260 32 */
mariob 13:69ff47a83260 33 #define START_2 255
mariob 13:69ff47a83260 34
mariob 13:69ff47a83260 35
mariob 13:69ff47a83260 36 /**
mariob 13:69ff47a83260 37 * dimension of the buffers used by the sender and receiver procedure
mariob 13:69ff47a83260 38 */
mariob 4:dbbf82c966c2 39 #define INTERNAL_BUFFER_SIZE 100
mariob 4:dbbf82c966c2 40
mariob 13:69ff47a83260 41
mariob 13:69ff47a83260 42 /** \brief channel abstraction
mariob 13:69ff47a83260 43 *
mariob 13:69ff47a83260 44 * This object represent the communication channel that can be
mariob 13:69ff47a83260 45 * different means
mariob 13:69ff47a83260 46 */
mariob 13:69ff47a83260 47 ssWiChannel* channel = NULL;
mariob 13:69ff47a83260 48
mariob 13:69ff47a83260 49 /** \brief serialize read and write operations
mariob 13:69ff47a83260 50 *
mariob 13:69ff47a83260 51 * simultaneous multiple accesses to the mean are avoided
mariob 13:69ff47a83260 52 */
mariob 13:69ff47a83260 53 Mutex mutexChannel;
mariob 13:69ff47a83260 54
mariob 13:69ff47a83260 55 /** \brief set of registered communication ports
mariob 13:69ff47a83260 56 *
mariob 13:69ff47a83260 57 */
mariob 13:69ff47a83260 58 std::map<int, ssWiPort> ports;
mariob 13:69ff47a83260 59
mariob 13:69ff47a83260 60 /** \brief transmission rate
mariob 13:69ff47a83260 61 *
mariob 13:69ff47a83260 62 */
mariob 13:69ff47a83260 63 int TXRate;
mariob 13:69ff47a83260 64
mariob 13:69ff47a83260 65 /** \brief reading rate
mariob 13:69ff47a83260 66 *
mariob 13:69ff47a83260 67 */
mariob 13:69ff47a83260 68 int RXRate;
mariob 13:69ff47a83260 69
mariob 13:69ff47a83260 70
mariob 13:69ff47a83260 71
mariob 13:69ff47a83260 72 #ifndef NO_THREAD
mariob 13:69ff47a83260 73
mariob 4:dbbf82c966c2 74 Thread* sender;
mariob 4:dbbf82c966c2 75 Thread* receiver;
mariob 4:dbbf82c966c2 76
mariob 4:dbbf82c966c2 77 void threadSender (void const* arg);
mariob 4:dbbf82c966c2 78 void threadReceiver (void const* arg);
mariob 4:dbbf82c966c2 79
mariob 4:dbbf82c966c2 80 bool ssWi_init (ssWiChannel* c, int rateTX, int rateRX)
mariob 4:dbbf82c966c2 81 {
mariob 4:dbbf82c966c2 82 if (channel!=NULL)
mariob 4:dbbf82c966c2 83 return false;
mariob 8:354a0e3087c1 84 TXRate = 1000.0/rateTX;
mariob 8:354a0e3087c1 85 RXRate = 1000.0/rateRX;
mariob 4:dbbf82c966c2 86 mutexChannel.lock();
mariob 4:dbbf82c966c2 87 channel = c;
mariob 4:dbbf82c966c2 88 sender = new Thread(threadSender);
mariob 4:dbbf82c966c2 89 receiver = new Thread(threadReceiver);
mariob 4:dbbf82c966c2 90 mutexChannel.unlock();
mariob 4:dbbf82c966c2 91 return true;
mariob 4:dbbf82c966c2 92 }
mariob 4:dbbf82c966c2 93
mariob 4:dbbf82c966c2 94 void threadSender (void const* arg)
mariob 4:dbbf82c966c2 95 {
mariob 9:b5b5d0533fa6 96 char buffer[50];
mariob 4:dbbf82c966c2 97 while(true) {
mariob 9:b5b5d0533fa6 98 int n = 3;
mariob 9:b5b5d0533fa6 99 int numFrames = 0;
mariob 9:b5b5d0533fa6 100 for (std::map<int, ssWiPort>::iterator it = ports.begin(); it!=ports.end(); it++) {
mariob 4:dbbf82c966c2 101 if ((*it).second.isModified()) {
mariob 4:dbbf82c966c2 102 buffer[n++] = (*it).first;
mariob 4:dbbf82c966c2 103 PortValue tmp = (*it).second.getTXValue();
mariob 5:0b0ca40aeb81 104 memcpy(&buffer[n], &tmp, sizeof(PortValue));
mariob 5:0b0ca40aeb81 105 n += sizeof(PortValue);
mariob 9:b5b5d0533fa6 106 //printf("Write[%d] = %d\n\r", (*it).first, tmp);
mariob 9:b5b5d0533fa6 107 numFrames++;
mariob 4:dbbf82c966c2 108 }
mariob 4:dbbf82c966c2 109 }
mariob 9:b5b5d0533fa6 110 if (numFrames>0) {
mariob 9:b5b5d0533fa6 111 buffer[0] = START_0;
mariob 9:b5b5d0533fa6 112 buffer[1] = START_1;
mariob 9:b5b5d0533fa6 113 buffer[2] = START_2;
mariob 4:dbbf82c966c2 114 mutexChannel.lock();
mariob 4:dbbf82c966c2 115 channel->write(buffer, n);
mariob 4:dbbf82c966c2 116 mutexChannel.unlock();
mariob 11:4ad44d62d510 117 /*
mariob 9:b5b5d0533fa6 118 printf("W(%d): ", n);
mariob 8:354a0e3087c1 119 for(int k=0; k<n; k++)
mariob 8:354a0e3087c1 120 printf("%d ", buffer[k]);
mariob 8:354a0e3087c1 121 printf("\n\r");
mariob 11:4ad44d62d510 122 */
mariob 4:dbbf82c966c2 123 }
mariob 4:dbbf82c966c2 124 Thread::wait(TXRate);
mariob 4:dbbf82c966c2 125 }
mariob 4:dbbf82c966c2 126 }
mariob 4:dbbf82c966c2 127
mariob 4:dbbf82c966c2 128 void threadReceiver (void const* arg)
mariob 4:dbbf82c966c2 129 {
mariob 9:b5b5d0533fa6 130 char buffer[50];
mariob 9:b5b5d0533fa6 131
mariob 4:dbbf82c966c2 132 while(true) {
mariob 4:dbbf82c966c2 133 mutexChannel.lock();
mariob 5:0b0ca40aeb81 134 int n = channel->read(buffer);
mariob 4:dbbf82c966c2 135 mutexChannel.unlock();
mariob 9:b5b5d0533fa6 136
mariob 11:4ad44d62d510 137 /*
mariob 11:4ad44d62d510 138 if (n>0) {
mariob 11:4ad44d62d510 139 printf("R(%d): ", n);
mariob 11:4ad44d62d510 140 for(int k=0; k<n; k++)
mariob 11:4ad44d62d510 141 printf("%d ", buffer[k]);
mariob 11:4ad44d62d510 142 printf("\n\r");
mariob 11:4ad44d62d510 143 }
mariob 11:4ad44d62d510 144 */
mariob 9:b5b5d0533fa6 145 bool alreadyIn = false;
mariob 9:b5b5d0533fa6 146 for (int i=0; i<(n-2);) {
mariob 9:b5b5d0533fa6 147 bool found = false;
mariob 9:b5b5d0533fa6 148 if (buffer[i]==START_0 && buffer[i+1]==START_1 && buffer[i+2]==START_2) {
mariob 9:b5b5d0533fa6 149 found = true;
mariob 9:b5b5d0533fa6 150 alreadyIn = true;
mariob 9:b5b5d0533fa6 151 i += 3;
mariob 4:dbbf82c966c2 152 }
mariob 9:b5b5d0533fa6 153 if ((found || alreadyIn) && (n-i)>=(sizeof(PortID)+sizeof(PortValue))) {
mariob 9:b5b5d0533fa6 154 PortID port = buffer[i++];
mariob 9:b5b5d0533fa6 155 PortValue value = 0;
mariob 9:b5b5d0533fa6 156 memcpy(&value, &buffer[i], sizeof(PortValue));
mariob 11:4ad44d62d510 157 // printf("Read[%d] = %d\n\r", port, value);
mariob 9:b5b5d0533fa6 158 i += sizeof(PortValue);
mariob 9:b5b5d0533fa6 159 if (ports.find(port)!=ports.end())
mariob 9:b5b5d0533fa6 160 ports[port].setRXValue(value);
mariob 13:69ff47a83260 161 }// else
mariob 13:69ff47a83260 162 // i++;
mariob 4:dbbf82c966c2 163 }
mariob 4:dbbf82c966c2 164 Thread::wait(RXRate);
mariob 4:dbbf82c966c2 165 }
mariob 4:dbbf82c966c2 166 }
mariob 13:69ff47a83260 167 #endif
mariob 13:69ff47a83260 168
mariob 13:69ff47a83260 169
mariob 13:69ff47a83260 170 inline bool ssWi_isActive (PortID port)
mariob 13:69ff47a83260 171 {
mariob 13:69ff47a83260 172 return channel!=NULL && ports.find(port)!=ports.end();
mariob 13:69ff47a83260 173 }
mariob 13:69ff47a83260 174
mariob 13:69ff47a83260 175
mariob 13:69ff47a83260 176 bool ssWi_setPort (PortID port)
mariob 13:69ff47a83260 177 {
mariob 13:69ff47a83260 178 if (channel==NULL)
mariob 13:69ff47a83260 179 return false;
mariob 13:69ff47a83260 180 ports[port];
mariob 13:69ff47a83260 181 return true;
mariob 13:69ff47a83260 182 }
mariob 13:69ff47a83260 183
mariob 13:69ff47a83260 184
mariob 13:69ff47a83260 185 bool ssWi_unsetPort (PortID port)
mariob 13:69ff47a83260 186 {
mariob 13:69ff47a83260 187 if (!ssWi_isActive(port))
mariob 13:69ff47a83260 188 return false;
mariob 13:69ff47a83260 189 ports.erase(port);
mariob 13:69ff47a83260 190 return true;
mariob 13:69ff47a83260 191 }