Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancements to LOGMODE=LIVE logging functionality #279

Merged
merged 1 commit into from
Sep 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions Firmware/Chameleon-Mini/Chameleon-Mini.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,19 @@ int main(void) {
if (SystemTick100ms()) {
LEDTick(); // this has to be the first function called here, since it is time-critical - the functions below may have non-negligible runtimes!
PinTick();

RandomTick();
TerminalTick();
ButtonTick();
LogTick();
ApplicationTick();
LogTick();
CommandLineTick();
AntennaLevelTick();

LEDHook(LED_POWERED, LED_ON);
}

TerminalTask();
LogTask();
ApplicationTask();
CodecTask();
LogTask();
TerminalTask();
}
}

1 change: 1 addition & 0 deletions Firmware/Chameleon-Mini/Chameleon-Mini.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "Random.h"
#include "Button.h"
#include "Log.h"
#include "LiveLogTick.h"
#include "AntennaLevel.h"
#include "Settings.h"

Expand Down
6 changes: 5 additions & 1 deletion Firmware/Chameleon-Mini/LUFAConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,16 @@
#define USE_FLASH_DESCRIPTORS
// #define USE_EEPROM_DESCRIPTORS
// #define NO_INTERNAL_SERIAL
#undef NO_INTERNAL_SERIAL
#define FIXED_CONTROL_ENDPOINT_SIZE 8
// #define DEVICE_STATE_AS_GPIOR {Insert Value Here}
#define FIXED_NUM_CONFIGURATIONS 1
// #define CONTROL_ONLY_DEVICE
#define MAX_ENDPOINT_INDEX 5
#ifndef MAX_ENDPOINT_INDEX
#define MAX_ENDPOINT_INDEX 4 // 5
#endif
// #define NO_DEVICE_REMOTE_WAKEUP
// #define NO_DEVICE_SELF_POWER
#undef NO_DEVICE_SELF_POWER

#endif
121 changes: 121 additions & 0 deletions Firmware/Chameleon-Mini/LiveLogTick.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/* 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 and prevent the contents of
* USB serial data from getting jumbled or concatenated.
*/

#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 *logBlockStart;
uint8_t logBlockSize;
struct LogBlockListNode *nextBlock;
} LogBlockListNode;

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 > LogMemLeft) && (LogMemPtr != LogMem)) {
if(FLUSH_LOGS_ON_SPACE_ERROR) {
LiveLogTick();
FreeLogBlocks();
}
status = false;
}
else if(logDataSize + 4 <= LogMemLeft) {
LogBlockListNode *logBlock = (LogBlockListNode *) malloc(sizeof(LogBlockListNode));
logBlock->logBlockStart = LogMemPtr;
logBlock->logBlockSize = logDataSize + 4;
logBlock->nextBlock = NULL;
*(LogMemPtr++) = logCode;
*(LogMemPtr++) = logDataSize;
*(LogMemPtr++) = (uint8_t) (sysTickTime >> 8);
*(LogMemPtr++) = (uint8_t) (sysTickTime >> 0);
memcpy(LogMemPtr, logData, logDataSize);
LogMemPtr += logDataSize;
LogMemLeft -= logDataSize + 4;
if(LogBlockListBegin != NULL && LogBlockListEnd != NULL) {
LogBlockListEnd->nextBlock = logBlock;
LogBlockListEnd = logBlock;
}
else {
LogBlockListBegin = LogBlockListEnd = logBlock;
}
++LogBlockListElementCount;
}
else {
status = false;
}
return status;
}

INLINE void
FreeLogBlocks(void) {
LogMemPtr = &LogMem[0];
LogBlockListNode *logBlockCurrent = LogBlockListBegin;
LogBlockListNode *logBlockNext = NULL;
while(logBlockCurrent != NULL) {
logBlockNext = logBlockCurrent->nextBlock;
LogMemLeft += logBlockCurrent->logBlockSize;
free(logBlockCurrent);
logBlockCurrent = logBlockNext;
}
LogBlockListBegin = LogBlockListEnd = NULL;
LogBlockListElementCount = 0;
}

INLINE bool
AtomicLiveLogTick(void) {
bool status;
status = LiveLogTick();
return status;
}

INLINE bool
LiveLogTick(void) {
bool status = LogBlockListBegin == NULL;
LogBlockListNode *logBlockCurrent = LogBlockListBegin;
while(logBlockCurrent != NULL && LogBlockListElementCount > 0) {
TerminalFlushBuffer();
TerminalSendBlock(logBlockCurrent->logBlockStart, logBlockCurrent->logBlockSize);
TerminalFlushBuffer();
logBlockCurrent = logBlockCurrent->nextBlock;
}
FreeLogBlocks();
LiveLogModePostTickCount = 0x00;
return status;
}

#endif
30 changes: 20 additions & 10 deletions Firmware/Chameleon-Mini/Log.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
#include "Log.h"
#include "LiveLogTick.h"
#include "Settings.h"
#include "Terminal/Terminal.h"
#include "System.h"
#include "Map.h"
#include "LEDHook.h"

static uint8_t LogMem[LOG_SIZE];
static uint8_t *LogMemPtr;
static uint16_t LogMemLeft;
uint8_t LogMem[LOG_SIZE];
uint8_t *LogMemPtr;
uint16_t LogMemLeft;

static uint16_t LogFRAMAddr = FRAM_LOG_START_ADDR;
static uint8_t EEMEM LogFRAMAddrValid = false;
static bool EnableLogSRAMtoFRAM = false;
LogFuncType CurrentLogFunc;

LogBlockListNode *LogBlockListBegin = NULL;
LogBlockListNode *LogBlockListEnd = NULL;
uint8_t LogBlockListElementCount = 0;
uint8_t LiveLogModePostTickCount = 0;

static const MapEntryType PROGMEM LogModeMap[] = {
{ .Id = LOG_MODE_OFF, .Text = "OFF" },
{ .Id = LOG_MODE_MEMORY, .Text = "MEMORY" },
{ .Id = LOG_MODE_LIVE, .Text = "LIVE" }
{ .Id = LOG_MODE_LIVE, .Text = "LIVE" }
};

static void LogFuncOff(LogEntryEnum Entry, const void *Data, uint8_t Length) {
Expand Down Expand Up @@ -50,12 +57,12 @@ static void LogFuncMemory(LogEntryEnum Entry, const void *Data, uint8_t Length)

static void LogFuncLive(LogEntryEnum Entry, const void *Data, uint8_t Length) {
uint16_t SysTick = SystemGetSysTick();

TerminalSendByte((uint8_t) Entry);
TerminalSendByte((uint8_t) Length);
TerminalSendByte((uint8_t)(SysTick >> 8));
TerminalSendByte((uint8_t)(SysTick >> 0));
TerminalSendBlock(Data, Length);
//TerminalSendByte((uint8_t) Entry);
//TerminalSendByte((uint8_t) Length);
//TerminalSendByte((uint8_t)(SysTick >> 8));
//TerminalSendByte((uint8_t)(SysTick >> 0));
//TerminalSendBlock(Data, Length);
AtomicAppendLogBlock(Entry, SysTick, Data, Length);
}

void LogInit(void) {
Expand All @@ -79,6 +86,9 @@ void LogInit(void) {
}

void LogTick(void) {
if (GlobalSettings.ActiveSettingPtr->LogMode == LOG_MODE_LIVE &&
(++LiveLogModePostTickCount % LIVE_LOGGER_POST_TICKS) == 0)
AtomicLiveLogTick();
if (EnableLogSRAMtoFRAM)
LogSRAMToFRAM();
}
Expand Down
4 changes: 4 additions & 0 deletions Firmware/Chameleon-Mini/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#define FRAM_LOG_START_ADDR 0x4002 // directly after the address
#define FRAM_LOG_SIZE 0x3FFE // the whole second half (minus the 2 Bytes of Address)

extern uint8_t LogMem[LOG_SIZE];
extern uint8_t *LogMemPtr;
extern uint16_t LogMemLeft;

/** Enum for log entry type. \note Every entry type has a specific integer value, which can be found in the source code. */
typedef enum {
/* Generic */
Expand Down
8 changes: 6 additions & 2 deletions Firmware/Chameleon-Mini/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,11 @@ SRC += Codec/ISO15693.c
SRC += Application/Vicinity.c Application/Sl2s2002.c Application/TITagitstandard.c Application/ISO15693-A.c Application/EM4233.c
SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
LUFA_PATH = ../LUFA
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -DFLASH_DATA_ADDR=$(FLASH_DATA_ADDR) -DFLASH_DATA_SIZE=$(FLASH_DATA_SIZE) -DSPM_HELPER_ADDR=$(SPM_HELPER_ADDR) -DBUILD_DATE=$(BUILD_DATE) -DCOMMIT_ID=\"$(COMMIT_ID)\" $(SETTINGS)
LD_FLAGS = -Wl,--section-start=.flashdata=$(FLASH_DATA_ADDR) -Wl,--section-start=.spmhelper=$(SPM_HELPER_ADDR)
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -DFLASH_DATA_ADDR=$(FLASH_DATA_ADDR) -DFLASH_DATA_SIZE=$(FLASH_DATA_SIZE) \
-DSPM_HELPER_ADDR=$(SPM_HELPER_ADDR) -DBUILD_DATE=$(BUILD_DATE) -DCOMMIT_ID=\"$(COMMIT_ID)\" $(SETTINGS) \
-D__AVR_ATxmega128A4U__ -D__PROG_TYPES_COMPAT__ -DMAX_ENDPOINT_INDEX=4 \
-std=gnu99 -Werror=implicit-function-declaration
LD_FLAGS = $(CC_FLAGS) -Wl,--section-start=.flashdata=$(FLASH_DATA_ADDR) -Wl,--section-start=.spmhelper=$(SPM_HELPER_ADDR)
OBJDIR = Bin
OBJECT_FILES =

Expand All @@ -128,6 +131,7 @@ AVRDUDE_WRITE_EEPROM_LATEST = -U eeprom:w:Latest/Chameleon-Mini.eep

# Default target
all:
$(CROSS)-size --mcu=atmega128 -C $(TARGET).elf

# Include LUFA build script makefiles
include $(LUFA_PATH)/Build/lufa_core.mk
Expand Down
18 changes: 9 additions & 9 deletions Firmware/Chameleon-Mini/Terminal/CommandLine.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ static const CommandStatusType PROGMEM StatusTable[] = {
STATUS_TABLE_ENTRY(COMMAND_ERR_TIMEOUT_ID, COMMAND_ERR_TIMEOUT),
};

static uint16_t BufferIdx;
uint16_t TerminalBufferIdx = 0;

void (*CommandLinePendingTaskTimeout)(void) = NO_FUNCTION; // gets called on Timeout
static bool TaskPending = false;
Expand Down Expand Up @@ -476,7 +476,7 @@ static void DecodeCommand(void) {
}

void CommandLineInit(void) {
BufferIdx = 0;
TerminalBufferIdx = 0;
}

bool CommandLineProcessByte(uint8_t Byte) {
Expand All @@ -487,24 +487,24 @@ bool CommandLineProcessByte(uint8_t Byte) {
}

/* Prevent buffer overflow and account for '\0' */
if (BufferIdx < TERMINAL_BUFFER_SIZE - 1) {
TerminalBuffer[BufferIdx++] = Byte;
if (TerminalBufferIdx < TERMINAL_BUFFER_SIZE - 1) {
TerminalBuffer[TerminalBufferIdx++] = Byte;
}
} else if (Byte == '\r') {
/* Process on \r. Terminate string and decode. */
TerminalBuffer[BufferIdx] = '\0';
BufferIdx = 0;
TerminalBuffer[TerminalBufferIdx] = '\0';
TerminalBufferIdx = 0;

if (!TaskPending)
DecodeCommand();
} else if (Byte == '\b') {
/* Backspace. Delete last character in buffer. */
if (BufferIdx > 0) {
BufferIdx--;
if (TerminalBufferIdx > 0) {
TerminalBufferIdx--;
}
} else if (Byte == 0x1B) {
/* Drop buffer on escape */
BufferIdx = 0;
TerminalBufferIdx = 0;
} else {
/* Ignore other chars */
}
Expand Down
2 changes: 1 addition & 1 deletion Firmware/Chameleon-Mini/Terminal/Terminal.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ USB_ClassInfo_CDC_Device_t TerminalHandle = {
}
};

uint8_t TerminalBuffer[TERMINAL_BUFFER_SIZE];
uint8_t TerminalBuffer[TERMINAL_BUFFER_SIZE] = { 0x00 };
TerminalStateEnum TerminalState = TERMINAL_UNINITIALIZED;
static uint8_t TerminalInitDelay = INIT_DELAY;

Expand Down
7 changes: 7 additions & 0 deletions Firmware/Chameleon-Mini/Terminal/Terminal.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ typedef enum {
} TerminalStateEnum;

extern uint8_t TerminalBuffer[TERMINAL_BUFFER_SIZE];
extern uint16_t TerminalBufferIdx;
extern USB_ClassInfo_CDC_Device_t TerminalHandle;
extern TerminalStateEnum TerminalState;

Expand All @@ -49,4 +50,10 @@ void EVENT_USB_Device_ControlRequest(void);
INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); }
INLINE void TerminalSendByte(uint8_t Byte) { CDC_Device_SendByte(&TerminalHandle, Byte); }

INLINE void TerminalFlushBuffer(void) {
CDC_Device_Flush(&TerminalHandle);
TerminalBufferIdx = 0;
TerminalBuffer[TerminalBufferIdx] = '\0';
}

#endif /* TERMINAL_H_ */