Stage-1 Students SoCEM
/
Task632-mbedos54
Demonstration of a message queue + memory pool
Diff: main.cpp
- Revision:
- 2:70084af839d3
- Parent:
- 1:4fb27aea76b2
- Child:
- 3:423191a375dc
--- a/main.cpp Tue Mar 08 12:26:28 2016 +0000 +++ b/main.cpp Tue Mar 08 20:51:13 2016 +0000 @@ -1,13 +1,77 @@ #include "mbed.h" #include "rtos.h" +#include "string.h" +#include <stdio.h> +#include <ctype.h> #define RED_DONE 1 #define YELLOW_DONE 2 +//Delays in ms +#define TUNIT 250 +#define TDOT TUNIT +#define TDASH (3*TUNIT) +#define TGAP TUNIT +#define TLETTER (3*TUNIT) +#define TWORD (7*TUNIT) -//Function declarations -void countUP(void const *args); -void countDOWN(void const *args); +//Size of the morse character buffer +#define BUFFERSIZE 240 + + +/* +**** Morse Code *** + +. 1 unit +- 3 units +inter-space 1 unit + +between letters 3 units +between words 7 units +*/ + +//Morse code +const char* const morseAlpha[] = { + ".-", //A + "-...", //B + "-.-.", //C + "-..", //D + ".", //E + "..-.", //F + "--.", //G + "....", //H + "..", //I + ".---", //J + "-.-", //K + ".-..", //L + "--", //M + "-.", //N + "---", //O + ".--.", //P + "--.-", //Q + ".-.", //R + "...", //S + "-", //T + "..-", //U + "...-", //V + ".--", //W + "-..-", //X + "-.--", //Y + "--.." //Z +}; + +const char* const morseNumeric[] = { + "-----", //0 + ".----", //1 + "..---", //2 + "...--", //3 + "....-", //4 + ".....", //5 + "-....", //6 + "--...", //7 + "---..", //8 + "----." //9 +}; //Digital outputs DigitalOut onBoardLED(LED1); @@ -15,112 +79,168 @@ DigitalOut yellowLED(D6); DigitalOut greenLED(D5); +//Serial Interface +Serial pc(USBTX, USBRX); + //Digital inputs DigitalIn onBoardSwitch(USER_BUTTON); DigitalIn SW1(D4); DigitalIn SW2(D3); -//MUTEX Lock -Mutex *countLock; - //Thread ID for the Main function (CMSIS API) osThreadId tidMain; -//Stared mutable state -volatile long long count = 0; +//Thread sychronisation primatives +Semaphore *spaceAvailable; +Semaphore *samplesInBuffer; +Mutex *bufferLock; + +//Output buffer +char buffer[BUFFERSIZE]; +unsigned int newestIndex = BUFFERSIZE-1; //First time it is incremented, it will be 0 +unsigned int oldestIndex = BUFFERSIZE-1; -//Threads -void countUP(void const *args) -{ - redLED = 1; - - for (unsigned int n=0; n<10000; n++) { - //Take lock - countLock->lock(); + +//Producer +void addCharacterToQueue(const char c) +{ + //Is there space? + spaceAvailable->wait(); + + //Ok, there is space - take the lock + bufferLock->lock(); + redLED = 1; - //Critical section(s) - count++; - count++; - count++; - count++; - count++; - count++; - count++; - count++; - count++; - count++; + //Update buffer + newestIndex = (newestIndex+1) % BUFFERSIZE; + buffer[newestIndex] = c; + + //Release lock + bufferLock->unlock(); + redLED = 0; + + //Signal that a sample has been added + samplesInBuffer->release(); +} + +//Consumer +char takeCharacterFromQueue() +{ + //Are thre any samples in the buffer + samplesInBuffer->wait(); - //Release lock - countLock->unlock(); - } + //Ok, there are samples - take the lock + bufferLock->lock(); + yellowLED = 1; + + //Update buffer - remove oldest + oldestIndex = (oldestIndex+1) % BUFFERSIZE; + char cc = buffer[oldestIndex]; - redLED = 0; - osSignalSet(tidMain, RED_DONE); //Signal main thread we are done + //Release lock + bufferLock->unlock(); + yellowLED = 0; + + //Signal there is space in the buffer + spaceAvailable->release(); + + //return a copy of the result + return cc; } -void countDOWN(void const *args) +void morseGenerator( const void* arg ) { - yellowLED = 1; - - for (unsigned int n=0; n<10000; n++) { - //Take lock - countLock->lock(); + while (true) { + + //Are there samples available? + char nextChar = takeCharacterFromQueue(); + nextChar = tolower(nextChar); + + //Look up morse code + + //Space between words - assumes only one + if (nextChar == ' ') { + Thread::wait(TWORD-TLETTER); + continue; + } + + //Number? + const char *nextString; + if ((nextChar >= '0') && (nextChar <= '9')) { + nextString = morseNumeric[nextChar - '0']; + } + //Character? + else if ((nextChar >='a') && (nextChar <= 'z')) { + nextString = morseAlpha[nextChar - 'a']; + } else { + //Invalid + continue; + } - //Critical section(s) - count--; - count--; - count--; - count--; - count--; - count--; - count--; - count--; - count--; - count--; + //Flash morse for this letter + for (unsigned int n=0; n<strlen(nextString); n++) { + char symb = nextString[n]; + greenLED = 1; + switch (symb) { + case '.': + Thread::wait(TDOT); + break; + case '-': + Thread::wait(TDASH); + break; + default: + break; + } + greenLED = 0; + + //A gap between symbols + Thread::wait(TGAP); + } - //Release lock - countLock->unlock(); - } - - osSignalSet(tidMain, YELLOW_DONE); //Signal main thread we are done - yellowLED = 0; + //Gap between letters + Thread::wait(TLETTER-TGAP); + + } } +void convertToMorseAsync(const char* pString) +{ + //Copy each character into the buffer + int L = strlen(pString); + for (int n=0; n<L; n++) { + char c = pString[n]; + addCharacterToQueue(c); + } +} + //Main thread int main() { redLED = 0; yellowLED = 0; - greenLED = 1; + greenLED = 0; + + //Semaphores + bufferLock = new Mutex(); + spaceAvailable = new Semaphore(BUFFERSIZE); + samplesInBuffer = new Semaphore(0); + //Main thread ID tidMain = Thread::gettid(); - //Create lock - countLock = new Mutex(); + + //Thread for outputting mors + Thread writer(morseGenerator); - //Press the switch to run concurrently - if (onBoardSwitch == 1) { - printf("Running sequntially\n"); - countUP(NULL); - countDOWN(NULL); - } else { - printf("Running concurrently\n"); - Thread t1(countUP); - Thread t2(countDOWN); - - //Wait for the ALL_ON signal - Thread::signal_wait(RED_DONE,osWaitForever); - Thread::signal_wait(YELLOW_DONE,osWaitForever); + pc.printf("Type characters to send\n"); + while (true) { + //Read keyboard (serial port) + char c = pc.getc(); + pc.printf("\n"); + addCharacterToQueue(c); } - printf("Final result = %lld\n", count); - if (count == 0) { - greenLED = 0; - } - - //Tidy - delete countLock; - - while(true); } + +