SAE Teensy ECU
IIT SAE Microcontroller programming
Loading...
Searching...
No Matches
Log.cpp
Go to the documentation of this file.
1
12// @cond
13
14#include <cstring>
15#include <stdarg.h>
16#include <stdio.h>
17
18#include "Canbus.h"
19#include "ECUGlobalConfig.h"
20#include "Log.h"
21#include "LogConfig.def"
22#include "map"
23
27extern unsigned char log_lookup[];
28
32extern unsigned int log_lookup_len;
33
37extern unsigned int log_lookup_pad_len;
38
42extern unsigned int log_lookup_uncmp_len;
43
44namespace Logging {
45
46#ifdef SILENT
47#ifdef CONF_LOGGING_MAX_LEVEL
48#undef CONF_LOGGING_MAX_LEVEL
49#endif
50#define CONF_LOGGING_MAX_LEVEL 0
51#endif
52
53#ifndef CONF_LOGGING_MAX_LEVEL
54#define CONF_LOGGING_MAX_LEVEL 4
55#endif
56
57#if CONF_LOGGING_MAX_LEVEL >= 5
58#define __LOGGER_NONE_PRINT
59#define __LOGGER_DEBUG_PRINT
60#define __LOGGER_INFO_PRINT
61#define __LOGGER_WARN_PRINT
62#define __LOGGER_ERROR_PRINT
63#define __LOGGER_FATAL_PRINT
64#elif CONF_LOGGING_MAX_LEVEL == 4
65#define __LOGGER_NONE_PRINT
66#define __LOGGER_INFO_PRINT
67#define __LOGGER_WARN_PRINT
68#define __LOGGER_ERROR_PRINT
69#define __LOGGER_FATAL_PRINT
70#elif CONF_LOGGING_MAX_LEVEL == 3
71#define __LOGGER_NONE_PRINT
72#define __LOGGER_WARN_PRINT
73#define __LOGGER_ERROR_PRINT
74#define __LOGGER_FATAL_PRINT
75#elif CONF_LOGGING_MAX_LEVEL == 2
76#define __LOGGER_WARN_PRINT
77#define __LOGGER_ERROR_PRINT
78#define __LOGGER_FATAL_PRINT
79#elif CONF_LOGGING_MAX_LEVEL == 1
80#define __LOGGER_ERROR_PRINT
81#define __LOGGER_FATAL_PRINT
82#endif
83
84#if CONF_LOGGING_MAPPED_MODE > 0
85
86struct uMsg {
87 uint32_t LAST_NUMBER = 0;
88 elapsedMillis last;
89 bool update(uint32_t newNum, int mediate) { // TODO: Add to infographic mediate functionality
97 if ((mediate >= 1 && newNum != LAST_NUMBER) || (mediate > 1 && (int)last > mediate) || (mediate < 0 && ((int)last > -mediate && newNum != LAST_NUMBER))) {
98 last = 0;
99 LAST_NUMBER = newNum;
100 return true;
101 }
102 return false;
103 }
104};
105
106struct uTag {
107 std::map<uint32_t, uMsg> uniqueMessages;
108 bool update(uint32_t msg, uint32_t num, int mediate) {
109 return uniqueMessages[msg].update(num, mediate);
110 }
111};
112
113static std::map<uint16_t, uTag> uniqueTags;
114
115// No Timestamping for this mode
116
117// Do this to use the same fuction header, we don't need these for mapped logging
118static void *NONE;
119static void *DEBUG = NONE;
120static void *INFO = NONE;
121static void *WARN = NONE;
122static void *ERROR = NONE;
123static void *FATAL = NONE;
124
125static uint8_t log_buf[8] = {0};
126
131static void __logger_print_num(void *TYPE, LOG_TAG TAG, LOG_MSG MESSAGE, const uint32_t NUMBER, int mediate) {
132 if (!mediate || uniqueTags[TAG].update(MESSAGE, NUMBER, mediate)) {
133 memcpy(log_buf, &TAG, 2);
134 memcpy(log_buf + 2, &MESSAGE, 2);
135 memcpy(log_buf + 4, &NUMBER, 4);
136#if CONF_ECU_POSITION == BACK_ECU
137#ifdef CONF_ECU_DEBUG
138 Serial.write(log_buf, 8);
139#endif
140 Canbus::sendData(ADD_AUX_LOGGING, log_buf);
141#else
142 Serial.write(log_buf, 8);
143#endif
144 }
145}
146
151static void __logger_print(void *TYPE, LOG_TAG TAG, LOG_MSG MESSAGE) {
152 __logger_print_num(TYPE, TAG, MESSAGE, 0, 0);
153}
154
155#else
156
157#ifdef __LOGGER_NONE_PRINT
158static const char *NONE = "[ LOG ]";
159#ifdef __LOGGER_DEBUG_PRINT
160static const char *DEBUG = "[DEBUG]";
161#endif
162#ifdef __LOGGER_INFO_PRINT
163static const char *INFO = "[INFO] ";
164#endif
165#ifdef __LOGGER_WARN_PRINT
166static const char *WARN = "[WARN] ";
167#endif
168#ifdef __LOGGER_ERROR_PRINT
169static const char *ERROR = "[ERROR]";
170#endif
171#ifdef __LOGGER_FATAL_PRINT
172static const char *FATAL = "[FATAL]";
173#endif
174
175#ifdef CONF_LOGGING_ENABLE_TIMESTAMP
176static const char *FORMAT = "%s @ %u [%s]: %s\n";
177static const char *FORMAT_NUM = "%s @ %u [%s]: %s %u\n";
178static void __logger_print(const char *TYPE, LOG_TAG TAG, LOG_MSG MESSAGE) { Serial.printf(FORMAT, TYPE, millis(), TAG, MESSAGE); }
179static void __logger_print_num(const char *TYPE, LOG_TAG TAG, LOG_MSG MESSAGE, const uint32_t NUMBER, int mediate = false) { Serial.printf(FORMAT_NUM, TYPE, millis(), TAG, MESSAGE, NUMBER); }
180#else
181static const char *FORMAT = "%s [%s]: %s\n";
182static const char *FORMAT_NUM = "%s [%s]: %s %u\n";
183static void __logger_print(const char *TYPE, LOG_TAG TAG, LOG_MSG MESSAGE) { Serial.printf(FORMAT, TYPE, TAG, MESSAGE); }
184static void __logger_print_num(const char *TYPE, LOG_TAG TAG, LOG_MSG MESSAGE, const uint32_t NUMBER, int mediate = false) { Serial.printf(FORMAT_NUM, TYPE, TAG, MESSAGE, NUMBER); }
185#endif
186#endif
187
188#endif
189
190void Log_t::operator()(LOG_TAG TAG, LOG_MSG message) {
191#ifdef __LOGGER_NONE_PRINT
192 __logger_print(NONE, TAG, message);
193#endif
194}
195
196void Log_t::d(LOG_TAG TAG, LOG_MSG message) {
197#ifdef __LOGGER_DEBUG_PRINT
198 __logger_print(DEBUG, TAG, message);
199#endif
200}
201
202void Log_t::i(LOG_TAG TAG, LOG_MSG message) {
203#ifdef __LOGGER_INFO_PRINT
204 __logger_print(INFO, TAG, message);
205#endif
206}
207
208void Log_t::w(LOG_TAG TAG, LOG_MSG message) {
209#ifdef __LOGGER_WARN_PRINT
210 __logger_print(WARN, TAG, message);
211#endif
212}
213
214void Log_t::e(LOG_TAG TAG, LOG_MSG message) {
215#ifdef __LOGGER_ERROR_PRINT
216 __logger_print(ERROR, TAG, message);
217#endif
218}
219
220void Log_t::f(LOG_TAG TAG, LOG_MSG message) {
221#ifdef __LOGGER_FATAL_PRINT
222 __logger_print(FATAL, TAG, message);
223#endif
224}
225
226void Log_t::operator()(LOG_TAG TAG, LOG_MSG message, const uint32_t number, int mediate) {
227#ifdef __LOGGER_NONE_PRINT
228 __logger_print_num(NONE, TAG, message, number, mediate);
229#endif
230}
231
232void Log_t::d(LOG_TAG TAG, LOG_MSG message, const uint32_t number, int mediate) {
233#ifdef __LOGGER_DEBUG_PRINT
234 __logger_print_num(DEBUG, TAG, message, number, mediate);
235#endif
236}
237
238void Log_t::i(LOG_TAG TAG, LOG_MSG message, const uint32_t number, int mediate) {
239#ifdef __LOGGER_INFO_PRINT
240 __logger_print_num(INFO, TAG, message, number, mediate);
241#endif
242}
243
244void Log_t::w(LOG_TAG TAG, LOG_MSG message, const uint32_t number, int mediate) {
245#ifdef __LOGGER_WARN_PRINT
246 __logger_print_num(WARN, TAG, message, number, mediate);
247#endif
248}
249
250void Log_t::e(LOG_TAG TAG, LOG_MSG message, const uint32_t number, int mediate) {
251#ifdef __LOGGER_ERROR_PRINT
252 __logger_print_num(ERROR, TAG, message, number, mediate);
253#endif
254}
255
256void Log_t::f(LOG_TAG TAG, LOG_MSG message, const uint32_t number, int mediate) {
257#ifdef __LOGGER_FATAL_PRINT
258 __logger_print_num(FATAL, TAG, message, number, mediate);
259#endif
260}
261
262void Log_t::p(LOG_TAG name, LOG_MSG prettyName, const uint32_t number, int mediate) {
263 __logger_print_num(FATAL, name, prettyName, number, mediate);
264}
265
266static void _receiveLogBuffer(uint32_t address, volatile uint8_t *buf) {
267 Serial.write((uint8_t *)buf, 8); // FIXME: does dropping the volatile cause any issues?
268}
269
270void enableCanbusRelay() {
271 Canbus::addCallback(ADD_AUX_LOGGING, _receiveLogBuffer);
272}
273
274void printLookup() {
275 static elapsedMillis timeElapsed;
276 noInterrupts();
277 Serial.flush();
278 uint64_t ullen = 0;
279 uint8_t *bytes = (uint8_t *)&(ullen);
280 Serial.write(bytes, 8);
281 ullen = log_lookup_len;
282 Serial.write(bytes, 8);
283 ullen = log_lookup_uncmp_len;
284 Serial.write(bytes, 8);
285 timeElapsed = 0;
286 for (size_t i = 0; i < log_lookup_pad_len; i += 8) {
287 Serial.write(log_lookup + i, 8);
288 Serial.flush();
289 while (!Serial.available()) {
290 if (timeElapsed > 31000) { // Entire process should take less than 30s
291 interrupts();
292 return;
293 }
294 }
295 Serial.read();
296 }
297 interrupts();
298}
299
300} // namespace Logging
301
306
307#if CONF_LOGGING_MAPPED_MODE > 0
308uint32_t TAG2NUM(LOG_TAG tagValue) {
309 return tagValue;
310}
311#else
312uint32_t TAG2NUM(LOG_TAG tagValue) {
313 return 0;
314}
315#endif
316
317// @endcond
FlexCAN_T4 wrapper.
Configure global build properties.
Special logging functionality.
uint32_t TAG2NUM(LOG_TAG tagValue)
Return the final numbervalue of a LOG_TAG.
const char * LOG_MSG
Type definition for logging messages, only used internally.
Definition Log.h:52
const char * LOG_TAG
Type definition of logging tags This typedef is necessary to allow for easier manipulation of code by...
Definition Log.h:48
Logging::Log_t Log
The global logging object.
Configuration file for the Log Module.
Namespace to isolate Log_t struct.
Definition Log.h:69
void enableCanbusRelay()
If a set address is received through canbus, the data will be pushed to a buffer to be printed.
void printLookup()
Print the ZLib compressed string of the current lookup table to serial.
void update(void)
Poll analog pin values.
Base class used to log things over serial.
Definition Log.h:157
void operator()(LOG_TAG TAG, LOG_MSG message)
Log a string usb serial.
void d(LOG_TAG TAG, LOG_MSG message)
Log a string using a debug tag.
void w(LOG_TAG TAG, LOG_MSG message)
Log a string using a warning tag.
void e(LOG_TAG TAG, LOG_MSG message)
Log a string using an error tag.
void i(LOG_TAG TAG, LOG_MSG message)
Log a string using an info tag.
void p(LOG_TAG name, LOG_MSG prettyName, const uint32_t number, int mediate=false)
Post a monitored value.
void f(LOG_TAG TAG, LOG_MSG message)
Log a string using a fatal tag.