t
Dependencies: DM_FATFileSystem DM_HttpServer DM_USBHost EthernetInterface USBDevice mbed-rpc mbed-rtos
Fork of DMSupport by
RtosLog.cpp@2:887c6b45e7fa, 2014-12-02 (annotated)
- Committer:
- embeddedartists
- Date:
- Tue Dec 02 15:21:18 2014 +0000
- Revision:
- 2:887c6b45e7fa
- Child:
- 34:fc366bab393f
Added RTOS-safe logger (RtosLog). Switched USBHost library so that it works in an RTOS setting. Modified the FAT file system to work in an RTOS setting.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
embeddedartists | 2:887c6b45e7fa | 1 | /* |
embeddedartists | 2:887c6b45e7fa | 2 | * Copyright 2014 Embedded Artists AB |
embeddedartists | 2:887c6b45e7fa | 3 | * |
embeddedartists | 2:887c6b45e7fa | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
embeddedartists | 2:887c6b45e7fa | 5 | * you may not use this file except in compliance with the License. |
embeddedartists | 2:887c6b45e7fa | 6 | * You may obtain a copy of the License at |
embeddedartists | 2:887c6b45e7fa | 7 | * |
embeddedartists | 2:887c6b45e7fa | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
embeddedartists | 2:887c6b45e7fa | 9 | * |
embeddedartists | 2:887c6b45e7fa | 10 | * Unless required by applicable law or agreed to in writing, software |
embeddedartists | 2:887c6b45e7fa | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
embeddedartists | 2:887c6b45e7fa | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
embeddedartists | 2:887c6b45e7fa | 13 | * See the License for the specific language governing permissions and |
embeddedartists | 2:887c6b45e7fa | 14 | * limitations under the License. |
embeddedartists | 2:887c6b45e7fa | 15 | */ |
embeddedartists | 2:887c6b45e7fa | 16 | |
embeddedartists | 2:887c6b45e7fa | 17 | #include "mbed.h" |
embeddedartists | 2:887c6b45e7fa | 18 | #include "RtosLog.h" |
embeddedartists | 2:887c6b45e7fa | 19 | #include <cstdarg> |
embeddedartists | 2:887c6b45e7fa | 20 | |
embeddedartists | 2:887c6b45e7fa | 21 | /****************************************************************************** |
embeddedartists | 2:887c6b45e7fa | 22 | * Defines and typedefs |
embeddedartists | 2:887c6b45e7fa | 23 | *****************************************************************************/ |
embeddedartists | 2:887c6b45e7fa | 24 | |
embeddedartists | 2:887c6b45e7fa | 25 | |
embeddedartists | 2:887c6b45e7fa | 26 | /****************************************************************************** |
embeddedartists | 2:887c6b45e7fa | 27 | * Local variables |
embeddedartists | 2:887c6b45e7fa | 28 | *****************************************************************************/ |
embeddedartists | 2:887c6b45e7fa | 29 | |
embeddedartists | 2:887c6b45e7fa | 30 | /****************************************************************************** |
embeddedartists | 2:887c6b45e7fa | 31 | * Private Functions |
embeddedartists | 2:887c6b45e7fa | 32 | *****************************************************************************/ |
embeddedartists | 2:887c6b45e7fa | 33 | |
embeddedartists | 2:887c6b45e7fa | 34 | void RtosLog::logTask(void const* args) |
embeddedartists | 2:887c6b45e7fa | 35 | { |
embeddedartists | 2:887c6b45e7fa | 36 | RtosLog* instance = (RtosLog*)args; |
embeddedartists | 2:887c6b45e7fa | 37 | |
embeddedartists | 2:887c6b45e7fa | 38 | while (true) { |
embeddedartists | 2:887c6b45e7fa | 39 | osEvent evt = instance->_queue.get(); |
embeddedartists | 2:887c6b45e7fa | 40 | if (evt.status == osEventMessage) { |
embeddedartists | 2:887c6b45e7fa | 41 | message_t *message = (message_t*)evt.value.p; |
embeddedartists | 2:887c6b45e7fa | 42 | if (message->ptr != NULL) { |
embeddedartists | 2:887c6b45e7fa | 43 | instance->_serial.printf(message->ptr); |
embeddedartists | 2:887c6b45e7fa | 44 | free(message->ptr); |
embeddedartists | 2:887c6b45e7fa | 45 | } else { |
embeddedartists | 2:887c6b45e7fa | 46 | instance->_serial.printf(message->msg); |
embeddedartists | 2:887c6b45e7fa | 47 | } |
embeddedartists | 2:887c6b45e7fa | 48 | |
embeddedartists | 2:887c6b45e7fa | 49 | instance->_mpool.free(message); |
embeddedartists | 2:887c6b45e7fa | 50 | |
embeddedartists | 2:887c6b45e7fa | 51 | // Increase the number of available messages in the pool |
embeddedartists | 2:887c6b45e7fa | 52 | instance->_sem.release(); |
embeddedartists | 2:887c6b45e7fa | 53 | } |
embeddedartists | 2:887c6b45e7fa | 54 | } |
embeddedartists | 2:887c6b45e7fa | 55 | } |
embeddedartists | 2:887c6b45e7fa | 56 | |
embeddedartists | 2:887c6b45e7fa | 57 | /****************************************************************************** |
embeddedartists | 2:887c6b45e7fa | 58 | * Public Functions |
embeddedartists | 2:887c6b45e7fa | 59 | *****************************************************************************/ |
embeddedartists | 2:887c6b45e7fa | 60 | |
embeddedartists | 2:887c6b45e7fa | 61 | RtosLog::RtosLog() : |
embeddedartists | 2:887c6b45e7fa | 62 | _sem(NumMessages), _serial(USBTX, USBRX), _thr(NULL) |
embeddedartists | 2:887c6b45e7fa | 63 | { |
embeddedartists | 2:887c6b45e7fa | 64 | #if defined(DM_BOARD_USE_FAST_UART) |
embeddedartists | 2:887c6b45e7fa | 65 | // This works because both the default serial (used by printf) and the s instance |
embeddedartists | 2:887c6b45e7fa | 66 | // (used by s.printf) would use the same underlying UART code so setting the baudrate |
embeddedartists | 2:887c6b45e7fa | 67 | // in one affects the other. |
embeddedartists | 2:887c6b45e7fa | 68 | _serial.baud(115200); |
embeddedartists | 2:887c6b45e7fa | 69 | #endif |
embeddedartists | 2:887c6b45e7fa | 70 | } |
embeddedartists | 2:887c6b45e7fa | 71 | |
embeddedartists | 2:887c6b45e7fa | 72 | RtosLog::~RtosLog() |
embeddedartists | 2:887c6b45e7fa | 73 | { |
embeddedartists | 2:887c6b45e7fa | 74 | if (_thr != NULL) { |
embeddedartists | 2:887c6b45e7fa | 75 | _thr->terminate(); |
embeddedartists | 2:887c6b45e7fa | 76 | delete _thr; |
embeddedartists | 2:887c6b45e7fa | 77 | _thr = NULL; |
embeddedartists | 2:887c6b45e7fa | 78 | } |
embeddedartists | 2:887c6b45e7fa | 79 | } |
embeddedartists | 2:887c6b45e7fa | 80 | |
embeddedartists | 2:887c6b45e7fa | 81 | void RtosLog::init() |
embeddedartists | 2:887c6b45e7fa | 82 | { |
embeddedartists | 2:887c6b45e7fa | 83 | if (_thr == NULL) { |
embeddedartists | 2:887c6b45e7fa | 84 | _thr = new Thread(&RtosLog::logTask, this); |
embeddedartists | 2:887c6b45e7fa | 85 | } |
embeddedartists | 2:887c6b45e7fa | 86 | } |
embeddedartists | 2:887c6b45e7fa | 87 | |
embeddedartists | 2:887c6b45e7fa | 88 | int RtosLog::printf(const char* format, ...) |
embeddedartists | 2:887c6b45e7fa | 89 | { |
embeddedartists | 2:887c6b45e7fa | 90 | // The pool has no "wait for free message" so we use a Sempahore |
embeddedartists | 2:887c6b45e7fa | 91 | // to keep track of the number of free messages and, if needed, |
embeddedartists | 2:887c6b45e7fa | 92 | // block the caller until a message is free |
embeddedartists | 2:887c6b45e7fa | 93 | _sem.wait(); |
embeddedartists | 2:887c6b45e7fa | 94 | |
embeddedartists | 2:887c6b45e7fa | 95 | // Allocate a null terminated message. Will always succeed due to |
embeddedartists | 2:887c6b45e7fa | 96 | // the semaphore above |
embeddedartists | 2:887c6b45e7fa | 97 | message_t *message = _mpool.calloc(); |
embeddedartists | 2:887c6b45e7fa | 98 | |
embeddedartists | 2:887c6b45e7fa | 99 | // Write the callers formatted message |
embeddedartists | 2:887c6b45e7fa | 100 | std::va_list args; |
embeddedartists | 2:887c6b45e7fa | 101 | va_start(args, format); |
embeddedartists | 2:887c6b45e7fa | 102 | int ret = vsnprintf(message->msg, MessageLen, format, args); |
embeddedartists | 2:887c6b45e7fa | 103 | va_end(args); |
embeddedartists | 2:887c6b45e7fa | 104 | |
embeddedartists | 2:887c6b45e7fa | 105 | // If the entire message could not fit in the preallocated buffer |
embeddedartists | 2:887c6b45e7fa | 106 | // then allocate a new one and try again. |
embeddedartists | 2:887c6b45e7fa | 107 | if (ret > MessageLen) { |
embeddedartists | 2:887c6b45e7fa | 108 | message->ptr = (char*)malloc(ret + 1); |
embeddedartists | 2:887c6b45e7fa | 109 | if (message->ptr != NULL) { |
embeddedartists | 2:887c6b45e7fa | 110 | va_start(args, format); |
embeddedartists | 2:887c6b45e7fa | 111 | ret = vsnprintf(message->ptr, ret + 1, format, args); |
embeddedartists | 2:887c6b45e7fa | 112 | va_end(args); |
embeddedartists | 2:887c6b45e7fa | 113 | } |
embeddedartists | 2:887c6b45e7fa | 114 | } |
embeddedartists | 2:887c6b45e7fa | 115 | |
embeddedartists | 2:887c6b45e7fa | 116 | // Send message |
embeddedartists | 2:887c6b45e7fa | 117 | _queue.put(message); |
embeddedartists | 2:887c6b45e7fa | 118 | |
embeddedartists | 2:887c6b45e7fa | 119 | // Note that the Semaphore is not released here, that is done after |
embeddedartists | 2:887c6b45e7fa | 120 | // the message has been processed and released into the pool by |
embeddedartists | 2:887c6b45e7fa | 121 | // logTask() |
embeddedartists | 2:887c6b45e7fa | 122 | //_sem.release(); |
embeddedartists | 2:887c6b45e7fa | 123 | |
embeddedartists | 2:887c6b45e7fa | 124 | return ret; |
embeddedartists | 2:887c6b45e7fa | 125 | } |
embeddedartists | 2:887c6b45e7fa | 126 |