Stage-1 Students SoCEM
/
Task632-mbedos54
Demonstration of a message queue + memory pool
main.cpp@2:70084af839d3, 2016-03-08 (annotated)
- 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?
User | Revision | Line number | New 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 |