Factory Logging Module
Section titled “Factory Logging Module”The factory_logging module provides a minimal, self-contained debug log gate for the Factory application. It defines a compile-time–gated logging macro (FACTORY_LOGD) and a runtime helper (factory_log_silence_sd_stack) that suppresses verbose SD/FAT driver output. Together, these two primitives keep UART output clean in production while still allowing targeted debug output during development — without any dependency on the main firmware’s esp3d_log infrastructure.
Architecture Overview
Section titled “Architecture Overview”The module is intentionally a single-header design: each board copies factory_log.h into its own Factory/main/ directory. There is no shared component dependency — the factory app is a standalone ESP-IDF project fully isolated from the main firmware component tree.
Module Context
Section titled “Module Context”The factory_logging module is a sub-module of the Factory Application & Bootloader. It is consumed exclusively inside the factory app and has no dependency on the main firmware’s esp3d_log system (documented in docs/guides/esp3d_log_guide.md).
File Layout
Section titled “File Layout”The header is replicated per board under each board’s Factory/main/ directory. All copies are identical — the file is not shared via a CMake component in order to keep every factory project self-contained and independently buildable.
| Board | Path |
|---|---|
| esp32_3248s035c | boards/esp32_3248s035c/Factory/main/factory_log.h |
| esp32_3248s035r | boards/esp32_3248s035r/Factory/main/factory_log.h |
| esp32s3_4827s043c | boards/esp32s3_4827s043c/Factory/main/factory_log.h |
| esp32s3_8048_touch_lcd_7 | boards/esp32s3_8048_touch_lcd_7/Factory/main/factory_log.h |
| esp32s3_8048s043c | boards/esp32s3_8048s043c/Factory/main/factory_log.h |
| esp32s3_8048s050c | boards/esp32s3_8048s050c/Factory/main/factory_log.h |
| esp32s3_8048s070c | boards/esp32s3_8048s070c/Factory/main/factory_log.h |
| esp32s3_bzm_tft35_gt911 | boards/esp32s3_bzm_tft35_gt911/Factory/main/factory_log.h |
| esp32s3_hmi43v3 | boards/esp32s3_hmi43v3/Factory/main/factory_log.h |
| esp32s3_zx3d50ce02s_usrc_4832 | boards/esp32s3_zx3d50ce02s_usrc_4832/Factory/main/factory_log.h |
| pibot_pendant_v1_0 | boards/pibot_pendant_v1_0/Factory/main/factory_log.h |
API Reference
Section titled “API Reference”Compile-Time Constant: FACTORY_LOG_LEVEL
Section titled “Compile-Time Constant: FACTORY_LOG_LEVEL”#ifndef FACTORY_LOG_LEVEL#define FACTORY_LOG_LEVEL 0#endif| Attribute | Value |
|---|---|
| Default | 0 — production mode; all FACTORY_LOGD calls become no-ops |
| Set by | ENABLE_FACTORY_DEBUG_LOG option in Factory/CMakeLists.txt |
| Scope | Independent of the global CONFIG_LOG_DEFAULT_LEVEL in sdkconfig |
⚠️ This constant gates only
FACTORY_LOGDcalls.ESP_LOGWandESP_LOGEare always active regardless of this value.
Macro: FACTORY_LOGD
Section titled “Macro: FACTORY_LOGD”// When FACTORY_LOG_LEVEL = 1 (debug build):#define FACTORY_LOGD(tag, fmt, ...) ESP_LOGI(tag, fmt, ##__VA_ARGS__)
// When FACTORY_LOG_LEVEL = 0 (production build):#define FACTORY_LOGD(tag, fmt, ...) do {} while (0)Parameters
| Parameter | Type | Description |
|---|---|---|
tag | const char * | ESP-IDF log tag string (e.g. "factory_sdcard") |
fmt | const char * | printf-style format string |
... | variadic | Format arguments |
Behavior
| Mode | Expansion | Runtime Cost |
|---|---|---|
Production (FACTORY_LOG_LEVEL=0) | do {} while (0) — null statement | Zero — eliminated by the compiler |
Debug (FACTORY_LOG_LEVEL=1) | ESP_LOGI(tag, fmt, ...) | Normal ESP-IDF log path |
Usage example
#include "factory_log.h"
static const char *TAG = "factory_sdcard";
esp_err_t sdcard_mount(void) { FACTORY_LOGD(TAG, "Mounting SD card..."); // ... mount logic ... FACTORY_LOGD(TAG, "SD card mounted at /sdcard"); return ESP_OK;}Function: factory_log_silence_sd_stack
Section titled “Function: factory_log_silence_sd_stack”static inline void factory_log_silence_sd_stack(void);Suppresses verbose runtime output from the ESP-IDF SD/FAT driver subsystem by setting each relevant driver tag to ESP_LOG_NONE via esp_log_level_set().
Silenced tags
| Tag | Driver Component |
|---|---|
sdmmc | SD/MMC core driver |
vfs_fat_sdmmc | VFS layer over FAT on SD |
sdmmc_periph | SD peripheral HAL |
sdmmc_req | SD request queue |
sdmmc_common | SD common utilities |
fatfs | FatFS file system |
sdspi | SD over SPI driver |
sd_diskio | SD disk I/O layer |
Call site: Called once at the start of app_main(), before the first call to sdcard_mount().
void app_main(void) { factory_log_silence_sd_stack(); // suppress SD stack chatter first // ... sdcard_mount();}Why this is needed in debug builds: When
FACTORY_LOG_LEVEL=1, the build uses the basesdkconfigwhich raises the global log ceiling toINFO. This causes the SD/FAT driver stack to emit its own internal progress messages — unrelated to factory logic — making the UART output difficult to read.factory_log_silence_sd_stack()re-mutes those specific tags at runtime after initialization.
Two-Layer Silencing Strategy
Section titled “Two-Layer Silencing Strategy”The module uses two complementary mechanisms to control log output, each targeting a different phase of boot:
| Layer | Mechanism | Phase | Controls |
|---|---|---|---|
| Static | sdkconfig.prod_log build overlay | Before app_main() | ESP-IDF boot banner, spi_flash, esp_partition, early FAT/SD startup logs |
| Dynamic | factory_log_silence_sd_stack() | Inside app_main() | SD/FAT driver runtime chatter across all 8 driver tags |
Build Configuration
Section titled “Build Configuration”Enabling Debug Logging
Section titled “Enabling Debug Logging”Each board’s Factory/CMakeLists.txt exposes an option that controls logging. When enabled, it:
- Defines
FACTORY_LOG_LEVEL=1soFACTORY_LOGDexpands toESP_LOGI - Selects the base
sdkconfig(INFO ceiling) instead of thesdkconfig.prod_logoverlay
option(ENABLE_FACTORY_DEBUG_LOG "Enable factory debug logging" OFF)
if(ENABLE_FACTORY_DEBUG_LOG) add_compile_definitions(FACTORY_LOG_LEVEL=1) # Build uses base sdkconfig (INFO-level ceiling)else() # Build applies sdkconfig.prod_log overlay (strict / silent)endif()To build with debug logging enabled:
idf.py -DENABLE_FACTORY_DEBUG_LOG=ON buildLog Level Matrix
Section titled “Log Level Matrix”| Build Mode | FACTORY_LOG_LEVEL | FACTORY_LOGD output | sdkconfig used | SD stack at runtime |
|---|---|---|---|---|
| Production | 0 | None (no-op) | sdkconfig.prod_log (strict ceiling) | Silenced at build level |
| Debug | 1 | ESP_LOGI(...) | base sdkconfig (INFO ceiling) | Silenced at runtime via factory_log_silence_sd_stack() |
Data Flow
Section titled “Data Flow”Relationship to Main Firmware Logging
Section titled “Relationship to Main Firmware Logging”The factory app’s logging system is entirely separate from the main firmware’s esp3d_log infrastructure. They share only the underlying ESP-IDF esp_log.h layer.
| Aspect | Factory App (factory_log.h) | Main Firmware (esp3d_log) |
|---|---|---|
| Primary macro | FACTORY_LOGD | esp3d_log / esp3d_log_d |
| Backend | ESP_LOGI — direct ESP-IDF call | Pluggable: serial, SD, telnet, WebSocket, UART2 |
| Runtime hooks | None | esp3d_log_register_hook |
| Verbosity control | Compile-time (FACTORY_LOG_LEVEL) | Two-tier: esp3d_log (always) / esp3d_log_d (debug only) |
| Scope | Factory standalone app only | Full main firmware stack |
| Shares code with main firmware | No | Yes — components/esp3d_log/ |
For main firmware logging details, see docs/guides/esp3d_log_guide.md.
Dependencies
Section titled “Dependencies”External dependencies: esp_log.h from ESP-IDF only.
Internal dependencies: None — no link-time dependency on any main firmware component.
Design Notes
Section titled “Design Notes”- Header-only: The entire module is a single
#pragma onceheader with no.cfile and no CMake component registration. Inclusion cost is zero. - Zero-cost in production:
FACTORY_LOGDexpands todo {} while (0). All optimizing compilers eliminate this completely — no instructions, no string literals emitted into the production binary. - No string tables in production: Because
FACTORY_LOGDis a no-op whenFACTORY_LOG_LEVEL=0,tagandfmtstring literals are never emitted into the production flash image. - Warnings and errors always active:
ESP_LOGWandESP_LOGEare used directly — they bypassFACTORY_LOGDand are never gated. Critical problems remain visible in both production and debug builds. - Per-board copy is intentional: The header is duplicated rather than placed in a shared component. Each board’s
Factory/directory is an independent ESP-IDF project; a shared component would require a common registry orEXTRA_COMPONENT_DIRSwiring that contradicts the factory app’s isolation model. static inlinefunction:factory_log_silence_sd_stack()is declaredstatic inlineto avoid duplicate-symbol link errors when the header is included in multiple translation units within the same factory build.
Related Documentation
Section titled “Related Documentation”- Factory Application & Bootloader — Parent module; contains the factory app entry point (
app_main) and all factory sub-modules - Factory SD Card — The SD card module whose verbose driver output
factory_log_silence_sd_stack()suppresses docs/guides/esp3d_log_guide.md— Main firmware logging system (esp3d_logmacros, backends, hook API); distinct from this moduledocs/Factory/— Factory app and custom bootloader overview documentation