first compiled version
Dependencies: mbed-rtos mbed C12832_lcd LM75B
main.cpp
- Committer:
- nleoni
- Date:
- 2014-03-11
- Revision:
- 9:f40c7c08d1c2
- Parent:
- 8:4fcba095bdf0
File content as of revision 9:f40c7c08d1c2:
//LAB 6: RTOS AND IPC //WRITTEN BY: ROBERT HARRELL AND NAPOLEON LEONI //IPC: INTER PROGRAMMER COMMUNICATION.... //This program tests IPC for the mbed RTOS //It features an LCD thread that updates the Pot value, //Temperature and the fortune cookie using IPC methods with timeout //The POT thread reads the POT value in a polling loop every 10 seconds //and uses the IPC queue to send the data to the LCD thread //The TEMP thread reads the temp value in a polling loop every 60 seconds //and uses the IPC queue to send the data to the LCD thread //The fortune cookie thread reads a fortune from a user using getc on a polling loop //every 100 ms and sends the fortune cookie via an IPC memory pool to the LCD thread //The TOD thread updates the time of date once a minute, it uses a mutex to share the LCD //with the LCD thread. //***************************** TESTING ********************************************************// // TEST TEST DESCRIPTION STATUS // // 1 POT thread updates to a in less than 10 s when pot PASS // // value is changed // // 2 Temp thread updates to a in less than 60 s when sensor PASS // // sensor temperature changes // // 3 Strings entered with the terminal are faithfully displayed PASS // // in the LCD, no missing characters regardless of typing // // speed // // 4 Enetering a fortune cookie in the terminal does not block PASS // // normsl executions o the other threads // // 5 There is no risk of overunning the fortune cookie buffer PASS // // if the user continues to type beyond the allowable cookie // // length the program trims the fortune cookie and reads the // // reamining characters for the next cookie, no missing characters // // 6 Pressing center joystick button at reset allows entering date PASS // // from the terminal. //**********************************************************************************************// #include "mbed.h" #include "rtos.h" #include "C12832_lcd.h" #include "LM75B.h" #include <string> //#define _DEBUGMODE //Uncomment to enter debug mode which prints some diagnostic strings to the terminal #define BUFFER 17 #define COOKIEQUEUE 30 #define TIMEOUT 200 C12832_LCD lcd; Serial pc(USBTX, USBRX); //To differentiate from LCD functions Mutex lcdMutex; AnalogIn pot1(p19); MemoryPool<float, 10> potReadingBuffer; Queue<float,10> potReadingQueue; //Temperature Sensor LM75B tmp(p28,p27); Queue<float,10> tempReadingQueue; MemoryPool<char[BUFFER], COOKIEQUEUE> cookieReadingBuffer; Queue<char[BUFFER],COOKIEQUEUE> cookieReadingQueue; DigitalIn center(p14); //Initiate RTC clock setup /****************************************************************** * *An LCD thread that updates the LCD based on information *received from other threads via IPC * *Uses the top 3 lines of the LCD to reflect the pot, the *temperature, and the cookie. This task must use IPC (with *timeout) methods to get data from each of the previous threads * *******************************************************************/ void lcdUpdate(void const*){ while(1){ osStatus lcdStatus = lcdMutex.lock(TIMEOUT); if(lcdStatus == osOK){ osEvent evtPot = potReadingQueue.get(TIMEOUT); if (evtPot.status == osEventMessage) { float *queuePot = (float*)evtPot.value.p; lcd.locate(0,0); lcd.printf("Volt: %.2f V", *queuePot); potReadingBuffer.free(queuePot); } osEvent evtTemp = tempReadingQueue.get(TIMEOUT); if (evtPot.status == osEventMessage) { float *queueTemp = (float*)evtTemp.value.p; lcd.locate(0,8); lcd.printf("Temp: %.2f F", *queueTemp); } osEvent evtCookie = cookieReadingQueue.get(TIMEOUT); if (evtCookie.status == osEventMessage) { char (*queueCookie)[BUFFER] = (char (*)[BUFFER])evtCookie.value.p; lcd.locate(0,16); string str(*queueCookie); lcd.printf("F.Cookie: %s", str); cookieReadingBuffer.free(queueCookie); } } lcdMutex.unlock(); Thread::wait(1000); } } /****************************************************************** * *A POT thread that reads the pot value in a polling loop *every 10 seconds and sends value to LCD thread via IPC Queue * *******************************************************************/ void readPOT(void const*){ while(1){ float *queue = potReadingBuffer.alloc(); *queue = pot1; potReadingQueue.put(queue,TIMEOUT); #ifdef _DEBUGMODE pc.printf("POT read"); #endif Thread::wait(10000); } } /****************************************************************** * *A TEMP thread that read the temperature every 60 seconds *and sends the value to the LCD task via IPC Queue * *******************************************************************/ void readTemp(void const*){ float temp = 0.0; float *temp_ptr; while(1){ //pc.printf("TEMP read"); temp = tmp.read()*9/5+32; temp_ptr = &temp; tempReadingQueue.put(temp_ptr); Thread::wait(5000); } } /****************************************************************** * *A SCANF thread that reads in a fortune cookie from user *and sends it to the LCD task via IPC Memory Pool * *******************************************************************/ void readCookie(void const*){ pc.printf(">Enter your fortune cookie\n>"); char (*ptrBuffer)[BUFFER] = cookieReadingBuffer.alloc(); char *ptrChar; ptrChar=*ptrBuffer; while(1){ //Note the choice of using getc instead of scanf to read the fortune cookie, //this is a non-blocking call and allows the rest of our threads to continue operating //only when a new character is typed this thread executes its body otherwise //it immediately yields to other threads. if(pc.readable()){ *ptrChar=pc.getc(); pc.putc(*ptrChar); if((*ptrChar=='\n') || ((ptrChar-*ptrBuffer)>=(BUFFER-1)) ){ if((ptrChar-*ptrBuffer)>=(BUFFER-1)) *++ptrChar='\n'; while((ptrChar-*ptrBuffer)<=(BUFFER-1)){ *ptrChar++=' '; } *ptrChar='\0'; cookieReadingQueue.put(ptrBuffer,TIMEOUT); pc.printf(">Enter your fortune cookie\n>"); ptrChar=*ptrBuffer; } else { ptrChar++; } } //A 100 ms wait seems like reasonable delay which allows operation of the remaining threads. Thread::wait(100); } } /****************************************************************** * *A TOD thread that updates the 4th line of the LCD with time *of day once a minute. It shares the LCD with the LCD thread *using mutual exclusion * *******************************************************************/ void readTOD(void const*){ struct tm dt, *dtp; time_t t; char s[ 30 ]; dtp = &dt; while(1){ osStatus lcdStatus = lcdMutex.lock(TIMEOUT); if(lcdStatus == osOK){ //pc.printf("TOD updated"); t = time( NULL ); dtp = localtime( &t ); strftime( s, 20, "%b %d, %Y", dtp ); lcd.locate( 70, 0 ); lcd.printf( "%s", s ); strftime( s, 10, "%H:%M", dtp ); lcd.locate( 70, 8 ); lcd.printf( "%s", s ); } lcdMutex.unlock(); Thread::wait(60000); } } //Using a terminal, set the RTC to current date and time void rtc_setup(void) { // get the current time from the terminal struct tm t; lcd.locate( 0, 0 ); lcd.printf( "Please set time from serial terminal\n\r" ); pc.printf("Enter current date and time:\n\r"); pc.printf("YYYY MM DD HH MM[enter]\n\r"); pc.scanf("%d %d %d %d %d", &t.tm_year, &t.tm_mon, &t.tm_mday , &t.tm_hour, &t.tm_min); // adjust for tm structure required values t.tm_year = t.tm_year - 1900; t.tm_mon = t.tm_mon - 1; // set the time set_time(mktime(&t)); } DigitalOut myled(LED1); int main() { //RTC setup if Center Button is held down if (center) { rtc_setup(); } lcd.cls(); Thread threadLCD(lcdUpdate); Thread threadPOT(readPOT); Thread threadTemp(readTemp); Thread threadCookie(readCookie); Thread threadTOD(readTOD); while(1) { Thread::wait(250); } }