Demonstration of a message queue + memory pool

Revision:
10:3a3d2a571c8f
Parent:
9:31031bbb59c7
Child:
11:6cfaf7dfecb9
diff -r 31031bbb59c7 -r 3a3d2a571c8f main.cpp
--- a/main.cpp	Mon Mar 21 13:50:11 2016 +0000
+++ b/main.cpp	Tue Mar 22 13:40:05 2016 +0000
@@ -27,58 +27,83 @@
 //Threads
 Thread *t1;
 
-//Queues - "A message can be a integer or pointer value  to a certain type T that is sent to a thread or interrupt service routine."
-Queue<uint32_t, 5> *queue;
+//Class type
+class message_t {
+public:    
+    float    adcValue;    
+    int sw1State;
+    int sw2State;
+    
+    //Constructor
+    message_t(float f, int s1, int s2) {
+        adcValue = f;
+        sw1State = s1;
+        sw2State = s2;    
+    }
+};
+ 
+//Memory Pool - with capacity for 16 message_t types
+MemoryPool<message_t, 16> mpool;
 
+//Message queue - matched to the memory pool
+Queue<message_t, 16> queue;
 
 // Call this on precise intervals
 void adcISR() {
     
-    //Option to starve the queue
-    if (sw2 == 1) return;
+    //Read sample - make a copy
+    float sample = adcIn;
+    //Grab switch state
+    uint32_t switch1State = sw1;
+    uint32_t switch2State = sw2;
     
-    //Read sample - make a copy
-    uint32_t sample = (uint32_t)(4095*adcIn.read());
+    //Allocate a block from the memory pool
+    message_t *message = mpool.alloc();
+    if (message == NULL) {
+        //Out of memory
+        redLED = 1;
+        return;   
+    }
+    
+    //Fill in the data
+    message->adcValue = sample;
+    message->sw1State = switch1State;
+    message->sw2State = switch2State;
     
     //Write to queue
-    osStatus stat = queue->put((uint32_t*)sample);
+    osStatus stat = queue.put(message);    //Note we are sending the "pointer"
     
     //Check if succesful
     if (stat == osErrorResource) {
         redLED = 1; 
         printf("queue->put() Error code: %4Xh, Resource not available\r\n", stat);   
+        mpool.free(message);
+        return;
     }
-    
 }
 
 //Normal priority thread (consumer)
 void thread1( const void* arg ) 
-{    
+{      
     while (true) {
-        //Read queue - block (with timeout)
-        osEvent evt = queue->get(5000);     //With timeout
+        //Block on the queue
+        osEvent evt = queue.get();
         
-        //Check status of get()
-        switch (evt.status) { 
-            case osEventMessage:
-                //Normal status
-                printf("value = %d\n\r", evt.value.v);
-                greenLED = !greenLED;
-                break;
-            case osEventTimeout:
-                //Timeout
-                printf("queue->get() returned %02x status (timeout)\n\r", evt.status);
-                break;
-            default:
-                //All other errors (see cmsis_os.h for meaning of error code)
-                printf("queue->get() returned %02x status\n\r", evt.status);
-                break;
+        //Check status
+        if (evt.status == osEventMessage) {
+            message_t *pMessage = (message_t*)evt.value.p;  //This is the pointer (address)
+            //Make a copy
+            message_t msg(pMessage->adcValue, pMessage->sw1State, pMessage->sw2State);
+            //We are done with this, so give back the memory to the pool
+            mpool.free(pMessage);
+            
+            //Echo to the terminal
+            printf("ADC Value: %.2f\t",    msg.adcValue);
+            printf("SW1: %u\t",             msg.sw1State);
+            printf("SW2: %u\n\r",             msg.sw2State);
         }
-                
-        //Block up consumer if switch is held down
-        //Will fill the queue if held long enough
-        while (sw1 == 1);
-        
+
+             
     } //end while
 }
 
@@ -90,14 +115,11 @@
     greenLED  = 0;
            
     //Start message
-    printf("Welcome\n");
-           
-    //Queue
-    queue = new Queue<uint32_t,5>();
-
+    printf("Welcome\n");           
+   
     //Hook up timer interrupt   
     Ticker timer; 
-    timer.attach(&adcISR, 1.0);
+    timer.attach(&adcISR, 0.1);
                
     //Threads
     t1 = new Thread(&thread1);