From 18da37fb24981b0855dd34dc1f7c9dbf7bdd0ac5 Mon Sep 17 00:00:00 2001
From: Rahix <rahix@rahix.de>
Date: Sat, 20 Jul 2019 16:25:48 +0200
Subject: [PATCH] feat(epicardium): Add a module for logging

Closes #41

Signed-off-by: Rahix <rahix@rahix.de>
---
 epicardium/main.c              | 19 ++++++-----
 epicardium/modules/log.c       | 52 ++++++++++++++++++++++++++++++
 epicardium/modules/log.h       | 59 ++++++++++++++++++++++++++++++++++
 epicardium/modules/meson.build |  1 +
 4 files changed, 123 insertions(+), 8 deletions(-)
 create mode 100644 epicardium/modules/log.c
 create mode 100644 epicardium/modules/log.h

diff --git a/epicardium/main.c b/epicardium/main.c
index 53eed1ac5..4ffb263cc 100644
--- a/epicardium/main.c
+++ b/epicardium/main.c
@@ -10,6 +10,7 @@
 #include "leds.h"
 #include "api/dispatcher.h"
 #include "modules/modules.h"
+#include "modules/log.h"
 
 #include <Heart.h>
 #include "GUI_Paint.h"
@@ -47,7 +48,7 @@ int main(void)
 	cdcacm_init();
 	fatfs_init();
 
-	printf("=> Initializing tasks ...\n");
+	LOG_DEBUG("startup", "Initializing tasks ...");
 
 	/* Serial */
 	if (xTaskCreate(
@@ -57,7 +58,7 @@ int main(void)
 		    NULL,
 		    tskIDLE_PRIORITY + 1,
 		    NULL) != pdPASS) {
-		printf("Failed to create serial-comms task!\n");
+		LOG_CRIT("startup", "Failed to create %s task!", "Serial");
 		abort();
 	}
 
@@ -69,7 +70,7 @@ int main(void)
 		    NULL,
 		    tskIDLE_PRIORITY + 1,
 		    NULL) != pdPASS) {
-		printf("Failed to create pmic task!\n");
+		LOG_CRIT("startup", "Failed to create %s task!", "PMIC");
 		abort();
 	}
 
@@ -81,17 +82,19 @@ int main(void)
 		    NULL,
 		    tskIDLE_PRIORITY + 2,
 		    &dispatcher_task_id) != pdPASS) {
-		printf("Failed to create api dispatcher task!\n");
+		LOG_CRIT("startup", "Failed to create %s task!", "API Dispatcher");
 		abort();
 	}
 
-	printf("=> Initializing dispatcher ...\n");
+	LOG_INFO("startup", "Initializing dispatcher ...");
 	api_dispatcher_init();
 
-	printf("=> Starting core1 payload ...\n");
+	LOG_INFO("startup", "Starting core1 payload ...");
 	core1_start();
 
-	printf("=> Starting FreeRTOS ...\n");
+	LOG_INFO("startup", "Starting FreeRTOS ...");
 	vTaskStartScheduler();
-	printf("ERROR: FreeRTOS did not start due to unknown error!\n");
+
+	LOG_CRIT("startup", "FreeRTOS did not start due to unknown error!");
+	abort();
 }
diff --git a/epicardium/modules/log.c b/epicardium/modules/log.c
new file mode 100644
index 000000000..c04084f21
--- /dev/null
+++ b/epicardium/modules/log.c
@@ -0,0 +1,52 @@
+#include "modules/log.h"
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#if LOG_ENABLE
+int log_msg(const char *subsys, const char *format, ...)
+{
+	va_list ap;
+	int ret;
+
+	if (!LOG_ENABLE_DEBUG && format[0] == 'D') {
+		return 0;
+	}
+
+	va_start(ap, format);
+	if (LOG_ENABLE_COLOR) {
+		char *msg_color = "";
+
+		switch (format[0]) {
+		case 'W':
+			msg_color = "\x1B[1m";
+			break;
+		case 'E':
+			msg_color = "\x1B[31;1m";
+			break;
+		case 'C':
+			msg_color = "\x1B[37;41;1m";
+			break;
+		}
+
+		printf("\x1B[32m[%12lu] \x1B[33m%s\x1B[0m: %s",
+		       xTaskGetTickCount(),
+		       subsys,
+		       msg_color);
+
+		ret = vprintf(&format[1], ap);
+
+		printf("\x1B[0m\n");
+	} else {
+		printf("[%12lu] %s: ", xTaskGetTickCount(), subsys);
+		ret = vprintf(&format[1], ap);
+		printf("\n");
+	}
+	va_end(ap);
+
+	return ret;
+}
+#endif /* LOG_ENABLE */
diff --git a/epicardium/modules/log.h b/epicardium/modules/log.h
new file mode 100644
index 000000000..bbeecd528
--- /dev/null
+++ b/epicardium/modules/log.h
@@ -0,0 +1,59 @@
+#pragma once
+
+#define SEV_DEBUG "D"
+#define SEV_INFO  "I"
+#define SEV_WARN  "W"
+#define SEV_ERR   "E"
+#define SEV_CRIT  "C"
+
+/* Whether to enable logging at all */
+#ifndef LOG_ENABLE
+#define LOG_ENABLE 1
+#endif
+
+/* Whether to enable even more verbose logging */
+#ifndef LOG_ENABLE_DEBUG
+#define LOG_ENABLE_DEBUG 0
+#endif
+
+/* Whether to enable colorful log */
+#ifndef LOG_ENABLE_COLOR
+#define LOG_ENABLE_COLOR 1
+#endif
+
+#if LOG_ENABLE
+
+int log_msg(const char *subsys, const char *format, ...)
+	__attribute__((format(printf, 2, 3)));
+
+#if LOG_ENABLE_DEBUG
+#define LOG_DEBUG(subsys, format, ...)                                         \
+	log_msg(subsys, SEV_DEBUG format, ##__VA_ARGS__)
+#else /* LOG_ENABLE_DEBUG */
+#define LOG_DEBUG(subsys, format, ...)
+#endif /* LOG_ENABLE_DEBUG */
+
+#define LOG_INFO(subsys, format, ...)                                          \
+	log_msg(subsys, SEV_INFO format, ##__VA_ARGS__)
+#define LOG_WARN(subsys, format, ...)                                          \
+	log_msg(subsys, SEV_WARN format, ##__VA_ARGS__)
+#define LOG_ERR(subsys, format, ...)                                           \
+	log_msg(subsys, SEV_ERR format, ##__VA_ARGS__)
+#define LOG_CRIT(subsys, format, ...)                                          \
+	log_msg(subsys, SEV_CRIT format, ##__VA_ARGS__)
+
+#else /* LOG_ENABLE_DEBUG */
+
+inline __attribute__((format(printf, 2, 3))) int
+log_msg(const char *subsys, const char *format, ...)
+{
+	return 0;
+}
+
+#define LOG_DEBUG(subsys, format, ...)
+#define LOG_INFO(subsys, format, ...)
+#define LOG_WARN(subsys, format, ...)
+#define LOG_ERR(subsys, format, ...)
+#define LOG_CRIT(subsys, format, ...)
+
+#endif /* LOG_ENABLE_DEBUG */
diff --git a/epicardium/modules/meson.build b/epicardium/modules/meson.build
index d77973ad7..dfc27d005 100644
--- a/epicardium/modules/meson.build
+++ b/epicardium/modules/meson.build
@@ -1,6 +1,7 @@
 module_sources = files(
   'fatfs.c',
   'leds.c',
+  'log.c',
   'pmic.c',
   'serial.c',
   'vibra.c',
-- 
GitLab