diff --git a/CMakeLists.txt b/CMakeLists.txt index e1088bf..44437b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,7 @@ add_executable(baseline ${APP_DIR}/net/EthernetIf.c ${APP_DIR}/storage/diskio.c ${APP_DIR}/storage/SemihostingDisk.c + ${APP_DIR}/syslog/Syslog.c ${APP_DIR}/syslog/SyslogErrorHandler.c $ ) diff --git a/README.md b/README.md index e18c78e..43eb43e 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,15 @@ It builds on a baseline that simulates the sort of device you might be adding th measures itself: see [docs/baseline.md](docs/baseline.md) for what the baseline is, how the figures are made, and how to run it. -## This stage — Error handler +## This stage — Logger created -The device installs its own handler on SolidSyslog's error slot, before creating anything. A -`_Create` that cannot succeed returns a Null object rather than failing, so without this a -mis-wired logger and a quiet one look identical. +The logger exists, with nothing wired into it. Both collaborators that decide where a record goes +are absent, so the handler from the previous stage reports them and the run report carries the +faults — which is the point of creating it empty first. -**Cost above baseline: Flash +404 B, RAM +8 B.** +**Cost above baseline: Flash +1,036 B, RAM +180 B.** @@ -34,6 +34,7 @@ committed as [`run-report.md`](run-report.md), and rewritten by every stage. | Baseline | a device that already networks, stores, and holds an mTLS session — before any syslog | — | — | | Linked | the core library and lwIP raw-mode networking, linked but not yet called | +0 | +0 | | Error handler | a fault inside the logger reaches the console instead of being silent | +404 | +8 | +| Logger created | the logger object, reporting exactly what is still missing from it | +1,036 | +180 | *Deltas are bytes above the baseline, which is itself Flash 350,308 B, RAM 111,192 B.* diff --git a/app/main.c b/app/main.c index b5a7b11..e64d325 100644 --- a/app/main.c +++ b/app/main.c @@ -9,6 +9,7 @@ #include "SemihostingExit.h" #include "ServiceTask.h" #include "SimulatedExistingApp.h" +#include "Syslog.h" #include "SyslogErrorHandler.h" #include "lwip/tcpip.h" @@ -97,6 +98,8 @@ int main(void) /* Before the first _Create — see SyslogErrorHandler.h for why that matters. */ SyslogErrorHandler_Install(); + Syslog_Start(); + /* lwIP tcpip thread + core-lock mutex + mbox. Pre-scheduler safe. */ tcpip_init(NULL, NULL); diff --git a/app/syslog/Syslog.c b/app/syslog/Syslog.c new file mode 100644 index 0000000..ffad356 --- /dev/null +++ b/app/syslog/Syslog.c @@ -0,0 +1,30 @@ +/* See Syslog.h. Created with nothing wired into it, on purpose: a missing + * collaborator is substituted with its Null object and reported, and the run + * report is where that shows. */ + +#include "Syslog.h" + +#include "SolidSyslogConfig.h" + +#include + +static struct SolidSyslog* s_logger = NULL; + +void Syslog_Start(void) +{ + /* Buffer and Sender decide where a record goes. NULL is "not supplied" and + * is reported; a collaborator deliberately done without is passed as its + * Null object instead, which is how the library tells the two apart. */ + struct SolidSyslogConfig config = { + .Buffer = NULL, + .Sender = NULL, + }; + + /* No null check — Create returns a shared null instance rather than NULL. */ + s_logger = SolidSyslog_Create(&config); +} + +struct SolidSyslog* Syslog_Handle(void) +{ + return s_logger; +} diff --git a/app/syslog/Syslog.h b/app/syslog/Syslog.h new file mode 100644 index 0000000..0aaa665 --- /dev/null +++ b/app/syslog/Syslog.h @@ -0,0 +1,15 @@ +/* The device's SolidSyslog wiring — the one place that knows how the logger is + * assembled. Everything else in the application just logs. */ +#ifndef SYSLOG_H +#define SYSLOG_H + +struct SolidSyslog; + +/** Build the config and create the logger. Call once at startup, after + * SyslogErrorHandler_Install so any fault in here is reported. */ +void Syslog_Start(void); + +/** The logger, for the tasks that log from it and drain it. */ +struct SolidSyslog* Syslog_Handle(void); + +#endif /* SYSLOG_H */ diff --git a/measurements/logger.csv b/measurements/logger.csv new file mode 100644 index 0000000..af63256 --- /dev/null +++ b/measurements/logger.csv @@ -0,0 +1,13 @@ +# logger figures (bytes) — captured by scripts/run.sh (CAPTURE=1). +# The device reads measurements/Baseline.csv as its frozen baseline and reports current-minus-Baseline. +flash_text,350960 +flash_data,384 +static_bss,110988 +heap_used,4440 +mbedtls_peak,21192 +mbedtls_free,11576 +lwip_mem_free,7576 +lwip_pbufs_free,13 +stack_log,120 +stack_service,52 +stack_harness,2840 diff --git a/measurements/stages.tsv b/measurements/stages.tsv index 2999673..c9b1a5c 100644 --- a/measurements/stages.tsv +++ b/measurements/stages.tsv @@ -12,3 +12,4 @@ Baseline Baseline a device that already networks, stores, and holds an mTLS session — before any syslog linked Linked the core library and lwIP raw-mode networking, linked but not yet called error-handler Error handler a fault inside the logger reaches the console instead of being silent +logger Logger created the logger object, reporting exactly what is still missing from it diff --git a/run-report.md b/run-report.md index 3d8b6a0..b989132 100644 --- a/run-report.md +++ b/run-report.md @@ -1,20 +1,23 @@ -# solid-syslog-example — run (error-handler) +# solid-syslog-example — run (logger) ## Device (self-measured) ```text [device] solid-syslog-example (FreeRTOS + lwIP + mbedTLS + FatFs) +[syslog] CRITICAL SolidSyslog bad-config (detail 1) +[syslog] CRITICAL SolidSyslog bad-config (detail 2) +[syslog] CRITICAL SolidSyslog bad-config (detail 3) [device] starting simulated existing application... [sim] broker session to 10.0.2.2:8883: TLSv1.3, TLS1-3-CHACHA20-POLY1305-SHA256 [device] sim app (lwIP up, FatFs mounted, broker session held over mTLS): ready [report] --- SolidSyslog cost above baseline (simulated existing application) --- [report] key,current,baseline,used_above_baseline -[report] flash_text,350392,349992,400 -[report] flash_data,320,316,4 -[report] static_bss,110880,110876,4 +[report] flash_text,350960,349992,968 +[report] flash_data,384,316,68 +[report] static_bss,110988,110876,112 [report] heap_used,4440,4440,0 -[report] mbedtls_peak,21208,21332,-124 -[report] mbedtls_free,11560,11436,124 +[report] mbedtls_peak,21228,21332,-104 +[report] mbedtls_free,11540,11436,104 [report] lwip_mem_free,7576,7576,0 [report] lwip_pbufs_free,13,14,-1 [report] stack_log,120,120,0 @@ -28,7 +31,7 @@ ```text text data bss dec hex filename - 350384 328 110880 461592 70b18 /w/build/baseline-cross/baseline.elf + 350952 392 110988 462332 70dfc /w/build/baseline-cross/baseline.elf ``` ## Listeners (proved before the device ran) @@ -49,17 +52,17 @@ (nothing — this device sends no records yet) ``` -## Self-check (vs measurements/error-handler.csv) +## Self-check (vs measurements/logger.csv) ```text - OK flash_text: 350392 (expected 350392, Δ0) - OK flash_data: 320 (expected 320, Δ0) - OK static_bss: 110880 (expected 110880, Δ0) + OK flash_text: 350960 (expected 350960, Δ0) + OK flash_data: 384 (expected 384, Δ0) + OK static_bss: 110988 (expected 110988, Δ0) OK heap_used: 4440 (expected 4440, Δ0) - OK mbedtls_peak: 21208 (expected 21336, Δ128) - OK mbedtls_free: 11560 (expected 11432, Δ128) + OK mbedtls_peak: 21228 (expected 21192, Δ36) + OK mbedtls_free: 11540 (expected 11576, Δ36) OK lwip_mem_free: 7576 (expected 7576, Δ0) - OK lwip_pbufs_free: 13 (expected 14, Δ1) + OK lwip_pbufs_free: 13 (expected 13, Δ0) OK stack_log: 120 (expected 120, Δ0) OK stack_service: 52 (expected 52, Δ0) OK stack_harness: 2840 (expected 2840, Δ0)