feat: prove build, flashing, and stable basic operation
This commit is contained in:
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
.obsidian
|
.obsidian
|
||||||
sdkconfig.esp32-c6-devkitm-1
|
sdkconfig.esp32-c6-devkitm-1
|
||||||
.pio/build
|
.pio
|
||||||
|
.vscode
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ If all criteria pass, set this milestone to `DONE`, append its execution record,
|
|||||||
|
|
||||||
## Milestone 001 — Prove build, flashing, and stable basic operation
|
## Milestone 001 — Prove build, flashing, and stable basic operation
|
||||||
|
|
||||||
**Status:** `IN PROGRESS`
|
**Status:** `DONE`
|
||||||
**Depends on:** Milestone 000
|
**Depends on:** Milestone 000
|
||||||
|
|
||||||
### Objective
|
### Objective
|
||||||
@@ -153,11 +153,21 @@ Prove that the configuration selected in Milestone 000 works reliably on the phy
|
|||||||
|
|
||||||
If all criteria pass, set this milestone to `DONE`, append its execution record, and change Milestone 002 from `BLOCKED` to `READY`.
|
If all criteria pass, set this milestone to `DONE`, append its execution record, and change Milestone 002 from `BLOCKED` to `READY`.
|
||||||
|
|
||||||
|
Execution record
|
||||||
|
- Date: 2026-08-27
|
||||||
|
- Board model and revision: ESP32-C6FH4 QFN32, revision v0.2; the carrier board remains an unidentified SuperMini-style ESP32-C6 Mini.
|
||||||
|
- Toolchain and library versions: PlatformIO Core 6.1.19; `espressif32` 7.0.1; ESP-IDF 6.0.1; esptool.py 4.11.0; RISC-V toolchain 15.2.0+20251204.
|
||||||
|
- Result: PASS
|
||||||
|
- Evidence: `src/main.c` now logs reset reason, chip details, flash size, uptime, free heap, and minimum free heap every 30 seconds without Wi-Fi. `platformio.ini`, `sdkconfig.esp32-c6-devkitm-1`, and `partitions.csv` pin the platform, configure 4 MB flash, and select a verified 2 MB factory application plus 1,984 KB LittleFS partition. Four successful esptool upload cycles detected the ESP32-C6FH4 with 4 MB embedded flash, verified all written hashes, and hard-reset the board. The final upload wrote the bootloader at `0x0`, partition table at `0x8000`, and firmware at `0x10000`; decoding `.pio/build/esp32-c6-devkitm-1/partitions.bin` confirmed the configured NVS, PHY, factory, and LittleFS partitions. On 2026-08-27, the user reported that the no-Wi-Fi two-hour run completed successfully and confirmed that removing and restoring USB power produced a normal boot.
|
||||||
|
- Measurements: Final clean build: RAM 11,116 / 327,680 bytes (3.4%); firmware 161,288 / 2,097,152 bytes (7.7%). Device diagnostics repeatedly reported `reset_reason=usb`, `flash_bytes=4194304`, `free_heap_bytes=470012`, and `min_free_heap_bytes=470012` from uptime 15 to 195 seconds, with no error, watchdog, or unexpected restart observed. The candidate GPIO8 probe completed while native USB serial remained available.
|
||||||
|
- Issues or deviations: `pio test -e esp32-c6-devkitm-1 --without-uploading` found no test suites in `test/`. The user explicitly directed that visual confirmation of the GPIO8 LED probe be skipped; the LED wiring and polarity remain unconfirmed and must not be relied on by future work.
|
||||||
|
- Next action: Milestone 002 is ready but is not started as part of this milestone.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Milestone 002 — Prove the Wi-Fi, LittleFS, and HTTP vertical slice
|
## Milestone 002 — Prove the Wi-Fi, LittleFS, and HTTP vertical slice
|
||||||
|
|
||||||
**Status:** `BLOCKED`
|
**Status:** `READY`
|
||||||
**Depends on:** Milestone 001
|
**Depends on:** Milestone 001
|
||||||
|
|
||||||
### Objective
|
### Objective
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
|
factory, app, factory, 0x10000, 0x200000,
|
||||||
|
littlefs, data, littlefs,0x210000, 0x1f0000,
|
||||||
|
+4
-1
@@ -9,6 +9,9 @@
|
|||||||
; https://docs.platformio.org/page/projectconf.html
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
[env:esp32-c6-devkitm-1]
|
[env:esp32-c6-devkitm-1]
|
||||||
platform = espressif32
|
platform = espressif32 @ 7.0.1
|
||||||
board = esp32-c6-devkitm-1
|
board = esp32-c6-devkitm-1
|
||||||
framework = espidf
|
framework = espidf
|
||||||
|
board_build.partitions = partitions.csv
|
||||||
|
monitor_port = /dev/ttyACM0
|
||||||
|
monitor_speed = 115200
|
||||||
|
|||||||
+141
-1
@@ -1 +1,141 @@
|
|||||||
void app_main() {}
|
#include <inttypes.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "esp_chip_info.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_flash.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_timer.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
|
||||||
|
static const char *const kLogTag = "bringup";
|
||||||
|
static const gpio_num_t kCandidateLedGpio = GPIO_NUM_8;
|
||||||
|
static const uint32_t kLedProbeCount = 10;
|
||||||
|
static const uint32_t kLedProbeIntervalMs = 500;
|
||||||
|
static const uint32_t kHealthIntervalMs = 30000;
|
||||||
|
static const uint32_t kStartupAttachmentDelayMs = 10000;
|
||||||
|
|
||||||
|
static const char *reset_reason_name(esp_reset_reason_t reason) {
|
||||||
|
switch (reason) {
|
||||||
|
case ESP_RST_UNKNOWN:
|
||||||
|
return "unknown";
|
||||||
|
case ESP_RST_POWERON:
|
||||||
|
return "power_on";
|
||||||
|
case ESP_RST_EXT:
|
||||||
|
return "external";
|
||||||
|
case ESP_RST_SW:
|
||||||
|
return "software";
|
||||||
|
case ESP_RST_PANIC:
|
||||||
|
return "panic";
|
||||||
|
case ESP_RST_INT_WDT:
|
||||||
|
return "interrupt_watchdog";
|
||||||
|
case ESP_RST_TASK_WDT:
|
||||||
|
return "task_watchdog";
|
||||||
|
case ESP_RST_WDT:
|
||||||
|
return "other_watchdog";
|
||||||
|
case ESP_RST_DEEPSLEEP:
|
||||||
|
return "deep_sleep";
|
||||||
|
case ESP_RST_BROWNOUT:
|
||||||
|
return "brownout";
|
||||||
|
case ESP_RST_SDIO:
|
||||||
|
return "sdio";
|
||||||
|
case ESP_RST_USB:
|
||||||
|
return "usb";
|
||||||
|
case ESP_RST_JTAG:
|
||||||
|
return "jtag";
|
||||||
|
case ESP_RST_EFUSE:
|
||||||
|
return "efuse";
|
||||||
|
case ESP_RST_PWR_GLITCH:
|
||||||
|
return "power_glitch";
|
||||||
|
case ESP_RST_CPU_LOCKUP:
|
||||||
|
return "cpu_lockup";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "unrecognized";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_heap(uint64_t uptime_ms) {
|
||||||
|
const size_t free_heap_bytes = esp_get_free_heap_size();
|
||||||
|
const size_t minimum_free_heap_bytes = esp_get_minimum_free_heap_size();
|
||||||
|
uint32_t flash_size_bytes = 0;
|
||||||
|
const esp_err_t flash_result = esp_flash_get_size(NULL, &flash_size_bytes);
|
||||||
|
|
||||||
|
if (flash_result == ESP_OK) {
|
||||||
|
ESP_LOGI(kLogTag,
|
||||||
|
"health uptime_ms=%" PRIu64 " reset_reason=%s flash_bytes=%" PRIu32
|
||||||
|
" free_heap_bytes=%u min_free_heap_bytes=%u",
|
||||||
|
uptime_ms,
|
||||||
|
reset_reason_name(esp_reset_reason()),
|
||||||
|
flash_size_bytes,
|
||||||
|
(unsigned int)free_heap_bytes,
|
||||||
|
(unsigned int)minimum_free_heap_bytes);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(kLogTag, "health flash_size_failed=%s", esp_err_to_name(flash_result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void probe_candidate_led(void) {
|
||||||
|
ESP_LOGI(kLogTag,
|
||||||
|
"led_probe gpio=%d transitions=%" PRIu32 " interval_ms=%" PRIu32 "; visually confirm the LED",
|
||||||
|
(int)kCandidateLedGpio,
|
||||||
|
kLedProbeCount,
|
||||||
|
kLedProbeIntervalMs);
|
||||||
|
|
||||||
|
esp_err_t result = gpio_reset_pin(kCandidateLedGpio);
|
||||||
|
if (result != ESP_OK) {
|
||||||
|
ESP_LOGW(kLogTag, "led_probe gpio_reset_pin failed: %s", esp_err_to_name(result));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = gpio_set_direction(kCandidateLedGpio, GPIO_MODE_OUTPUT);
|
||||||
|
if (result != ESP_OK) {
|
||||||
|
ESP_LOGW(kLogTag, "led_probe gpio_set_direction failed: %s", esp_err_to_name(result));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t transition = 0; transition < kLedProbeCount; ++transition) {
|
||||||
|
gpio_set_level(kCandidateLedGpio, transition % 2U);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(kLedProbeIntervalMs));
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_set_level(kCandidateLedGpio, 0);
|
||||||
|
ESP_LOGI(kLogTag, "led_probe complete; USB serial remained available during probe");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_startup(void) {
|
||||||
|
esp_chip_info_t chip_info = {0};
|
||||||
|
uint32_t flash_size_bytes = 0;
|
||||||
|
const esp_err_t flash_result = esp_flash_get_size(NULL, &flash_size_bytes);
|
||||||
|
|
||||||
|
esp_chip_info(&chip_info);
|
||||||
|
ESP_LOGI(kLogTag,
|
||||||
|
"startup reset_reason=%s chip_model=%d chip_revision=%d cores=%d features=0x%08" PRIx32,
|
||||||
|
reset_reason_name(esp_reset_reason()),
|
||||||
|
(int)chip_info.model,
|
||||||
|
chip_info.revision,
|
||||||
|
chip_info.cores,
|
||||||
|
chip_info.features);
|
||||||
|
|
||||||
|
if (flash_result == ESP_OK) {
|
||||||
|
ESP_LOGI(kLogTag, "startup flash_bytes=%" PRIu32, flash_size_bytes);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(kLogTag, "startup flash_size_failed=%s", esp_err_to_name(flash_result));
|
||||||
|
}
|
||||||
|
|
||||||
|
log_heap(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main(void) {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(kStartupAttachmentDelayMs));
|
||||||
|
log_startup();
|
||||||
|
probe_candidate_led();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
log_heap((uint64_t)(esp_timer_get_time() / 1000));
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(kHealthIntervalMs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user