Fixed issues with the logger and brought logger to same structure as the rest - now the logger is a independent object

Added testItems to HwValidationMenu for SWo

git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@235 05563f52-14a8-4384-a975-3d1654cca0fa
This commit is contained in:
mmi
2017-10-05 07:49:28 +00:00
parent 955d695720
commit c860b5b3b4
17 changed files with 283 additions and 258 deletions

View File

@@ -25,6 +25,8 @@
<option id="gnu.c.compiler.option.debugging.level.1951365338" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="gnu.c.compiler.option.include.paths.35161744" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/Platform/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/FreeRTOS/Source/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/hsb-mrts/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x}&quot;"/>
@@ -124,4 +126,5 @@
<path value=""/>
</doc-comment-owner>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cproject>

View File

@@ -5,7 +5,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-103770239591" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="1404919128665" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -16,7 +16,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-103770239591" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="1404919128665" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>

View File

@@ -11,7 +11,7 @@ ROOTDIR = ../
LIBRARY_NAME = libHAL.a
CCFLAGS = -c -O2 -Wall -g -fno-common -mcpu=cortex-m3 -mthumb $(PLATFORM) $(RELEASE_DEFINES) \
CCFLAGS = -c -O2 -Wall -g -fno-common -mcpu=cortex-m3 -mthumb $(PLATFORM) $(RELEASE_DEFINES) $(ADDITIONAL_SWITCHES) \
-Iinc \
-I$(ROOTDIR)/Platform/inc \
-I$(ROOTDIR)/hsb-mrts/inc \
@@ -24,6 +24,7 @@ ARFLAGS = rs
OBJECTS = \
DisplayDevice.o \
Logger.o \
MAX5715.o \
nhd0420.o

View File

@@ -0,0 +1,142 @@
// -----------------------------------------------------------------------------
/// @file Logger.h
/// @brief File description
// -----------------------------------------------------------------------------
// Micro-Key bv
// Industrieweg 28, 9804 TG Noordhorn
// Postbus 92, 9800 AB Zuidhorn
// The Netherlands
// Tel: +31 594 503020
// Fax: +31 594 505825
// Email: support@microkey.nl
// Web: www.microkey.nl
// -----------------------------------------------------------------------------
/// $Revision$
/// $Author$
/// $Date$
// (c) 2017 Micro-Key bv
// -----------------------------------------------------------------------------
/// @defgroup {group_name} {group_description}
/// Description
/// @file Logger.h
/// @ingroup {group_name}
#ifndef _LOGGER_H_
#define _LOGGER_H_
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include "stm32f10x.h"
#include <stdbool.h>
#include "FreeRTOS.h"
#include "semphr.h"
#include "queue.h"
#include "task.h"
#include "platform.h"
#include "IODevice.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
/**
* Logs an error
* \memberof Logger
*/
#define LOGGER_ERROR(a, ...) \
Logger_log(a, __FILE__, __func__, __LINE__, LOGTYPE_ERROR, ##__VA_ARGS__)
#define LOGGER_WARNING(a, ...) \
Logger_log(a, __FILE__, __func__, __LINE__, LOGTYPE_WARNING, ##__VA_ARGS__)
#define LOGGER_INFO(a, ...) \
Logger_log(a, __FILE__, __func__, __LINE__, LOGTYPE_INFO, ##__VA_ARGS__)
#define LOGGER_DEBUG(a, ...) \
Logger_log(a, __FILE__, __func__, __LINE__, LOGTYPE_DEBUG, ##__VA_ARGS__)
#define LOGGER_PRINT(a, ...) \
Logger_log(a, "", "", 0, LOGTYPE_PRINT, ##__VA_ARGS__)
#define LOGGER_ERROR_ISR(a, ...) \
Logger_logISR(a, __FILE__, __func__, __LINE__, LOGTYPE_ERROR, ##__VA_ARGS__)
#define LOGGER_WARNING_ISR(a, ...) \
Logger_logISR(a, __FILE__, __func__, __LINE__, LOGTYPE_WARNING, ##__VA_ARGS__)
#define LOGGER_INFO_ISR(a, ...) \
Logger_logISR(a, __FILE__, __func__, __LINE__, LOGTYPE_INFO, ##__VA_ARGS__)
#define LOGGER_DEBUG_ISR(a, ...) \
Logger_logISR(a, __FILE__, __func__, __LINE__, LOGTYPE_DEBUG, ##__VA_ARGS__)
#define LOGGER_PRINT_ISR(a, ...) \
Logger_logISR(a, "", "", 0, LOGTYPE_PRINT, ##__VA_ARGS__)
// -----------------------------------------------------------------------------
// Type definitions.
// -----------------------------------------------------------------------------
typedef enum
{
LOGTYPE_PRINT, /**< Raw print */
LOGTYPE_DEBUG, /**< Debug information only; will not be stored on SD-card */
LOGTYPE_INFO, /**< Informational messages of important events */
LOGTYPE_WARNING, /**< Recoverable fault */
LOGTYPE_ERROR /**< Unrecoverable fault */
} LogType;
struct LogQueueItem
{
char fileName[32];
char functionName[32];
char context[128];
int lineNumber;
LogType logType;
};
struct Logger
{
struct IODevice* loggingDevice;
TaskHandle_t taskHandle;
int TaskPriority;
uint16_t stackSize;
bool runTask;
QueueHandle_t logQueue;
bool initialized;
};
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
extern ErrorStatus Logger_construct(struct Logger* self, struct IODevice* const device, int taskPriority, uint16_t stackSize);
extern void Logger_terminate(struct Logger* self);
void Logger_logISR(struct Logger* self, const char* fileName, const char* functionName, int lineNumber, LogType logType, const char* context);
/**
* Logs a string.
* Use the Logging macros instead
* \memberof Logger
* \private
* \param fileName File name to be logged
* \param functionName Function name to be logged
* \param lineNumber Line number to be logged
* \param logType Type of logging
* \param format printf-type formatting string
* \param ... Variable arguments according to the formatting string
*/
void Logger_log(struct Logger* self, const char* fileName, const char* functionName, int lineNumber, LogType logType, const char* format, ...) __attribute__((format(printf, 6, 7)));
#endif

View File

@@ -0,0 +1,301 @@
// -----------------------------------------------------------------------------
/// @file Logger.c
/// @brief Description
// -----------------------------------------------------------------------------
// Micro-Key bv
// Industrieweg 28, 9804 TG Noordhorn
// Postbus 92, 9800 AB Zuidhorn
// The Netherlands
// Tel: +31 594 503020
// Fax: +31 594 505825
// Email: support@microkey.nl
// Web: www.microkey.nl
// -----------------------------------------------------------------------------
/// $Revision$
/// $Author$
/// $Date$
// (c) 2017 Micro-Key bv
// -----------------------------------------------------------------------------
/// @file main.c
/// @ingroup {group_name}
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include <FreeRTOSFixes.h>
#include "FreeRTOS.h"
#include "Logger.h"
#include "semphr.h"
#include "queue.h"
#include "task.h"
#include "misc.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
#include "uart.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
#define LOGQUEUE_SIZE (24)
// Makefile compile options:
// ENABLE_SERIAL_LOGGING: Use the serial port for logging.
#if defined(ENABLE_SERIAL_LOGGING)
#define ENABLE_LOGGING
#else
#undef ENABLE_LOGGING
#endif
// -----------------------------------------------------------------------------
// Type definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// File-scope variables
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
static void composeLogQueueItem(struct LogQueueItem* logQueueItem, const char* fileName, const char* functionName,
int lineNumber, LogType logType, const char* context);
static void loggerTask(void* parameters);
// -----------------------------------------------------------------------------
// Function definitions
// -----------------------------------------------------------------------------
ErrorStatus Logger_construct(struct Logger* self, struct IODevice* const device, int taskPriority, uint16_t stackSize)
{
ErrorStatus returnValue = SUCCESS;
if (!self->initialized)
{
self->loggingDevice = device;
self->TaskPriority = taskPriority;
self->stackSize = stackSize;
if(returnValue == SUCCESS)
{
self->logQueue = xQueueCreate(LOGQUEUE_SIZE, sizeof(struct LogQueueItem));
if(self->logQueue == 0)
{
returnValue = ERROR;
}
}
if(returnValue == SUCCESS)
{
if(xTaskCreate(loggerTask, (const char*)"loggerTask", self->stackSize, self, self->TaskPriority, &self->taskHandle) != pdPASS)
{
returnValue = ERROR;
}
}
if(returnValue == SUCCESS)
{
LOGGER_INFO(self, "Logger started");
self->initialized = true;
}
}
return returnValue;
}
void Logger_destruct(struct Logger* self)
{
self->initialized = false;
}
void Logger_log(struct Logger* self, const char* fileName, const char* functionName, int lineNumber, LogType logType, const char* format, ...)
{
#if defined(ENABLE_LOGGING)
static int nrLostMessages = 0;
static bool overflowRecovery = false;
int nrOfMessages;
struct LogQueueItem logQueueItem;
va_list ap;
if (self->initialized)
{
nrOfMessages = uxQueueMessagesWaiting(&self->logQueue);
if((nrOfMessages == LOGQUEUE_SIZE - 1) && !overflowRecovery)
{
// Queue almost full, only one entry left. Log a warning instead
composeLogQueueItem(&logQueueItem, __FILE__, __func__, __LINE__, LOGTYPE_WARNING, "Log queue overflow");
(void)xQueueSend(self->logQueue, &logQueueItem, 0);
overflowRecovery = true;
nrLostMessages = 1;
}
else if((nrOfMessages == 0) && overflowRecovery)
{
// Queue empty again after an overflow
char str[128];
snprintf(str, sizeof(str) / sizeof(str[0]), "%d messages lost", nrLostMessages);
composeLogQueueItem(&logQueueItem, __FILE__, __func__, __LINE__, LOGTYPE_WARNING, str);
(void)xQueueSend(self->logQueue, &logQueueItem, 0);
overflowRecovery = false;
}
else if(!overflowRecovery)
{
// Normal behaviour, queue not full
char str[128];
va_start(ap, format);
vsnprintf(str, sizeof(str) / sizeof(str[0]), format, ap);
va_end(ap);
composeLogQueueItem(&logQueueItem, fileName, functionName, lineNumber, logType, str);
(void)xQueueSend(self->logQueue, &logQueueItem, 0);
}
else
{
// Count number of lost messages
++nrLostMessages;
}
}
#endif
}
void Logger_logISR(struct Logger* self, const char* fileName, const char* functionName, int lineNumber, LogType logType, const char* context)
{
#if defined(ENABLE_LOGGING)
if (self->initialized)
{
struct LogQueueItem logQueueItem;
portBASE_TYPE higherPriorityTaskWoken = pdFALSE;
composeLogQueueItem(&logQueueItem, fileName, functionName, lineNumber, logType, context);
if(xQueueSendFromISR(self->logQueue, &logQueueItem, &higherPriorityTaskWoken) != pdTRUE)
{
// Queue failed
}
portEND_SWITCHING_ISR(higherPriorityTaskWoken);
}
#endif
}
static void composeLogQueueItem(struct LogQueueItem* logQueueItem, const char* fileName, const char* functionName,
int lineNumber, LogType logType, const char* context)
{
const size_t fileNameSize = sizeof(logQueueItem->fileName) / sizeof(logQueueItem->fileName[0]);
const size_t functionNameSize = sizeof(logQueueItem->functionName) / sizeof(logQueueItem->functionName[0]);
const size_t contextSize = sizeof(logQueueItem->context) / sizeof(logQueueItem->context[0]);
logQueueItem->logType = logType;
strncpy(&(logQueueItem->context[0]), context, contextSize);
logQueueItem->context[contextSize - 1] = '\0';
if(logType != LOGTYPE_PRINT)
{
int fileNameIndex = 0;
// If filename starts with "src/", strip this part
if((fileName[0] == 's') &&
(fileName[1] == 'r') &&
(fileName[2] == 'c') &&
(fileName[3] == '/'))
{
fileNameIndex = 4;
}
// All logtypes except LOGTYPE_PRINT need filename, functionname and linenumber.
strncpy(&(logQueueItem->fileName[0]), &fileName[fileNameIndex], fileNameSize);
strncpy(&(logQueueItem->functionName[0]), functionName, functionNameSize);
logQueueItem->lineNumber = lineNumber;
// Fix terminating null byte in strncpy in case string to be copied is too long
logQueueItem->fileName[fileNameSize - 1] = '\0';
logQueueItem->functionName[functionNameSize - 1] = '\0';
}
}
static void loggerTask(void* parameters)
{
struct Logger* self = (struct Logger*)parameters;
while(self->initialized)
{
struct LogQueueItem logQueueItem;
xQueueReceive(self->logQueue, &logQueueItem, portMAX_DELAY);
if(logQueueItem.logType == LOGTYPE_PRINT)
{
// Raw print
#if defined(ENABLE_SERIAL_LOGGING)
IODevice_write(self->loggingDevice, logQueueItem.context, strlen(logQueueItem.context));
#endif
}
else
{
#if defined(ENABLE_SERIAL_LOGGING)
char str[256];
char* vt100Prefix = "";
const char* vt100Postfix = "\033[0m";
#endif
#if defined(ENABLE_SERIAL_LOGGING)
if(logQueueItem.logType == LOGTYPE_INFO)
{
vt100Prefix = "\033[33m";
}
else if(logQueueItem.logType == LOGTYPE_WARNING)
{
vt100Prefix = "\033[35m";
}
else if(logQueueItem.logType == LOGTYPE_ERROR)
{
vt100Prefix = "\033[31m";
}
#endif
#if defined(ENABLE_SERIAL_LOGGING)
// Formatted print
snprintf(str, sizeof(str) / sizeof(str[0]), "%s[%s] %s, %s, %d: %s%s\n",
vt100Prefix,
(logQueueItem.logType == LOGTYPE_DEBUG) ? "DBG" :
(logQueueItem.logType == LOGTYPE_INFO) ? "INF" :
(logQueueItem.logType == LOGTYPE_WARNING) ? "WRN" : "ERR",
logQueueItem.fileName,
logQueueItem.functionName,
logQueueItem.lineNumber,
logQueueItem.context,
vt100Postfix);
#endif
#if defined(ENABLE_SERIAL_LOGGING)
IODevice_write(self->loggingDevice, str, strlen(str));
#endif
char buffer[5] = {0,};
size_t actualLength = 0;
IODevice_read(self->loggingDevice, buffer, 5, &actualLength);
snprintf(str, sizeof(str) / sizeof(str[0]), "%d - %x %x %x %x %x", actualLength, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]);
IODevice_write(self->loggingDevice, str, strlen(str));
}
}
vTaskDelete(self->taskHandle);
}