This repository was archived by the owner on Mar 16, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathLiveLogTick.h
146 lines (125 loc) · 4.9 KB
/
LiveLogTick.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
The DESFire stack portion of this firmware source
is free software written by Maxie Dion Schmidt (@maxieds):
You can redistribute it and/or modify
it under the terms of this license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The complete source distribution of
this firmware is available at the following link:
https://github.com/maxieds/ChameleonMiniFirmwareDESFireStack.
Based in part on the original DESFire code created by
@dev-zzo (GitHub handle) [Dmitry Janushkevich] available at
https://github.com/dev-zzo/ChameleonMini/tree/desfire.
This notice must be retained at the top of all source files where indicated.
*/
/* LiveLogTick.h : Handle flushing of live logging buffers out through USB
* by an atomic code block with interrupts disabled.
* If there are many logs being generated at once, this will maintain
* consistency in the returned buffers.
*/
#ifndef __LIVE_LOG_TICK_H__
#define __LIVE_LOG_TICK_H__
#include <inttypes.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/atomic.h>
#include "LUFADescriptors.h"
#include "Log.h"
#include "Terminal/Terminal.h"
#define cli_memory() __asm volatile( "cli" ::: "memory" )
#define sei_memory() __asm volatile( "sei" ::: "memory" )
#ifndef FLUSH_LOGS_ON_SPACE_ERROR
#define FLUSH_LOGS_ON_SPACE_ERROR (1)
#endif
typedef struct LogBlockListNode {
uint8_t *logBlockDataStart;
uint8_t logBlockDataSize;
struct LogBlockListNode *nextBlock;
} LogBlockListNode;
#define LOG_BLOCK_LIST_NODE_SIZE (sizeof(LogBlockListNode) + 4 - (uint8_t) (sizeof(LogBlockListNode) % 4))
extern LogBlockListNode *LogBlockListBegin;
extern LogBlockListNode *LogBlockListEnd;
extern uint8_t LogBlockListElementCount;
#define LIVE_LOGGER_POST_TICKS (3)
extern uint8_t LiveLogModePostTickCount;
INLINE bool AtomicAppendLogBlock(LogEntryEnum logCode, uint16_t sysTickTime, const uint8_t *logData, uint8_t logDataSize);
INLINE void FreeLogBlocks(void);
INLINE bool AtomicLiveLogTick(void);
INLINE bool LiveLogTick(void);
INLINE bool
AtomicAppendLogBlock(LogEntryEnum logCode, uint16_t sysTickTime, const uint8_t *logData, uint8_t logDataSize) {
bool status = true;
if((logDataSize + 4 + 3 + LOG_BLOCK_LIST_NODE_SIZE > LogMemLeft) && (LogMemPtr != LogMem)) {
if(FLUSH_LOGS_ON_SPACE_ERROR) {
LiveLogTick();
FreeLogBlocks();
}
status = false;
}
else if(logDataSize + 4 + 3 + LOG_BLOCK_LIST_NODE_SIZE <= LogMemLeft) {
uint8_t alignOffset = 4 - (uint8_t) (((uint16_t) LogMemPtr) % 4);
uint8_t *logBlockStart = LogMemPtr + alignOffset;
LogBlockListNode logBlock;
LogMemPtr += LOG_BLOCK_LIST_NODE_SIZE + alignOffset;
LogMemLeft -= LOG_BLOCK_LIST_NODE_SIZE + alignOffset;
logBlock.logBlockDataStart = LogMemPtr;
logBlock.logBlockDataSize = logDataSize + 4;
logBlock.nextBlock = 0;
*(LogMemPtr++) = (uint8_t) logCode;
*(LogMemPtr++) = logDataSize;
*(LogMemPtr++) = (uint8_t) (sysTickTime >> 8);
*(LogMemPtr++) = (uint8_t) (sysTickTime >> 0);
memcpy(LogMemPtr, logData, logDataSize);
LogMemPtr += logDataSize;
LogMemLeft -= logDataSize + 4;
memcpy(logBlockStart, &logBlock, sizeof(LogBlockListNode));
if(LogBlockListBegin != NULL && LogBlockListEnd != NULL) {
LogBlockListEnd->nextBlock = (LogBlockListNode *) logBlockStart;
LogBlockListEnd = (LogBlockListNode *) logBlockStart;
}
else {
LogBlockListBegin = LogBlockListEnd = (LogBlockListNode *) logBlockStart;
}
++LogBlockListElementCount;
}
else {
status = false;
}
return status;
}
INLINE void
FreeLogBlocks(void) {
LogMemPtr = &LogMem[0];
LogMemLeft = LOG_SIZE;
LogBlockListBegin = LogBlockListEnd = NULL;
LogBlockListElementCount = 0;
}
INLINE bool
AtomicLiveLogTick(void) {
return LiveLogTick();
}
INLINE bool
LiveLogTick(void) {
LogBlockListNode logBlockCurrent, *tempBlockPtr = NULL;
memcpy(&logBlockCurrent, LogBlockListBegin, sizeof(LogBlockListNode));
while(LogBlockListElementCount > 0) {
TerminalFlushBuffer();
TerminalSendBlock(logBlockCurrent.logBlockDataStart, logBlockCurrent.logBlockDataSize);
TerminalFlushBuffer();
tempBlockPtr = logBlockCurrent.nextBlock;
if(tempBlockPtr != NULL) {
memcpy(&logBlockCurrent, tempBlockPtr, sizeof(LogBlockListNode));
}
else {
break;
}
--LogBlockListElementCount;
}
FreeLogBlocks();
LiveLogModePostTickCount = 0;
return true;
}
#endif