Skip to content

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.


defines

0 - production default

1 - debug build

strict log ceiling

before app_main

raises sdkconfig ceiling to INFO

runtime fix

esp_log_level_set(NONE)

calls once at startup

uses throughout

always active

Factory/CMakeLists.txt

ENABLE_FACTORY_DEBUG_LOG

FACTORY_LOG_LEVEL

0 or 1

FACTORY_LOGD

→ no-op do{}while(0)

FACTORY_LOGD

→ ESP_LOGI

sdkconfig.prod_log

build-time overlay

ESP-IDF boot logs

silenced statically

SD stack becomes

verbose at runtime

factory_log_silence_sd_stack()

sdmmc / vfs_fat_sdmmc

sdmmc_periph / sdmmc_req

sdmmc_common / fatfs

sdspi / sd_diskio

app_main()

FACTORY_LOGD

ESP_LOGW / ESP_LOGE

warnings and errors

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.


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).

ESP-IDF Runtime

Build System

Factory Application

ENABLE_FACTORY_DEBUG_LOG

static log ceiling override

wraps

factory_logging

factory_log.h

factory_core

main.c

factory_graphics

gfx.c

factory_sdcard

sdcard.c

factory_buttons

buttons.c

factory_buzzer

buzzer.c

factory_encoder

encoder.c

Factory/CMakeLists.txt

sdkconfig.prod_log

esp_log.h

ESP_LOGI / esp_log_level_set


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.

BoardPath
esp32_3248s035cboards/esp32_3248s035c/Factory/main/factory_log.h
esp32_3248s035rboards/esp32_3248s035r/Factory/main/factory_log.h
esp32s3_4827s043cboards/esp32s3_4827s043c/Factory/main/factory_log.h
esp32s3_8048_touch_lcd_7boards/esp32s3_8048_touch_lcd_7/Factory/main/factory_log.h
esp32s3_8048s043cboards/esp32s3_8048s043c/Factory/main/factory_log.h
esp32s3_8048s050cboards/esp32s3_8048s050c/Factory/main/factory_log.h
esp32s3_8048s070cboards/esp32s3_8048s070c/Factory/main/factory_log.h
esp32s3_bzm_tft35_gt911boards/esp32s3_bzm_tft35_gt911/Factory/main/factory_log.h
esp32s3_hmi43v3boards/esp32s3_hmi43v3/Factory/main/factory_log.h
esp32s3_zx3d50ce02s_usrc_4832boards/esp32s3_zx3d50ce02s_usrc_4832/Factory/main/factory_log.h
pibot_pendant_v1_0boards/pibot_pendant_v1_0/Factory/main/factory_log.h

#ifndef FACTORY_LOG_LEVEL
#define FACTORY_LOG_LEVEL 0
#endif
AttributeValue
Default0 — production mode; all FACTORY_LOGD calls become no-ops
Set byENABLE_FACTORY_DEBUG_LOG option in Factory/CMakeLists.txt
ScopeIndependent of the global CONFIG_LOG_DEFAULT_LEVEL in sdkconfig

⚠️ This constant gates only FACTORY_LOGD calls. ESP_LOGW and ESP_LOGE are always active regardless of this value.


// 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

ParameterTypeDescription
tagconst char *ESP-IDF log tag string (e.g. "factory_sdcard")
fmtconst char *printf-style format string
...variadicFormat arguments

Behavior

ModeExpansionRuntime Cost
Production (FACTORY_LOG_LEVEL=0)do {} while (0) — null statementZero — 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;
}

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

TagDriver Component
sdmmcSD/MMC core driver
vfs_fat_sdmmcVFS layer over FAT on SD
sdmmc_periphSD peripheral HAL
sdmmc_reqSD request queue
sdmmc_commonSD common utilities
fatfsFatFS file system
sdspiSD over SPI driver
sd_diskioSD 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 base sdkconfig which raises the global log ceiling to INFO. 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.


The module uses two complementary mechanisms to control log output, each targeting a different phase of boot:

UART Outputapp_main()ESP-IDF Boot (before app_main)Build SystemUART Outputapp_main()ESP-IDF Boot (before app_main)Build SystemSilences spi_flash, esp_partition,fatfs/sdmmc boot banner, startup logsDynamic esp_log_level_set(NONE)for all 8 SD/FAT driver tagsApply sdkconfig.prod_log overlay(only when ENABLE_FACTORY_DEBUG_LOG=OFF)ESP-IDF internal boot logs(filtered by sdkconfig ceiling)factory_log_silence_sd_stack()FACTORY_LOGD → ESP_LOGI(only when FACTORY_LOG_LEVEL=1)ESP_LOGW / ESP_LOGE(always active, both modes)
LayerMechanismPhaseControls
Staticsdkconfig.prod_log build overlayBefore app_main()ESP-IDF boot banner, spi_flash, esp_partition, early FAT/SD startup logs
Dynamicfactory_log_silence_sd_stack()Inside app_main()SD/FAT driver runtime chatter across all 8 driver tags

Each board’s Factory/CMakeLists.txt exposes an option that controls logging. When enabled, it:

  1. Defines FACTORY_LOG_LEVEL=1 so FACTORY_LOGD expands to ESP_LOGI
  2. Selects the base sdkconfig (INFO ceiling) instead of the sdkconfig.prod_log overlay
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:

Terminal window
idf.py -DENABLE_FACTORY_DEBUG_LOG=ON build
Build ModeFACTORY_LOG_LEVELFACTORY_LOGD outputsdkconfig usedSD stack at runtime
Production0None (no-op)sdkconfig.prod_log (strict ceiling)Silenced at build level
Debug1ESP_LOGI(...)base sdkconfig (INFO ceiling)Silenced at runtime via factory_log_silence_sd_stack()

0 - production

1 - debug

> ESP_LOG_NONE

== ESP_LOG_NONE

(set by factory_log_silence_sd_stack)

Developer calls

FACTORY_LOGD(TAG, msg)

FACTORY_LOG_LEVEL?

Macro → do{}while(0)

Zero overhead, no output

Macro → ESP_LOGI(TAG, msg)

ESP-IDF log level

for this TAG?

Message emitted

to UART

Message suppressed

ESP_LOGW / ESP_LOGE calls

Always emitted

regardless of FACTORY_LOG_LEVEL


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.

AspectFactory App (factory_log.h)Main Firmware (esp3d_log)
Primary macroFACTORY_LOGDesp3d_log / esp3d_log_d
BackendESP_LOGI — direct ESP-IDF callPluggable: serial, SD, telnet, WebSocket, UART2
Runtime hooksNoneesp3d_log_register_hook
Verbosity controlCompile-time (FACTORY_LOG_LEVEL)Two-tier: esp3d_log (always) / esp3d_log_d (debug only)
ScopeFactory standalone app onlyFull main firmware stack
Shares code with main firmwareNoYes — components/esp3d_log/

For main firmware logging details, see docs/guides/esp3d_log_guide.md.


includes

consumed by

consumed by

consumed by

consumed by

consumed by

consumed by

factory_log.h

factory_logging

esp_log.h

ESP-IDF built-in

factory_core

main.c

factory_graphics

gfx.c

factory_sdcard

sdcard.c

factory_buttons

buttons.c

factory_buzzer

buzzer.c

factory_encoder

encoder.c

External dependencies: esp_log.h from ESP-IDF only.
Internal dependencies: None — no link-time dependency on any main firmware component.


  • Header-only: The entire module is a single #pragma once header with no .c file and no CMake component registration. Inclusion cost is zero.
  • Zero-cost in production: FACTORY_LOGD expands to do {} 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_LOGD is a no-op when FACTORY_LOG_LEVEL=0, tag and fmt string literals are never emitted into the production flash image.
  • Warnings and errors always active: ESP_LOGW and ESP_LOGE are used directly — they bypass FACTORY_LOGD and 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 or EXTRA_COMPONENT_DIRS wiring that contradicts the factory app’s isolation model.
  • static inline function: factory_log_silence_sd_stack() is declared static inline to avoid duplicate-symbol link errors when the header is included in multiple translation units within the same factory build.

  • 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_log macros, backends, hook API); distinct from this module
  • docs/Factory/ — Factory app and custom bootloader overview documentation