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