Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/manual-build-artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ on:
workflow_dispatch:
inputs:
board_envs:
description: 'Comma-separated PlatformIO envs (e.g., "esp32s3,esp32c3").'
description: 'Comma-separated PlatformIO envs (e.g., "esp32s3,esp32c3,esp32c6,esp32c6m,seeed_esp32c6").'
required: true
default: "esp32s3"
default: "esp32s3,seeed_esp32c3,esp32,seeed_esp32s3,esp32c3,esp32c3supermini,esp32c6,esp32c6m,seeed_esp32c6"
git_ref:
description: 'Git ref to build (tag, branch, or SHA).'
required: true
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,18 @@ This creates an isolated build environment in `tools/.venv/` and `tools/.platfor
python tools/setup_local_env.py
```

### Stress mode (optional)

To accelerate loops and increase internal load for crash reproduction, build with:

```ini
# platformio.ini
# Add to an environment's build_flags (preserving existing flags):
build_flags =
${common.build_flags}
-DSTRESS_MODE
```

## Contributing

- Run `python tools/build_and_flash.py --local` before opening a PR (verifies the build still succeeds).
Expand Down
2 changes: 1 addition & 1 deletion distributor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ python -m http.server 8000
Then open `http://localhost:8000`. Use `?tag=v0.6.1-alpha` (or omit to use the latest release).

## Expected release assets
For each PlatformIO env (e.g., `esp32s3`, `esp32c3`, `esp32`, `seeed_esp32c3`, `seeed_esp32s3`, `esp32c3supermini`), the Release must include:
For each PlatformIO env (e.g., `esp32s3`, `esp32c3`, `esp32`, `seeed_esp32c3`, `seeed_esp32s3`, `esp32c3supermini`, `esp32c6`, `esp32c6m`, `seeed_esp32c6`), the Release must include:
- `<env>-firmware_merged.bin` (used for WebSerial flashing)
- `<env>-firmware.bin` (OTA app)
- `<env>-littlefs.bin` (OTA filesystem)
Expand Down
48 changes: 48 additions & 0 deletions distributor/boards.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,54 @@
"files": [
"firmware/seeed_esp32c3/firmware_merged.bin"
]
},
{
"id": "esp32c6",
"name": "OpenFilamentSensor",
"variant": "ESP32-C6",
"chipFamily": "ESP32-C6",
"status": "experimental",
"version": "0.5.0",
"released": "2026-03-01",
"manifest": "firmware/esp32c6/manifest.json",
"notes": [
"Experimental C6 build - untested"
],
"files": [
"firmware/esp32c6/firmware_merged.bin"
]
},
{
"id": "esp32c6m",
"name": "OpenFilamentSensor",
"variant": "ESP32-C6 DevKitM-1",
"chipFamily": "ESP32-C6",
"status": "experimental",
"version": "0.5.0",
"released": "2026-03-01",
"manifest": "firmware/esp32c6m/manifest.json",
"notes": [
"Experimental C6 DevKitM-1 build - untested"
],
"files": [
"firmware/esp32c6m/firmware_merged.bin"
]
},
{
"id": "seeed_esp32c6",
"name": "OpenFilamentSensor",
"variant": "Seeed XIAO ESP32-C6",
"chipFamily": "ESP32-C6",
"status": "experimental",
"version": "0.5.0",
"released": "2026-03-01",
"manifest": "firmware/seeed_esp32c6/manifest.json",
"notes": [
"Experimental Seeed XIAO ESP32-C6 build - untested"
],
"files": [
"firmware/seeed_esp32c6/firmware_merged.bin"
]
}
]
}
12 changes: 6 additions & 6 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ lib_deps =
adafruit/Adafruit GFX Library@^1.11.9
build_flags =
-D ELEGANTOTA_USE_ASYNC_WEBSERVER=1
; -D FILAMENT_RUNOUT_PIN=12
; -D MOVEMENT_SENSOR_PIN=13
-D FILAMENT_RUNOUT_PIN=12
-D MOVEMENT_SENSOR_PIN=13
; -D INVERT_RUNOUT_PIN=1 ; Uncomment in board config if pin logic is inverted
; Coredump configuration - saves crash info to flash partition for analysis
; -D CONFIG_APP_REPRODUCIBLE_BUILD=y ; commented out because
; Firmware ThumbprintFilesystemThumbprint,Project Status
; and Version displayed in the WebUI about tab might depend on them
-D CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=1
-D CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=1
-D CONFIG_ESP_COREDUMP_CHECKSUM_CRC32=1
-D CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=1
-D CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=1
-D CONFIG_ESP_COREDUMP_CHECKSUM_CRC32=1
; Crash testing endpoint (/api/panic) and UI section. Disable for release builds.
; -D ENABLE_CRASH_TESTING=1
extra_scripts =
Expand Down Expand Up @@ -197,7 +197,7 @@ build_unflags =
lib_deps =
${common.lib_deps}
lib_ignore =
WebServer ; arduino 3.x has its own synchrnous WebServer implementation that must be removed
WebServer ; arduino 3.x has its own synchronous WebServer implementation that must be removed
extra_scripts =
${common.extra_scripts}
post:tools/merge_bin.py
Expand Down
6 changes: 3 additions & 3 deletions src/ElegooCC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ printer_info_t ElegooCC::getCurrentInformation()
info.runoutPauseCommanded = runoutPauseCommanded;
info.runoutPauseRemainingMm = runoutPauseRemainingMm;
info.runoutPauseDelayMm = runoutPauseDelayMm;
info.mainboardID = mainboardID;
info.taskId = taskId;
info.filename = filename;
strlcpy(info.mainboardID, mainboardID.c_str(), sizeof(info.mainboardID));
strlcpy(info.taskId, taskId.c_str(), sizeof(info.taskId));
strlcpy(info.filename, filename.c_str(), sizeof(info.filename));
info.printStatus = printStatus;
info.isPrinting = (printStatus == SDCP_PRINT_STATUS_PRINTING && (machineStatusMask & (1 << SDCP_MACHINE_STATUS_PRINTING)) != 0);
info.currentLayer = currentLayer;
Expand Down
8 changes: 4 additions & 4 deletions src/ElegooCC.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ typedef enum
SDCP_COMMAND_STOP_FEEDING_MATERIAL = 132,
} sdcp_command_t;

// Struct to hold current printer information
// Struct to hold current printer information (uses fixed-size buffers to avoid heap allocations)
typedef struct
{
String mainboardID;
String taskId;
String filename;
char mainboardID[64];
char taskId[64];
char filename[128];
sdcp_print_status_t printStatus;
bool filamentStopped;
bool filamentRunout;
Expand Down
24 changes: 14 additions & 10 deletions src/Logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,17 @@ void Logger::logInternal(const char *message, LogLevel level)
return;
}

// Generate UUID
char uuid[37];
generateUUID(uuid);

// Get current timestamp
// Get current timestamp (safe to call outside critical section)
unsigned long timestamp = getTime();

// Critical section for buffer update
// Critical section for buffer update - UUID generation is inside
// to prevent duplicate uuidCounter values from concurrent log() calls
portENTER_CRITICAL(&_logMutex);

// Generate UUID inside critical section (uuidCounter++ must be atomic)
char uuid[37];
generateUUID(uuid);

// Store in circular buffer with fixed-size copy
strncpy(logBuffer[currentIndex].uuid, uuid, sizeof(logBuffer[currentIndex].uuid) - 1);
logBuffer[currentIndex].uuid[sizeof(logBuffer[currentIndex].uuid) - 1] = '\0';
Expand Down Expand Up @@ -211,9 +212,11 @@ String Logger::getLogsAsText(int maxEntries)
return result;
}

// Snapshot indices atomically to avoid race conditions
// Snapshot indices atomically under mutex (same pattern as streamLogs)
portENTER_CRITICAL(&_logMutex);
int snapshotIndex = currentIndex;
int snapshotCount = totalEntries;
portEXIT_CRITICAL(&_logMutex);

// Validate snapshot
if (snapshotCount < 0 || snapshotCount > logCapacity)
Expand Down Expand Up @@ -344,14 +347,15 @@ void Logger::streamLogs(Print* printer)

void Logger::clearLogs()
{
currentIndex = 0;
totalEntries = 0;
if (logCapacity == 0 || logBuffer == nullptr)
{
return;
}
// Clear the buffer
// Clear the buffer - indices MUST be inside the critical section
// to avoid TOCTOU race with logInternal()
portENTER_CRITICAL(&_logMutex);
currentIndex = 0;
totalEntries = 0;
for (int i = 0; i < logCapacity; i++)
{
memset(logBuffer[i].uuid, 0, sizeof(logBuffer[i].uuid));
Expand Down
Loading