Chameleon-Mini
LiveLogTick.h
1 /* LiveLogTick.h : Handle flushing of live logging buffers out through USB
2  * by an atomic code block with interrupts disabled.
3  * If there are many logs being generated at once, this will maintain
4  * consistency in the returned buffers and prevent the contents of
5  * USB serial data from getting jumbled or concatenated.
6  */
7 
8 #ifndef __LIVE_LOG_TICK_H__
9 #define __LIVE_LOG_TICK_H__
10 
11 #include <inttypes.h>
12 #include <stdlib.h>
13 #include <avr/interrupt.h>
14 #include <avr/io.h>
15 #include <util/atomic.h>
16 
17 #include "LUFADescriptors.h"
18 
19 #include "Log.h"
20 #include "Terminal/Terminal.h"
21 
22 #define cli_memory() __asm volatile( "cli" ::: "memory" )
23 #define sei_memory() __asm volatile( "sei" ::: "memory" )
24 
25 #ifndef FLUSH_LOGS_ON_SPACE_ERROR
26 #define FLUSH_LOGS_ON_SPACE_ERROR (1)
27 #endif
28 typedef struct LogBlockListNode {
29  uint8_t *logBlockDataStart;
30  uint8_t logBlockDataSize;
31  struct LogBlockListNode *nextBlock;
32 } LogBlockListNode;
33 
34 #define LOG_BLOCK_LIST_NODE_SIZE (sizeof(LogBlockListNode) + 4 - (uint8_t) (sizeof(LogBlockListNode) % 4))
35 extern LogBlockListNode *LogBlockListBegin;
36 extern LogBlockListNode *LogBlockListEnd;
37 extern uint8_t LogBlockListElementCount;
38 
39 #define LIVE_LOGGER_POST_TICKS (6)
40 extern uint8_t LiveLogModePostTickCount;
41 
42 INLINE bool AtomicAppendLogBlock(LogEntryEnum logCode, uint16_t sysTickTime, const uint8_t *logData, uint8_t logDataSize);
43 INLINE void FreeLogBlocks(void);
44 INLINE bool AtomicLiveLogTick(void);
45 INLINE bool LiveLogTick(void);
46 
47 INLINE bool
48 AtomicAppendLogBlock(LogEntryEnum logCode, uint16_t sysTickTime, const uint8_t *logData, uint8_t logDataSize) {
49  bool status = true;
50  if ((logDataSize + 4 + 3 + LOG_BLOCK_LIST_NODE_SIZE > LogMemLeft) && (LogMemPtr != LogMem)) {
51  if (FLUSH_LOGS_ON_SPACE_ERROR) {
52  LiveLogTick();
53  FreeLogBlocks();
54  }
55  status = false;
56  } else if (logDataSize + 4 + 3 + LOG_BLOCK_LIST_NODE_SIZE <= LogMemLeft) {
57  uint8_t alignOffset = 4 - (uint8_t)(((uint16_t) LogMemPtr) % 4);
58  uint8_t *logBlockStart = LogMemPtr + alignOffset;
59  LogBlockListNode logBlock;
60  LogMemPtr += LOG_BLOCK_LIST_NODE_SIZE + alignOffset;
61  LogMemLeft -= LOG_BLOCK_LIST_NODE_SIZE + alignOffset;
62  logBlock.logBlockDataStart = LogMemPtr;
63  logBlock.logBlockDataSize = logDataSize + 4;
64  logBlock.nextBlock = 0;
65  *(LogMemPtr++) = (uint8_t) logCode;
66  *(LogMemPtr++) = logDataSize;
67  *(LogMemPtr++) = (uint8_t)(sysTickTime >> 8);
68  *(LogMemPtr++) = (uint8_t)(sysTickTime >> 0);
69  memcpy(LogMemPtr, logData, logDataSize);
70  LogMemPtr += logDataSize;
71  LogMemLeft -= logDataSize + 4;
72  memcpy(logBlockStart, &logBlock, sizeof(LogBlockListNode));
73  if (LogBlockListBegin != NULL && LogBlockListEnd != NULL) {
74  LogBlockListEnd->nextBlock = (LogBlockListNode *) logBlockStart;
75  LogBlockListEnd = (LogBlockListNode *) logBlockStart;
76  } else {
77  LogBlockListBegin = LogBlockListEnd = (LogBlockListNode *) logBlockStart;
78  }
79  ++LogBlockListElementCount;
80  } else {
81  status = false;
82  }
83  return status;
84 }
85 
86 INLINE void
87 FreeLogBlocks(void) {
88  LogMemPtr = &LogMem[0];
89  LogMemLeft = LOG_SIZE;
90  LogBlockListBegin = LogBlockListEnd = NULL;
91  LogBlockListElementCount = 0;
92 }
93 
94 INLINE bool
95 AtomicLiveLogTick(void) {
96  return LiveLogTick();
97 }
98 
99 INLINE bool
100 LiveLogTick(void) {
101  LogBlockListNode logBlockCurrent, *tempBlockPtr = NULL;
102  memcpy(&logBlockCurrent, LogBlockListBegin, sizeof(LogBlockListNode));
103  while (LogBlockListElementCount > 0) {
104  TerminalFlushBuffer();
105  TerminalSendBlock(logBlockCurrent.logBlockDataStart, logBlockCurrent.logBlockDataSize);
106  TerminalFlushBuffer();
107  tempBlockPtr = logBlockCurrent.nextBlock;
108  if (tempBlockPtr != NULL) {
109  memcpy(&logBlockCurrent, tempBlockPtr, sizeof(LogBlockListNode));
110  } else {
111  break;
112  }
113  --LogBlockListElementCount;
114  }
115  FreeLogBlocks();
116  LiveLogModePostTickCount = 0;
117  return true;
118 }
119 
120 #endif
LogEntryEnum
Definition: Log.h:16