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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers <title>RtosLog.cpp Source File</title>

RtosLog.cpp

00001 /*
00002  *  Copyright 2014 Embedded Artists AB
00003  *
00004  *  Licensed under the Apache License, Version 2.0 (the "License");
00005  *  you may not use this file except in compliance with the License.
00006  *  You may obtain a copy of the License at
00007  *
00008  *    http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  *  Unless required by applicable law or agreed to in writing, software
00011  *  distributed under the License is distributed on an "AS IS" BASIS,
00012  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *  See the License for the specific language governing permissions and
00014  *  limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include "RtosLog.h"
00019 #include <cstdarg>
00020 
00021 /******************************************************************************
00022  * Defines and typedefs
00023  *****************************************************************************/
00024 
00025  
00026 /******************************************************************************
00027  * Local variables
00028  *****************************************************************************/
00029 
00030 /******************************************************************************
00031  * Private Functions
00032  *****************************************************************************/
00033 
00034 void RtosLog::logTask(void const* args)
00035 {
00036     RtosLog* instance = (RtosLog*)args;
00037     
00038     while (true) {
00039         osEvent evt = instance->_queue.get();
00040         if (evt.status == osEventMessage) {
00041             message_t *message = (message_t*)evt.value.p;
00042             if (message->ptr != NULL) {
00043                 instance->_serial.printf(message->ptr);
00044                 free(message->ptr);
00045             } else {
00046                 instance->_serial.printf(message->msg);
00047             }
00048             
00049             instance->_mpool.free(message);
00050             
00051             // Increase the number of available messages in the pool
00052             instance->_sem.release();
00053         }
00054     }    
00055 }
00056 
00057 /******************************************************************************
00058  * Public Functions
00059  *****************************************************************************/
00060 
00061 #if defined(DM_BOARD_USE_USBSERIAL_IN_RTOSLOG)
00062     RtosLog::RtosLog() :
00063         _sem(NumMessages), _serial(), _thr(NULL)
00064     {
00065     }
00066 #else
00067 RtosLog::RtosLog() :
00068     _sem(NumMessages), _serial(USBTX, USBRX), _thr(NULL)
00069 {
00070 #if defined(DM_BOARD_USE_FAST_UART)
00071     // This works because both the default serial (used by printf) and the s instance
00072     // (used by s.printf) would use the same underlying UART code so setting the baudrate
00073     // in one affects the other.
00074     _serial.baud(115200);
00075 #endif
00076 }
00077 #endif
00078 
00079 RtosLog::~RtosLog()
00080 {
00081     if (_thr != NULL) {
00082         _thr->terminate();
00083         delete _thr;
00084         _thr = NULL;
00085     }
00086 }
00087 
00088 void RtosLog::init()
00089 {
00090     if (_thr == NULL) {
00091         _thr = new Thread();
00092         _thr->start(callback(&RtosLog::logTask, this));
00093     }
00094 }
00095 
00096 int RtosLog::printf(const char* format, ...)
00097 {
00098     // The pool has no "wait for free message" so we use a Sempahore
00099     // to keep track of the number of free messages and, if needed,
00100     // block the caller until a message is free
00101     _sem.acquire();
00102     
00103     // Allocate a null terminated message. Will always succeed due to
00104     // the semaphore above
00105     message_t *message = _mpool.calloc();
00106     
00107     // Write the callers formatted message 
00108     std::va_list args;
00109     va_start(args, format);
00110     int ret = vsnprintf(message->msg, MessageLen, format, args);
00111     va_end(args);
00112     
00113     // If the entire message could not fit in the preallocated buffer
00114     // then allocate a new one and try again.
00115     if (ret > MessageLen) {
00116         message->ptr = (char*)malloc(ret + 1);
00117         if (message->ptr != NULL) {
00118             va_start(args, format);
00119             ret = vsnprintf(message->ptr, ret + 1, format, args);
00120             va_end(args);
00121         }
00122     }
00123     
00124     // Send message
00125     _queue.put(message);
00126     
00127     // Note that the Semaphore is not released here, that is done after
00128     // the message has been processed and released into the pool by
00129     // logTask()
00130     //_sem.release();
00131     
00132     return ret;
00133 }
00134 
00135 int RtosLog::isr_printf(const char* format, ...)
00136 {
00137     // The pool has no "wait for free message" so we use a Sempahore
00138     // to keep track of the number of free messages and, if needed,
00139     // block the caller until a message is free
00140     bool available = _sem.try_acquire();
00141     if (!available) {
00142       // no free messages and it is not good to wait in an ISR so
00143       // we discard the message
00144       return 0;
00145     }
00146     
00147     // Allocate a null terminated message. Will always succeed due to
00148     // the semaphore above
00149     message_t *message = _mpool.calloc();
00150     
00151     // Write the callers formatted message 
00152     std::va_list args;
00153     va_start(args, format);
00154     int ret = vsnprintf(message->msg, MessageLen, format, args);
00155     va_end(args);
00156     
00157     // If the entire message could not fit in the preallocated buffer
00158     // then allocate a new one and try again.
00159     if (ret > MessageLen) {
00160         message->ptr = (char*)malloc(ret + 1);
00161         if (message->ptr != NULL) {
00162             va_start(args, format);
00163             ret = vsnprintf(message->ptr, ret + 1, format, args);
00164             va_end(args);
00165         }
00166     }
00167     
00168     // Send message
00169     _queue.put(message);
00170     
00171     // Note that the Semaphore is not released here, that is done after
00172     // the message has been processed and released into the pool by
00173     // logTask()
00174     //_sem.release();
00175     
00176     return ret;
00177 }