Table driven Finite State Machine library based on the Harel state machine, supporting actions on transitions, state entry and state exit. Comes with example illustrating use with interrupts and timers. 03/01/2010 - fixed potential memory leak in DebugTrace.

Dependencies:   mbed

Committer:
snatch59
Date:
Sun Jan 03 11:56:03 2010 +0000
Revision:
0:918566a376fb

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
snatch59 0:918566a376fb 1 /*
snatch59 0:918566a376fb 2 * DebugTrace. Allows dumping debug messages/values to serial or
snatch59 0:918566a376fb 3 * to file.
snatch59 0:918566a376fb 4 *
snatch59 0:918566a376fb 5 * Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk>
snatch59 0:918566a376fb 6 *
snatch59 0:918566a376fb 7 * This file is part of DebugTrace.
snatch59 0:918566a376fb 8 *
snatch59 0:918566a376fb 9 * DebugTrace is free software: you can redistribute it and/or modify
snatch59 0:918566a376fb 10 * it under the terms of the GNU General Public License as published by
snatch59 0:918566a376fb 11 * the Free Software Foundation, either version 3 of the License, or
snatch59 0:918566a376fb 12 * (at your option) any later version.
snatch59 0:918566a376fb 13 *
snatch59 0:918566a376fb 14 * DebugTrace is distributed in the hope that it will be useful,
snatch59 0:918566a376fb 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
snatch59 0:918566a376fb 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
snatch59 0:918566a376fb 17 * GNU General Public License for more details.
snatch59 0:918566a376fb 18 *
snatch59 0:918566a376fb 19 * You should have received a copy of the GNU General Public License
snatch59 0:918566a376fb 20 * along with DebugTrace. If not, see <http://www.gnu.org/licenses/>.
snatch59 0:918566a376fb 21 */
snatch59 0:918566a376fb 22
snatch59 0:918566a376fb 23 #include "DebugTrace.h"
snatch59 0:918566a376fb 24 #include <mbed.h>
snatch59 0:918566a376fb 25 #include <stdarg.h>
snatch59 0:918566a376fb 26 #include <string.h>
snatch59 0:918566a376fb 27
snatch59 0:918566a376fb 28 Serial logSerial(USBTX, USBRX);
snatch59 0:918566a376fb 29 LocalFileSystem local("local");
snatch59 0:918566a376fb 30
snatch59 0:918566a376fb 31 const char* FILE_PATH = "/local/";
snatch59 0:918566a376fb 32 const char* EXTN = ".bak";
snatch59 0:918566a376fb 33
snatch59 0:918566a376fb 34 DebugTrace::DebugTrace(eLog on, eLogTarget mode, const char* fileName, int maxSize) :
snatch59 0:918566a376fb 35 enabled(on), logMode(mode), maxFileSize(maxSize), currentFileSize(0),
snatch59 0:918566a376fb 36 logFileStatus(0)
snatch59 0:918566a376fb 37 {
snatch59 0:918566a376fb 38 // allocate memory for file name strings
snatch59 0:918566a376fb 39 int str_size = (strlen(fileName) + strlen(FILE_PATH) + strlen(EXTN) + 1) * sizeof(char);
snatch59 0:918566a376fb 40 logFile = (char*)malloc(str_size);
snatch59 0:918566a376fb 41 logFileBackup = (char*)malloc(str_size);
snatch59 0:918566a376fb 42
snatch59 0:918566a376fb 43 // add path to log file name
snatch59 0:918566a376fb 44 strcpy(logFile, FILE_PATH);
snatch59 0:918566a376fb 45 strcat(logFile, fileName);
snatch59 0:918566a376fb 46
snatch59 0:918566a376fb 47 // create backup file name
snatch59 0:918566a376fb 48 strcpy(logFileBackup, logFile);
snatch59 0:918566a376fb 49 strcpy(logFileBackup, strtok(logFileBackup, "."));
snatch59 0:918566a376fb 50 strcat(logFileBackup, EXTN);
snatch59 0:918566a376fb 51 }
snatch59 0:918566a376fb 52
snatch59 0:918566a376fb 53 DebugTrace::~DebugTrace()
snatch59 0:918566a376fb 54 {
snatch59 0:918566a376fb 55 // dust to dust, ashes to ashes
snatch59 0:918566a376fb 56 if (logFile != NULL) free(logFile);
snatch59 0:918566a376fb 57 if (logFileBackup != NULL) free(logFileBackup);
snatch59 0:918566a376fb 58 }
snatch59 0:918566a376fb 59
snatch59 0:918566a376fb 60 void DebugTrace::clear()
snatch59 0:918566a376fb 61 {
snatch59 0:918566a376fb 62 // don't care about whether these fail
snatch59 0:918566a376fb 63 remove(logFile);
snatch59 0:918566a376fb 64 remove(logFileBackup);
snatch59 0:918566a376fb 65 }
snatch59 0:918566a376fb 66
snatch59 0:918566a376fb 67 void DebugTrace::backupLog()
snatch59 0:918566a376fb 68 {
snatch59 0:918566a376fb 69 // delete previous backup file
snatch59 0:918566a376fb 70 if (remove(logFileBackup))
snatch59 0:918566a376fb 71 {
snatch59 0:918566a376fb 72 // standard copy stuff
snatch59 0:918566a376fb 73 char ch;
snatch59 0:918566a376fb 74 FILE* to = fopen(logFileBackup, "wb");
snatch59 0:918566a376fb 75 if (NULL != to)
snatch59 0:918566a376fb 76 {
snatch59 0:918566a376fb 77 FILE* from = fopen(logFile, "rb");
snatch59 0:918566a376fb 78 if (NULL != from)
snatch59 0:918566a376fb 79 {
snatch59 0:918566a376fb 80 while(!feof(from))
snatch59 0:918566a376fb 81 {
snatch59 0:918566a376fb 82 ch = fgetc(from);
snatch59 0:918566a376fb 83 if (ferror(from)) break;
snatch59 0:918566a376fb 84
snatch59 0:918566a376fb 85 if(!feof(from)) fputc(ch, to);
snatch59 0:918566a376fb 86 if (ferror(to)) break;
snatch59 0:918566a376fb 87 }
snatch59 0:918566a376fb 88 }
snatch59 0:918566a376fb 89
snatch59 0:918566a376fb 90 if (NULL != from) fclose(from);
snatch59 0:918566a376fb 91 if (NULL != to) fclose(to);
snatch59 0:918566a376fb 92 }
snatch59 0:918566a376fb 93 }
snatch59 0:918566a376fb 94
snatch59 0:918566a376fb 95 // now delete the log file, so we are ready to start again
snatch59 0:918566a376fb 96 // even if backup creation failed - the show must go on!
snatch59 0:918566a376fb 97 logFileStatus = remove(logFile);
snatch59 0:918566a376fb 98 }
snatch59 0:918566a376fb 99
snatch59 0:918566a376fb 100 void DebugTrace::traceOut(const char* fmt, ...)
snatch59 0:918566a376fb 101 {
snatch59 0:918566a376fb 102 if (enabled)
snatch59 0:918566a376fb 103 {
snatch59 0:918566a376fb 104 va_list ap; // argument list pointer
snatch59 0:918566a376fb 105 va_start(ap, fmt);
snatch59 0:918566a376fb 106
snatch59 0:918566a376fb 107 if (TO_SERIAL == logMode)
snatch59 0:918566a376fb 108 {
snatch59 0:918566a376fb 109 vfprintf(logSerial, fmt, ap);
snatch59 0:918566a376fb 110 }
snatch59 0:918566a376fb 111 else // TO_FILE
snatch59 0:918566a376fb 112 {
snatch59 0:918566a376fb 113 if (0 == logFileStatus) // otherwise we failed to remove a full log file
snatch59 0:918566a376fb 114 {
snatch59 0:918566a376fb 115 // Write data to file. Note the file size may go over limit
snatch59 0:918566a376fb 116 // as we check total size afterwards, using the size written to file.
snatch59 0:918566a376fb 117 // This is not a big issue, as this mechanism is only here
snatch59 0:918566a376fb 118 // to stop the file growing unchecked. Just remember log file sizes may
snatch59 0:918566a376fb 119 // be some what over (as apposed to some what under), so don't push it
snatch59 0:918566a376fb 120 // with the max file size.
snatch59 0:918566a376fb 121 FILE* fp = fopen(logFile, "a");
snatch59 0:918566a376fb 122 if (NULL == fp)
snatch59 0:918566a376fb 123 {
snatch59 0:918566a376fb 124 va_end(ap);
snatch59 0:918566a376fb 125 return;
snatch59 0:918566a376fb 126 }
snatch59 0:918566a376fb 127 int size_written = vfprintf(fp, fmt, ap);
snatch59 0:918566a376fb 128 fclose(fp);
snatch59 0:918566a376fb 129
snatch59 0:918566a376fb 130 // check if we are over the max file size
snatch59 0:918566a376fb 131 // if so backup file and start again
snatch59 0:918566a376fb 132 currentFileSize += size_written;
snatch59 0:918566a376fb 133 if (currentFileSize >= maxFileSize)
snatch59 0:918566a376fb 134 {
snatch59 0:918566a376fb 135 backupLog();
snatch59 0:918566a376fb 136 currentFileSize = 0;
snatch59 0:918566a376fb 137 }
snatch59 0:918566a376fb 138 }
snatch59 0:918566a376fb 139 }
snatch59 0:918566a376fb 140
snatch59 0:918566a376fb 141 va_end(ap);
snatch59 0:918566a376fb 142 }
snatch59 0:918566a376fb 143 }