A board support package for the LPC4088 Display Module.

Dependencies:   DM_HttpServer DM_USBHost

Dependents:   lpc4088_displaymodule_emwin lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI ... more

Fork of DMSupport by EmbeddedArtists AB

Revision:
2:887c6b45e7fa
Child:
34:fc366bab393f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RtosLog.cpp	Tue Dec 02 15:21:18 2014 +0000
@@ -0,0 +1,126 @@
+/*
+ *  Copyright 2014 Embedded Artists AB
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "mbed.h"
+#include "RtosLog.h"
+#include <cstdarg>
+
+/******************************************************************************
+ * Defines and typedefs
+ *****************************************************************************/
+
+ 
+/******************************************************************************
+ * Local variables
+ *****************************************************************************/
+
+/******************************************************************************
+ * Private Functions
+ *****************************************************************************/
+
+void RtosLog::logTask(void const* args)
+{
+    RtosLog* instance = (RtosLog*)args;
+    
+    while (true) {
+        osEvent evt = instance->_queue.get();
+        if (evt.status == osEventMessage) {
+            message_t *message = (message_t*)evt.value.p;
+            if (message->ptr != NULL) {
+                instance->_serial.printf(message->ptr);
+                free(message->ptr);
+            } else {
+                instance->_serial.printf(message->msg);
+            }
+            
+            instance->_mpool.free(message);
+            
+            // Increase the number of available messages in the pool
+            instance->_sem.release();
+        }
+    }    
+}
+
+/******************************************************************************
+ * Public Functions
+ *****************************************************************************/
+
+RtosLog::RtosLog() :
+    _sem(NumMessages), _serial(USBTX, USBRX), _thr(NULL)
+{
+#if defined(DM_BOARD_USE_FAST_UART)
+    // This works because both the default serial (used by printf) and the s instance
+    // (used by s.printf) would use the same underlying UART code so setting the baudrate
+    // in one affects the other.
+    _serial.baud(115200);
+#endif
+}
+
+RtosLog::~RtosLog()
+{
+    if (_thr != NULL) {
+        _thr->terminate();
+        delete _thr;
+        _thr = NULL;
+    }
+}
+
+void RtosLog::init()
+{
+    if (_thr == NULL) {
+        _thr = new Thread(&RtosLog::logTask, this);
+    }
+}
+
+int RtosLog::printf(const char* format, ...)
+{
+    // The pool has no "wait for free message" so we use a Sempahore
+    // to keep track of the number of free messages and, if needed,
+    // block the caller until a message is free
+    _sem.wait();
+    
+    // Allocate a null terminated message. Will always succeed due to
+    // the semaphore above
+    message_t *message = _mpool.calloc();
+    
+    // Write the callers formatted message 
+    std::va_list args;
+    va_start(args, format);
+    int ret = vsnprintf(message->msg, MessageLen, format, args);
+    va_end(args);
+    
+    // If the entire message could not fit in the preallocated buffer
+    // then allocate a new one and try again.
+    if (ret > MessageLen) {
+        message->ptr = (char*)malloc(ret + 1);
+        if (message->ptr != NULL) {
+            va_start(args, format);
+            ret = vsnprintf(message->ptr, ret + 1, format, args);
+            va_end(args);
+        }
+    }
+    
+    // Send message
+    _queue.put(message);
+    
+    // Note that the Semaphore is not released here, that is done after
+    // the message has been processed and released into the pool by
+    // logTask()
+    //_sem.release();
+    
+    return ret;
+}
+