Commit 3c97a078 authored by Michael Zehrer's avatar Michael Zehrer
Browse files

add new conditional logging interface

parent e1907d84
......@@ -9,7 +9,7 @@ endif()
project(
arctos
VERSION 0.0.3
VERSION 0.0.4
LANGUAGES C CXX ASM
)
......
......@@ -23,6 +23,7 @@
#include <stddef.h>
#include <stdint.h>
#include <arctos/log/logging.hpp>
#include <arctos/hw_interface.h>
#ifdef __cplusplus
......@@ -62,9 +63,7 @@ void *__dso_handle = nullptr;
* contains a NULL pointer we call it a 'pure virtual function'.
*/
void __cxa_pure_virtual() {
// TODO
// kernel panic
//panic("\n\nKernel panic: pure virtual called");
::arctos::log::critical("\n\nKERNEL PANIC: pure virtual called");
}
/**
......
......@@ -9,7 +9,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <arctos/debug.hpp>
#include <arctos/log/logging.hpp>
#include <arctos/task.hpp>
#include <arctos/time.hpp>
......@@ -33,7 +33,7 @@ public:
};
void IdleTask::init() {
// TODO
PRINTF("yields all the time");
log::debug("yields all the time");
}
void IdleTask::run() {
/*
......
......@@ -6,7 +6,8 @@
* @brief A Task is an active schedulable object with own context and stack
* @author Michael Zehrer
*/
#include <arctos/debug.hpp>
#include <arctos/log/logging.hpp>
#include <arctos/log/logger.hpp>
#include <arctos/task.hpp>
#include <arctos/time.hpp>
......@@ -25,7 +26,7 @@ Task::Task(const char *p_name, const uint32_t priority, uint32_t stack_size)
this->p_stack_low = _hwAllocateMemory(stack_size);
if (this->p_stack_low == nullptr)
PANIC("Not enough memory for task '%s'. The user requested %lu bytes", p_name, stack_size);
log::critical("Not enough memory for task '%s'. The user requested %lu bytes", p_name, stack_size);
this->p_stack_high = reinterpret_cast<uint32_t*>(
reinterpret_cast<uintptr_t>(this->p_stack_low) + stack_size);
......@@ -72,16 +73,16 @@ LinkedList<Task> Task::tasks;
Task *Task::p_current = nullptr;
void Task::initAll() {
PRINTF("Task's in System:");
log::system("Task's in System:");
ITERATE_LIST(Task, Task::tasks) {
Task *t = item->getContent();
PRINTF("\n Prio = %6lu Stack = %6lu %s: ", t->getPriority(), t->getStackSize(), t->getName());
log::system("\n Prio = %6lu Stack = %6lu %s: ", t->getPriority(), t->getStackSize(), t->getName());
t->init();
//t->suspended_until = 0; TODO
}
PRINTF("\n");
log::system("\n");
// TODO
/*
ITERATE_LIST(Thread, threadList) {
......
......@@ -2,8 +2,8 @@ add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/src")
# Headers
target_sources(${UNIT} PUBLIC
"${CMAKE_CURRENT_LIST_DIR}/api/arctos/log/logging.hpp"
"${CMAKE_CURRENT_LIST_DIR}/api/arctos/memory/partitioning.hpp"
"${CMAKE_CURRENT_LIST_DIR}/api/arctos/debug.hpp"
"${CMAKE_CURRENT_LIST_DIR}/api/arctos/fifo.hpp"
"${CMAKE_CURRENT_LIST_DIR}/api/arctos/list.hpp"
"${CMAKE_CURRENT_LIST_DIR}/api/arctos/mutex.hpp"
......@@ -14,6 +14,7 @@ target_sources(${UNIT} PUBLIC
"${CMAKE_CURRENT_LIST_DIR}/api/compiler.h"
"${CMAKE_CURRENT_LIST_DIR}/api/new.hpp"
"${CMAKE_CURRENT_LIST_DIR}/inc/arctos/log/logger.hpp"
"${CMAKE_CURRENT_LIST_DIR}/inc/arctos/hw_interface.h"
"${CMAKE_CURRENT_LIST_DIR}/inc/arctos/hw_interface.hpp"
)
......
/**
* Copyright (c) 2018-2019, Michael Zehrer
* All rights reserved.
*
* @licence BSD
* @brief Debug functions (temporary interface)
* @author Michael Zehrer
*/
#ifndef ARCTOS_DEBUG_HPP
#define ARCTOS_DEBUG_HPP
#include <arctos/params.h>
#include <serial/all.hpp>
// TODO This is a temporary implementation -> delete ASAP
// IMPORTANT: 'RPI_DEBUG_SERIAL_IDX' isn't save to use here, because it is first defined in bare-metal!
#define PRINTF (modules::serial::get(RPI_DEBUG_SERIAL_IDX)->printf)
#define PANIC (modules::serial::get(RPI_DEBUG_SERIAL_IDX)->printf)
#endif /* ARCTOS_DEBUG_HPP */
/**
* Copyright (c) 2019, Michael Zehrer
* All rights reserved.
*
* @licence BSD
* @brief Simple logging and debugging interface
* @author Michael Zehrer
*/
#ifndef ARCTOS_LOG_LOGGING_HPP
#define ARCTOS_LOG_LOGGING_HPP
#include <stdint.h>
#include <stddef.h>
#include <arctos/params.h>
namespace arctos {
namespace log {
namespace level {
enum Level {
kDebug,
kInfo,
kWarning,
kSystem,
kError,
kCritical,
kNone
};
}
#if ARCTOS_LOG_LEVEL == kDebug
#define ARCTOS_LOG_DEBUG_AVAILABLE
__attribute__((__format__(__printf__, 1, 2))) size_t debug(const char *fmt, ...);
#else
inline size_t debug(...) { return 0; }
#endif
#if ARCTOS_LOG_LEVEL == kDebug || \
ARCTOS_LOG_LEVEL == kInfo
#define ARCTOS_LOG_INFO_AVAILABLE
__attribute__((__format__(__printf__, 1, 2))) size_t info(const char *fmt, ...);
#else
inline size_t info(...) { return 0; }
#endif
#if ARCTOS_LOG_LEVEL == kDebug || \
ARCTOS_LOG_LEVEL == kInfo || \
ARCTOS_LOG_LEVEL == kWarning
#define ARCTOS_LOG_WARNING_AVAILABLE
__attribute__((__format__(__printf__, 1, 2))) size_t warning(const char *fmt, ...);
#else
inline size_t warning(...) { return 0; }
#endif
#if ARCTOS_LOG_LEVEL == kDebug || \
ARCTOS_LOG_LEVEL == kInfo || \
ARCTOS_LOG_LEVEL == kWarning || \
ARCTOS_LOG_LEVEL == kSystem || \
ARCTOS_LOG_LEVEL == kError
#define ARCTOS_LOG_ERROR_AVAILABLE
__attribute__((__format__(__printf__, 1, 2))) size_t error(const char *fmt, ...);
#else
inline size_t error(...) { return 0; }
#endif
#if ARCTOS_LOG_LEVEL == kDebug || \
ARCTOS_LOG_LEVEL == kInfo || \
ARCTOS_LOG_LEVEL == kWarning || \
ARCTOS_LOG_LEVEL == kSystem || \
ARCTOS_LOG_LEVEL == kError || \
ARCTOS_LOG_LEVEL == kCritical
#define ARCTOS_LOG_CRITICAL_AVAILABLE
__attribute__((__format__(__printf__, 1, 2))) size_t critical(const char *fmt, ...);
#else
inline size_t critical(...) { while (true) {} }
#endif
} /* namespace log */
} /* namespace arctos */
#endif /* ARCTOS_LOG_LOGGING_HPP */
/**
* Copyright (c) 2019, Michael Zehrer
* All rights reserved.
*
* @licence BSD
* @brief Simple logging implementation
* @author Michael Zehrer
*/
#ifndef ARCTOS_LOG_LOGGER_HPP
#define ARCTOS_LOG_LOGGER_HPP
#include <stdint.h>
#include <stdarg.h>
#include <arctos/log/logging.hpp>
#include <arctos/printable.hpp>
namespace arctos {
namespace log {
#if ARCTOS_LOG_LEVEL == kDebug || \
ARCTOS_LOG_LEVEL == kInfo || \
ARCTOS_LOG_LEVEL == kWarning || \
ARCTOS_LOG_LEVEL == kSystem
#define ARCTOS_LOG_SYSTEM_AVAILABLE
__attribute__((__format__(__printf__, 1, 2))) size_t system(const char *fmt, ...);
#else
inline size_t system(...) { return 0; }
#endif
class Logger {
protected:
Logger() {}
Printable *destination_;
public:
void setDestination(Printable *dest) { this->destination_ = dest; }
size_t notify(level::Level lvl, const char *fmt, va_list vl);
static Logger *instance() {
static Logger log;
return &log;
}
};
} /* namespace log */
} /* namespace arctos */
#endif /* ARCTOS_LOG_LOGGER_HPP */
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<segment name="independent">
<types>
<type name="log_level">
<item id="kDebug" readable="Debug" />
<item id="kInfo" readable="Info" />
<item id="kWarning" readable="Warning" />
<item id="kSystem" readable="System" />
<item id="kError" readable="Error" />
<item id="kCritical" readable="Critical" />
<item id="kNone" readable="None" />
</type>
</types>
<configuration>
<option definition="ARCTOS_DEFAULT_TASK_PRIORITY"
readable="Default task priority"
......@@ -19,6 +30,19 @@
</option.description>
<option.value>1024</option.value>
</option>
<option definition="ARCTOS_LOG_LEVEL" readable="Logging level" type="log_level">
<option.description>
Defines the verbosity level of the build-in logging interface
</option.description>
<option.value>kDebug</option.value>
</option>
<option definition="ARCTOS_LOG_ENABLE_COLOR" readable="Enable colored output" type="bool">
<option.description>
ON = Use ANSI/VT100 Control sequences for colored messages
OFF = Print plain text only
</option.description>
<option.value>true</option.value>
</option>
</configuration>
<parameters>
<param definition="ARCTOS_NUMBER_OF_CORES"
......
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/libc-pico")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/log")
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/memory")
# Sources
......
target_sources(${UNIT} PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/logger.cpp"
)
/**
* Copyright (c) 2019, Michael Zehrer
* All rights reserved.
*
* @licence BSD
* @brief Simple logging implementation
* @author Michael Zehrer
*/
#include <arctos/log/logging.hpp>
#include <arctos/log/logger.hpp>
namespace arctos {
namespace log {
#ifdef ARCTOS_LOG_DEBUG_AVAILABLE
size_t debug(const char *fmt, ...) {
va_list vl;
va_start(vl, fmt);
size_t counter = Logger::instance()->notify(level::kDebug, fmt, vl);
va_end(vl);
return counter;
}
#endif
#ifdef ARCTOS_LOG_INFO_AVAILABLE
size_t info(const char *fmt, ...) {
va_list vl;
va_start(vl, fmt);
size_t counter = Logger::instance()->notify(level::kInfo, fmt, vl);
va_end(vl);
return counter;
}
#endif
#ifdef ARCTOS_LOG_WARNING_AVAILABLE
size_t warning(const char *fmt, ...) {
va_list vl;
va_start(vl, fmt);
size_t counter = Logger::instance()->notify(level::kWarning, fmt, vl);
va_end(vl);
return counter;
}
#endif
#ifdef ARCTOS_LOG_SYSTEM_AVAILABLE
size_t system(const char *fmt, ...) {
va_list vl;
va_start(vl, fmt);
size_t counter = Logger::instance()->notify(level::kSystem, fmt, vl);
va_end(vl);
return counter;
}
#endif
#ifdef ARCTOS_LOG_ERROR_AVAILABLE
size_t error(const char *fmt, ...) {
va_list vl;
va_start(vl, fmt);
size_t counter = Logger::instance()->notify(level::kError, fmt, vl);
va_end(vl);
return counter;
}
#endif
#ifdef ARCTOS_LOG_CRITICAL_AVAILABLE
size_t critical(const char *fmt, ...) {
va_list vl;
va_start(vl, fmt);
Logger::instance()->notify(level::kCritical, fmt, vl);
va_end(vl);
while (true) { }
}
#endif
size_t Logger::notify(level::Level lvl, const char *fmt, va_list vl) {
if (this->destination_ == nullptr)
return 0;
size_t counter = 0;
#ifdef ARCTOS_LOG_ENABLE_COLOR
switch (lvl) {
case level::kWarning:
counter += this->destination_->print("\e[33m", 6);
break;
case level::kError:
counter += this->destination_->print("\e[31m", 6);
break;
case level::kCritical:
counter += this->destination_->print("\e[5m\e[31m", 11);
break;
default:
break;
}
#endif
counter += this->destination_->vprintf(fmt, vl);
#ifdef ARCTOS_LOG_ENABLE_COLOR
counter += this->destination_->print("\e[0m", 5);
#endif
this->destination_->flush();
return counter;
}
} /* namespace log */
} /* namespace arctos */
......@@ -9,7 +9,7 @@
#include <arctos/hw_interface.hpp>
#include <arctos/scheduler.hpp>
#include <arctos/debug.hpp>
#include <arctos/log/logger.hpp>
#include <arctos/task.hpp>
namespace arctos {
......@@ -29,15 +29,14 @@ extern "C" int main(int argc, char** argv) {
static_cast<void>(argv);
_hwInit();
PRINTF("arctos (version: " ARCTOS_VERSION ")\n\n");
log::system("arctos (version: " ARCTOS_VERSION ")\n\n");
// Call all static constructors
__libc_init_array();
_initSystem();
//PRINTF("--------------------------------------------------\n");
PRINTF("-------------- applications running --------------\n");
log::system("-------------- applications running --------------\n");
Scheduler::getInstance()->idle();
return 0;
......
......@@ -9,7 +9,7 @@
#include <stddef.h>
#include <string.h>
#include <arctos/debug.hpp>
#include <arctos/log/logging.hpp>
#include <arctos/memory/partitioning.hpp>
#include <arctos/hw_interface.hpp>
......@@ -74,7 +74,7 @@ Partitioning *Partitioning::create(uint32_t full_size, uint32_t item_size) {
uint32_t alloc_size = header_size + full_size;
uint32_t *mem = _hwAllocateMemory(alloc_size);
if (mem == nullptr) {
PRINTF("[ERROR] Not enough memory to create a new %lu-bytes partition!\n", full_size);
::arctos::log::error("Not enough memory to create a new %lu-bytes partition!\n", full_size);
return nullptr;
}
......
......@@ -46,9 +46,9 @@
<set definition="ARCTOS_SOC" value="BCM2835" />
</item>
</type>
<type name="rpi_serial">
<item id="0" readable="PL011 UART" />
<item id="1" readable="miniUART" />
<type name="rpi_log_dest">
<item id="kSerial00" readable="PL011 UART" />
<item id="kSerial01" readable="miniUART" />
</type>
</types>
<configuration>
......@@ -69,9 +69,9 @@
<option definition="RPI_BOARD" readable="Board / Model" type="rpi_board">
<option.description>Target Raspberry Pi board / model</option.description>
</option>
<option definition="RPI_DEBUG_SERIAL_IDX" readable="Debug UART" type="rpi_serial">
<option.description>Default UART to print all debug messages</option.description>
<option.value>1</option.value>
<option definition="RPI_LOG_DESTINATION" readable="Logging destination" type="rpi_log_dest">
<option.description>Destination interface for all logging messages</option.description>
<option.value>kSerial01</option.value>
</option>
</configuration>
</target>
......@@ -10,17 +10,21 @@
#include <string.h>
#include <arctos/params.h>
#include <arctos/log/logger.hpp>
#include <arctos/printable.hpp>
#include <arctos/task.hpp>
#include <arctos/hw_interface.hpp>
#include <arctos/scheduler.hpp>
#include <serial/all.hpp>
#include <raspberry/all.h>
#include "include/context.h"
#include "include/mmu.h"
#include "include/cache.h"
using namespace modules;
namespace arctos {
uint32_t *_hwInitContext(uint32_t *stack, Task *task) {
......@@ -124,6 +128,11 @@ int64_t atomic64_cmpxchg(int64_t *v, int64_t o, int64_t n) {
*/
void *volatile g_p_cur_task_context;
enum LogDestination {
kSerial00 = 0,
kSerial01 = 1
};
/**
* @brief This function will be called at a very early startup state.
* It is intended to initialize certain hardware interfaces
......@@ -140,7 +149,11 @@ void _hwInit(void) {
_branchPredictor_enable();
#endif
serial::get(RPI_DEBUG_SERIAL_IDX)->begin();
#if ARCTOS_LOG_LEVEL != kNone
modules::serial::Serial *s = modules::serial::get(RPI_LOG_DESTINATION);
s->begin();
arctos::log::Logger::instance()->setDestination(s);
#endif
}
} // end extern "C"
......
#include <arctos/debug.hpp>
#include <arctos/log/logging.hpp>
#include <arctos/task.hpp>
class HelloWorldTask : public arctos::Task {
......@@ -6,6 +6,6 @@ public:
HelloWorldTask() : arctos::Task("HelloWorld-Task") {}
void run() {
PRINTF("Hello World!\n");
arctos::log::debug("Hello World!\n");
}
} tsk;
/**
* Generated on 2019-10-17 22:59
* Generated on 2019-12-19 21:18
* DO NOT EDIT
*
* @brief automatically generated params header
......@@ -9,14 +9,16 @@
#define ARCTOS_DEFAULT_TASK_PRIORITY 10
#define ARCTOS_DEFAULT_STACKSIZE 1024
#define ARCTOS_LOG_LEVEL kDebug
#define ARCTOS_LOG_ENABLE_COLOR
#define ARCTOS_SCHEDULER_TIME_SLOT_SIZE 100000
#define RPI_ENABLE_FPU
#define RPI_ENABLE_CACHE
#define RPI_BOARD RASPBERRY_PI_B
#define RPI_DEBUG_SERIAL_IDX 1
#define RPI_LOG_DESTINATION kSerial01
#define ARCTOS_NUMBER_OF_CORES 1
#define ARCTOS_BOARDNAME Raspberry Pi B
#define ARCTOS_SOC BCM2835
#endif /* ARCTOS_PARAMS_H */
#endif /* ARCTOS_PARAMS_H */
\ No newline at end of file
/**
* Generated on 2019-10-17 22:59
* Generated on 2019-12-19 21:18
* DO NOT EDIT
*
* @brief automatically generated params header
......
......@@ -2,7 +2,7 @@
# This script is automatically generated
# DO NOT EDIT
#
# Generated on 2019-10-17 22:59
# Generated on 2019-12-19 21:18
#
set(ARCTOS_TARGET "raspberry")
......@@ -18,11 +18,13 @@ target_link_libraries(${UNIT} ${ARCTOS_INTERFACE})
############ BEGIN-TARGET: raspberry #############
set(ARCTOS_DEFAULT_TASK_PRIORITY "10")
set(ARCTOS_DEFAULT_STACKSIZE "1024")
set(ARCTOS_LOG_LEVEL "kDebug")
set(ARCTOS_LOG_ENABLE_COLOR on)
set(ARCTOS_SCHEDULER_TIME_SLOT_SIZE "100000")
set(RPI_ENABLE_FPU on)
set(RPI_ENABLE_CACHE on)
set(RPI_BOARD "RASPBERRY_PI_B")
set(RPI_DEBUG_SERIAL_IDX "1")
set(RPI_LOG_DESTINATION "kSerial01")
set(ARCTOS_NUMBER_OF_CORES "1")
set(ARCTOS_BOARDNAME "Raspberry Pi B")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment