Demonstration of a message queue + memory pool

Committer:
noutram
Date:
Tue Mar 08 20:51:13 2016 +0000
Revision:
2:70084af839d3
Parent:
1:4fb27aea76b2
Child:
3:423191a375dc
text to morse code using a worker thread, a buffer and semaphores

Who changed what in which revision?

UserRevisionLine numberNew contents of line
noutram 0:f916cefba2f4 1 #include "mbed.h"
noutram 0:f916cefba2f4 2 #include "rtos.h"
noutram 2:70084af839d3 3 #include "string.h"
noutram 2:70084af839d3 4 #include <stdio.h>
noutram 2:70084af839d3 5 #include <ctype.h>
noutram 0:f916cefba2f4 6
noutram 0:f916cefba2f4 7 #define RED_DONE 1
noutram 0:f916cefba2f4 8 #define YELLOW_DONE 2
noutram 0:f916cefba2f4 9
noutram 2:70084af839d3 10 //Delays in ms
noutram 2:70084af839d3 11 #define TUNIT 250
noutram 2:70084af839d3 12 #define TDOT TUNIT
noutram 2:70084af839d3 13 #define TDASH (3*TUNIT)
noutram 2:70084af839d3 14 #define TGAP TUNIT
noutram 2:70084af839d3 15 #define TLETTER (3*TUNIT)
noutram 2:70084af839d3 16 #define TWORD (7*TUNIT)
noutram 0:f916cefba2f4 17
noutram 2:70084af839d3 18 //Size of the morse character buffer
noutram 2:70084af839d3 19 #define BUFFERSIZE 240
noutram 2:70084af839d3 20
noutram 2:70084af839d3 21
noutram 2:70084af839d3 22 /*
noutram 2:70084af839d3 23 **** Morse Code ***
noutram 2:70084af839d3 24
noutram 2:70084af839d3 25 . 1 unit
noutram 2:70084af839d3 26 - 3 units
noutram 2:70084af839d3 27 inter-space 1 unit
noutram 2:70084af839d3 28
noutram 2:70084af839d3 29 between letters 3 units
noutram 2:70084af839d3 30 between words 7 units
noutram 2:70084af839d3 31 */
noutram 2:70084af839d3 32
noutram 2:70084af839d3 33 //Morse code
noutram 2:70084af839d3 34 const char* const morseAlpha[] = {
noutram 2:70084af839d3 35 ".-", //A
noutram 2:70084af839d3 36 "-...", //B
noutram 2:70084af839d3 37 "-.-.", //C
noutram 2:70084af839d3 38 "-..", //D
noutram 2:70084af839d3 39 ".", //E
noutram 2:70084af839d3 40 "..-.", //F
noutram 2:70084af839d3 41 "--.", //G
noutram 2:70084af839d3 42 "....", //H
noutram 2:70084af839d3 43 "..", //I
noutram 2:70084af839d3 44 ".---", //J
noutram 2:70084af839d3 45 "-.-", //K
noutram 2:70084af839d3 46 ".-..", //L
noutram 2:70084af839d3 47 "--", //M
noutram 2:70084af839d3 48 "-.", //N
noutram 2:70084af839d3 49 "---", //O
noutram 2:70084af839d3 50 ".--.", //P
noutram 2:70084af839d3 51 "--.-", //Q
noutram 2:70084af839d3 52 ".-.", //R
noutram 2:70084af839d3 53 "...", //S
noutram 2:70084af839d3 54 "-", //T
noutram 2:70084af839d3 55 "..-", //U
noutram 2:70084af839d3 56 "...-", //V
noutram 2:70084af839d3 57 ".--", //W
noutram 2:70084af839d3 58 "-..-", //X
noutram 2:70084af839d3 59 "-.--", //Y
noutram 2:70084af839d3 60 "--.." //Z
noutram 2:70084af839d3 61 };
noutram 2:70084af839d3 62
noutram 2:70084af839d3 63 const char* const morseNumeric[] = {
noutram 2:70084af839d3 64 "-----", //0
noutram 2:70084af839d3 65 ".----", //1
noutram 2:70084af839d3 66 "..---", //2
noutram 2:70084af839d3 67 "...--", //3
noutram 2:70084af839d3 68 "....-", //4
noutram 2:70084af839d3 69 ".....", //5
noutram 2:70084af839d3 70 "-....", //6
noutram 2:70084af839d3 71 "--...", //7
noutram 2:70084af839d3 72 "---..", //8
noutram 2:70084af839d3 73 "----." //9
noutram 2:70084af839d3 74 };
noutram 0:f916cefba2f4 75
noutram 0:f916cefba2f4 76 //Digital outputs
noutram 0:f916cefba2f4 77 DigitalOut onBoardLED(LED1);
noutram 0:f916cefba2f4 78 DigitalOut redLED(D7);
noutram 0:f916cefba2f4 79 DigitalOut yellowLED(D6);
noutram 0:f916cefba2f4 80 DigitalOut greenLED(D5);
noutram 0:f916cefba2f4 81
noutram 2:70084af839d3 82 //Serial Interface
noutram 2:70084af839d3 83 Serial pc(USBTX, USBRX);
noutram 2:70084af839d3 84
noutram 0:f916cefba2f4 85 //Digital inputs
noutram 0:f916cefba2f4 86 DigitalIn onBoardSwitch(USER_BUTTON);
noutram 0:f916cefba2f4 87 DigitalIn SW1(D4);
noutram 0:f916cefba2f4 88 DigitalIn SW2(D3);
noutram 0:f916cefba2f4 89
noutram 0:f916cefba2f4 90 //Thread ID for the Main function (CMSIS API)
noutram 0:f916cefba2f4 91 osThreadId tidMain;
noutram 0:f916cefba2f4 92
noutram 2:70084af839d3 93 //Thread sychronisation primatives
noutram 2:70084af839d3 94 Semaphore *spaceAvailable;
noutram 2:70084af839d3 95 Semaphore *samplesInBuffer;
noutram 2:70084af839d3 96 Mutex *bufferLock;
noutram 2:70084af839d3 97
noutram 2:70084af839d3 98 //Output buffer
noutram 2:70084af839d3 99 char buffer[BUFFERSIZE];
noutram 2:70084af839d3 100 unsigned int newestIndex = BUFFERSIZE-1; //First time it is incremented, it will be 0
noutram 2:70084af839d3 101 unsigned int oldestIndex = BUFFERSIZE-1;
noutram 0:f916cefba2f4 102
noutram 2:70084af839d3 103
noutram 2:70084af839d3 104 //Producer
noutram 2:70084af839d3 105 void addCharacterToQueue(const char c)
noutram 2:70084af839d3 106 {
noutram 2:70084af839d3 107 //Is there space?
noutram 2:70084af839d3 108 spaceAvailable->wait();
noutram 2:70084af839d3 109
noutram 2:70084af839d3 110 //Ok, there is space - take the lock
noutram 2:70084af839d3 111 bufferLock->lock();
noutram 2:70084af839d3 112 redLED = 1;
noutram 1:4fb27aea76b2 113
noutram 2:70084af839d3 114 //Update buffer
noutram 2:70084af839d3 115 newestIndex = (newestIndex+1) % BUFFERSIZE;
noutram 2:70084af839d3 116 buffer[newestIndex] = c;
noutram 2:70084af839d3 117
noutram 2:70084af839d3 118 //Release lock
noutram 2:70084af839d3 119 bufferLock->unlock();
noutram 2:70084af839d3 120 redLED = 0;
noutram 2:70084af839d3 121
noutram 2:70084af839d3 122 //Signal that a sample has been added
noutram 2:70084af839d3 123 samplesInBuffer->release();
noutram 2:70084af839d3 124 }
noutram 2:70084af839d3 125
noutram 2:70084af839d3 126 //Consumer
noutram 2:70084af839d3 127 char takeCharacterFromQueue()
noutram 2:70084af839d3 128 {
noutram 2:70084af839d3 129 //Are thre any samples in the buffer
noutram 2:70084af839d3 130 samplesInBuffer->wait();
noutram 1:4fb27aea76b2 131
noutram 2:70084af839d3 132 //Ok, there are samples - take the lock
noutram 2:70084af839d3 133 bufferLock->lock();
noutram 2:70084af839d3 134 yellowLED = 1;
noutram 2:70084af839d3 135
noutram 2:70084af839d3 136 //Update buffer - remove oldest
noutram 2:70084af839d3 137 oldestIndex = (oldestIndex+1) % BUFFERSIZE;
noutram 2:70084af839d3 138 char cc = buffer[oldestIndex];
noutram 0:f916cefba2f4 139
noutram 2:70084af839d3 140 //Release lock
noutram 2:70084af839d3 141 bufferLock->unlock();
noutram 2:70084af839d3 142 yellowLED = 0;
noutram 2:70084af839d3 143
noutram 2:70084af839d3 144 //Signal there is space in the buffer
noutram 2:70084af839d3 145 spaceAvailable->release();
noutram 2:70084af839d3 146
noutram 2:70084af839d3 147 //return a copy of the result
noutram 2:70084af839d3 148 return cc;
noutram 0:f916cefba2f4 149 }
noutram 0:f916cefba2f4 150
noutram 2:70084af839d3 151 void morseGenerator( const void* arg )
noutram 0:f916cefba2f4 152 {
noutram 2:70084af839d3 153 while (true) {
noutram 2:70084af839d3 154
noutram 2:70084af839d3 155 //Are there samples available?
noutram 2:70084af839d3 156 char nextChar = takeCharacterFromQueue();
noutram 2:70084af839d3 157 nextChar = tolower(nextChar);
noutram 2:70084af839d3 158
noutram 2:70084af839d3 159 //Look up morse code
noutram 2:70084af839d3 160
noutram 2:70084af839d3 161 //Space between words - assumes only one
noutram 2:70084af839d3 162 if (nextChar == ' ') {
noutram 2:70084af839d3 163 Thread::wait(TWORD-TLETTER);
noutram 2:70084af839d3 164 continue;
noutram 2:70084af839d3 165 }
noutram 2:70084af839d3 166
noutram 2:70084af839d3 167 //Number?
noutram 2:70084af839d3 168 const char *nextString;
noutram 2:70084af839d3 169 if ((nextChar >= '0') && (nextChar <= '9')) {
noutram 2:70084af839d3 170 nextString = morseNumeric[nextChar - '0'];
noutram 2:70084af839d3 171 }
noutram 2:70084af839d3 172 //Character?
noutram 2:70084af839d3 173 else if ((nextChar >='a') && (nextChar <= 'z')) {
noutram 2:70084af839d3 174 nextString = morseAlpha[nextChar - 'a'];
noutram 2:70084af839d3 175 } else {
noutram 2:70084af839d3 176 //Invalid
noutram 2:70084af839d3 177 continue;
noutram 2:70084af839d3 178 }
noutram 1:4fb27aea76b2 179
noutram 2:70084af839d3 180 //Flash morse for this letter
noutram 2:70084af839d3 181 for (unsigned int n=0; n<strlen(nextString); n++) {
noutram 2:70084af839d3 182 char symb = nextString[n];
noutram 2:70084af839d3 183 greenLED = 1;
noutram 2:70084af839d3 184 switch (symb) {
noutram 2:70084af839d3 185 case '.':
noutram 2:70084af839d3 186 Thread::wait(TDOT);
noutram 2:70084af839d3 187 break;
noutram 2:70084af839d3 188 case '-':
noutram 2:70084af839d3 189 Thread::wait(TDASH);
noutram 2:70084af839d3 190 break;
noutram 2:70084af839d3 191 default:
noutram 2:70084af839d3 192 break;
noutram 2:70084af839d3 193 }
noutram 2:70084af839d3 194 greenLED = 0;
noutram 2:70084af839d3 195
noutram 2:70084af839d3 196 //A gap between symbols
noutram 2:70084af839d3 197 Thread::wait(TGAP);
noutram 2:70084af839d3 198 }
noutram 1:4fb27aea76b2 199
noutram 2:70084af839d3 200 //Gap between letters
noutram 2:70084af839d3 201 Thread::wait(TLETTER-TGAP);
noutram 2:70084af839d3 202
noutram 2:70084af839d3 203 }
noutram 0:f916cefba2f4 204 }
noutram 0:f916cefba2f4 205
noutram 2:70084af839d3 206 void convertToMorseAsync(const char* pString)
noutram 2:70084af839d3 207 {
noutram 2:70084af839d3 208 //Copy each character into the buffer
noutram 2:70084af839d3 209 int L = strlen(pString);
noutram 2:70084af839d3 210 for (int n=0; n<L; n++) {
noutram 2:70084af839d3 211 char c = pString[n];
noutram 2:70084af839d3 212 addCharacterToQueue(c);
noutram 2:70084af839d3 213 }
noutram 2:70084af839d3 214 }
noutram 2:70084af839d3 215
noutram 0:f916cefba2f4 216
noutram 0:f916cefba2f4 217 //Main thread
noutram 0:f916cefba2f4 218 int main() {
noutram 0:f916cefba2f4 219 redLED = 0;
noutram 0:f916cefba2f4 220 yellowLED = 0;
noutram 2:70084af839d3 221 greenLED = 0;
noutram 2:70084af839d3 222
noutram 2:70084af839d3 223 //Semaphores
noutram 2:70084af839d3 224 bufferLock = new Mutex();
noutram 2:70084af839d3 225 spaceAvailable = new Semaphore(BUFFERSIZE);
noutram 2:70084af839d3 226 samplesInBuffer = new Semaphore(0);
noutram 2:70084af839d3 227
noutram 0:f916cefba2f4 228
noutram 0:f916cefba2f4 229 //Main thread ID
noutram 0:f916cefba2f4 230 tidMain = Thread::gettid();
noutram 0:f916cefba2f4 231
noutram 2:70084af839d3 232
noutram 2:70084af839d3 233 //Thread for outputting mors
noutram 2:70084af839d3 234 Thread writer(morseGenerator);
noutram 1:4fb27aea76b2 235
noutram 2:70084af839d3 236 pc.printf("Type characters to send\n");
noutram 2:70084af839d3 237 while (true) {
noutram 2:70084af839d3 238 //Read keyboard (serial port)
noutram 2:70084af839d3 239 char c = pc.getc();
noutram 2:70084af839d3 240 pc.printf("\n");
noutram 2:70084af839d3 241 addCharacterToQueue(c);
noutram 0:f916cefba2f4 242 }
noutram 0:f916cefba2f4 243
noutram 0:f916cefba2f4 244 }
noutram 2:70084af839d3 245
noutram 2:70084af839d3 246