@mikrojs/firmware 0.12.0 → 0.14.0-pr-229.g0d8db1b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -7
- package/components/mikrojs/CMakeLists.txt +1 -1
- package/components/mikrojs/include/mikrojs_esp32.h +4 -0
- package/components/mikrojs/mik_http.cpp +23 -1
- package/components/mikrojs/mik_logfile.cpp +22 -0
- package/components/mikrojs/mik_main.cpp +31 -3
- package/components/mikrojs/mik_sntp.cpp +9 -0
- package/components/mikrojs/mik_wifi.cpp +19 -0
- package/components/mikrojs/platform_esp32.cpp +38 -0
- package/package.json +3 -7
- package/prebuilds/esp32/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32/mikrojs.bin +0 -0
- package/prebuilds/esp32c3/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32c3/mikrojs.bin +0 -0
- package/prebuilds/esp32c5/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32c5/mikrojs.bin +0 -0
- package/prebuilds/esp32c6/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32c6/mikrojs.bin +0 -0
- package/prebuilds/esp32s3/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32s3/mikrojs.bin +0 -0
- package/sdkconfig.defaults +4 -4
- package/bin/idf.py +0 -7
package/README.md
CHANGED
|
@@ -6,20 +6,19 @@ ESP32 firmware package for Mikro.js. Provides the ESP-IDF integration, build sys
|
|
|
6
6
|
|
|
7
7
|
- **`project.cmake`** - CMake module that integrates with ESP-IDF. Handles component discovery, SDK config merging, and partition table defaults.
|
|
8
8
|
- **`components/mikrojs/`** - ESP-IDF component that compiles the Mikro.js runtime, QuickJS engine, and platform-specific C modules.
|
|
9
|
-
- **`idf.py` wrapper** - Runs `idf.py` through `eim run`, so you don't need to manually activate ESP-IDF.
|
|
10
9
|
- **Default configs** - `sdkconfig.defaults` and `partitions.csv` for common setups.
|
|
11
10
|
|
|
12
11
|
## Usage
|
|
13
12
|
|
|
14
|
-
A custom firmware project depends on this package and includes `project.cmake
|
|
13
|
+
A custom firmware project depends on this package and includes `project.cmake` (resolved via `resolve.js`, see the docs below for the CMakeLists boilerplate):
|
|
15
14
|
|
|
16
15
|
```
|
|
17
16
|
my-firmware/
|
|
18
17
|
├── package.json # depends on @mikrojs/firmware
|
|
19
|
-
├── CMakeLists.txt #
|
|
20
|
-
└── main/
|
|
21
|
-
├── CMakeLists.txt
|
|
22
|
-
└── main.cpp
|
|
18
|
+
├── CMakeLists.txt # resolves and includes project.cmake via resolve.js
|
|
19
|
+
└── main/ # optional: omit it and the package's default main
|
|
20
|
+
├── CMakeLists.txt # (which calls MIK_Main()) is used automatically
|
|
21
|
+
└── main.cpp
|
|
23
22
|
```
|
|
24
23
|
|
|
25
24
|
See the [Custom Firmware](https://mikrojs.dev/develop/custom-firmware) docs for details.
|
|
@@ -27,4 +26,6 @@ See the [Custom Firmware](https://mikrojs.dev/develop/custom-firmware) docs for
|
|
|
27
26
|
## Requirements
|
|
28
27
|
|
|
29
28
|
- Node.js >= 24
|
|
30
|
-
- ESP-IDF >= 6.0.1 (installed via [EIM](https://docs.espressif.com/projects/
|
|
29
|
+
- ESP-IDF >= 6.0.1 (installed via [EIM](https://docs.espressif.com/projects/idf-im-ui/en/latest/))
|
|
30
|
+
|
|
31
|
+
To build, activate ESP-IDF in your shell first: run `eim select` and source the activation script it prints, then use `idf.py` as usual.
|
|
@@ -134,7 +134,7 @@ include("${MIK_BYTECODE_CMAKE}")
|
|
|
134
134
|
|
|
135
135
|
# Force linker to include self-registering native modules
|
|
136
136
|
set(_MIK_MODULES cbor pin i2c spi http http_server wifi rtc nvs_kv sntp sleep neopixel pwm uart)
|
|
137
|
-
set(_MIK_BYTECODE_MODULES cbor env result schema fs http/helpers http/request http/server i2c kv/nvs kv/rtc kv/shared module neopixel observable observable/lazy observable/operators pin pwm reader sleep spi sntp stdio stream sys test uart udp wifi)
|
|
137
|
+
set(_MIK_BYTECODE_MODULES abort cbor env result schema fs http/helpers http/request http/server i2c kv/nvs kv/rtc kv/shared module neopixel observable observable/lazy observable/operators pin pwm reader sleep spi sntp stdio stream sys test uart udp wifi)
|
|
138
138
|
if(CONFIG_BT_ENABLED)
|
|
139
139
|
list(APPEND _MIK_MODULES ble)
|
|
140
140
|
list(APPEND _MIK_BYTECODE_MODULES ble)
|
|
@@ -60,6 +60,10 @@ void mik_logfile_flush(void);
|
|
|
60
60
|
* when file logging is disabled. */
|
|
61
61
|
void mik_logfile_suspend(void);
|
|
62
62
|
void mik_logfile_resume(void);
|
|
63
|
+
/* Clear the log files: close + unlink log.txt and log.txt.1, then reopen
|
|
64
|
+
* a fresh empty log.txt. Logging continues uninterrupted (no restart).
|
|
65
|
+
* No-op when file logging is disabled. */
|
|
66
|
+
void mik_logfile_reset(void);
|
|
63
67
|
|
|
64
68
|
/* Serial binary I/O (mik_serial_io.cpp) */
|
|
65
69
|
void mik__serial_binary_begin_no_echo(void);
|
|
@@ -218,9 +218,17 @@ static void mik__http_task(void* arg) {
|
|
|
218
218
|
int tls_flags = 0;
|
|
219
219
|
esp_err_t last_tls_err =
|
|
220
220
|
esp_http_client_get_and_clear_last_tls_error(client, &tls_code, &tls_flags);
|
|
221
|
+
/* Alloc-class failures surface as opaque transport codes: 0x008d
|
|
222
|
+
* is PSA's INSUFFICIENT_MEMORY (-141) leaking through the mbedtls
|
|
223
|
+
* slot untranslated, 0x7f00 is MBEDTLS_ERR_SSL_ALLOC_FAILED. Name
|
|
224
|
+
* the condition when a trustworthy code is present; otherwise
|
|
225
|
+
* keep the plain connect error (no heap-level guessing). */
|
|
226
|
+
bool out_of_memory = err == ESP_ERR_NO_MEM || last_tls_err == ESP_ERR_NO_MEM ||
|
|
227
|
+
tls_code == 0x008d || tls_code == 0x7f00;
|
|
221
228
|
snprintf(error_buf, sizeof(error_buf),
|
|
222
|
-
"fetch failed:
|
|
229
|
+
"fetch failed: %s %s (%s, errno=%d, "
|
|
223
230
|
"esp_tls=%s, mbedtls=-0x%04x, flags=0x%x)",
|
|
231
|
+
out_of_memory ? "out of memory connecting to" : "could not connect to",
|
|
224
232
|
args->req.url, esp_err_to_name(err), sock_errno,
|
|
225
233
|
esp_err_to_name(last_tls_err), tls_code, tls_flags);
|
|
226
234
|
have_error = true;
|
|
@@ -573,6 +581,14 @@ static JSValue mik__http_request(JSContext* ctx, JSValue this_val, int argc, JSV
|
|
|
573
581
|
MIKHttpPending pending = {};
|
|
574
582
|
pending.id = mik__http_st(mik_rt)->next_id++;
|
|
575
583
|
JSValue headers_promise = MIK_InitPromise(ctx, &pending.headers_promise);
|
|
584
|
+
if (JS_IsException(headers_promise)) {
|
|
585
|
+
/* OOM building the promise. Nothing is registered yet, so just free the
|
|
586
|
+
* request and propagate. Do NOT register this pending entry: its
|
|
587
|
+
* headers_promise.rfuncs are unwritten on failure, and a later
|
|
588
|
+
* consume/destroy would free dangling values (gc_decref underflow). */
|
|
589
|
+
mik__http_free_request(&req);
|
|
590
|
+
return JS_EXCEPTION;
|
|
591
|
+
}
|
|
576
592
|
|
|
577
593
|
auto* cancelled = new std::atomic<bool>(false);
|
|
578
594
|
pending.cancelled = cancelled;
|
|
@@ -664,6 +680,12 @@ static JSValue mik__http_next_message(JSContext* ctx, JSValue this_val, int argc
|
|
|
664
680
|
|
|
665
681
|
/* Slow path: wait. Create a new promise stored on the pending entry. */
|
|
666
682
|
JSValue promise = MIK_InitPromise(ctx, &p->next_promise);
|
|
683
|
+
if (JS_IsException(promise)) {
|
|
684
|
+
/* OOM building the promise. Do NOT mark next_promise_active: rfuncs are
|
|
685
|
+
* unwritten on failure, so a later resolve/destroy would free dangling
|
|
686
|
+
* values (gc_decref underflow). */
|
|
687
|
+
return JS_EXCEPTION;
|
|
688
|
+
}
|
|
667
689
|
p->next_promise_active = true;
|
|
668
690
|
return promise;
|
|
669
691
|
}
|
|
@@ -232,6 +232,28 @@ void mik_logfile_resume(void) {
|
|
|
232
232
|
xSemaphoreGive(s_mtx);
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
void mik_logfile_reset(void) {
|
|
236
|
+
if (!s_mtx) return;
|
|
237
|
+
if (xSemaphoreTake(s_mtx, pdMS_TO_TICKS(100)) != pdTRUE) return;
|
|
238
|
+
if (s_file) {
|
|
239
|
+
fclose(s_file);
|
|
240
|
+
s_file = nullptr;
|
|
241
|
+
}
|
|
242
|
+
unlink(s_path_main);
|
|
243
|
+
unlink(s_path_rot);
|
|
244
|
+
/* Reopen the same path: unlinked, so this starts a fresh empty file. */
|
|
245
|
+
s_file = fopen(s_path_main, "a");
|
|
246
|
+
if (s_file) {
|
|
247
|
+
setvbuf(s_file, s_stdio_buf, _IOFBF, sizeof(s_stdio_buf));
|
|
248
|
+
s_file_size = 0;
|
|
249
|
+
}
|
|
250
|
+
/* Drop any half-assembled line so a stale prefix doesn't bleed into
|
|
251
|
+
* the fresh file. */
|
|
252
|
+
s_line_pos = 0;
|
|
253
|
+
s_line_has_ts = false;
|
|
254
|
+
xSemaphoreGive(s_mtx);
|
|
255
|
+
}
|
|
256
|
+
|
|
235
257
|
void mik_logfile_flush(void) {
|
|
236
258
|
if (!s_mtx || !s_file) return;
|
|
237
259
|
if (xSemaphoreTake(s_mtx, pdMS_TO_TICKS(50)) != pdTRUE) return;
|
|
@@ -75,7 +75,11 @@ static void mik__apply_nvs_log_level(void) {
|
|
|
75
75
|
#define MIK_SUP_PATH_MAX 384
|
|
76
76
|
static char s_sup_dbg[MIK_SUP_PATH_MAX + 64];
|
|
77
77
|
static char s_sup_esc[MIK_SUP_PATH_MAX * 2 + 8];
|
|
78
|
-
static char s_sup_buf[MIK_SUP_PATH_MAX * 2 +
|
|
78
|
+
static char s_sup_buf[MIK_SUP_PATH_MAX * 2 + 512];
|
|
79
|
+
/* Exception text captured by MIK_RunEntryErr when a test file fails to
|
|
80
|
+
* evaluate, and its JSON-escaped form for the synthesized test event. */
|
|
81
|
+
static char s_sup_err[192];
|
|
82
|
+
static char s_sup_err_esc[sizeof(s_sup_err) * 2 + 8];
|
|
79
83
|
|
|
80
84
|
/* Minimal JSON string-escape into a bounded buffer. Handles `"`, `\`, and
|
|
81
85
|
* control characters; everything else copies verbatim. Returns bytes
|
|
@@ -169,6 +173,14 @@ static bool platform_command_handler(MIKReplTransport* transport, uint8_t cmd_ty
|
|
|
169
173
|
return mik__handle_fs_get(transport, payload_len);
|
|
170
174
|
}
|
|
171
175
|
|
|
176
|
+
/* Log reset (0x2C): clear the on-device log files */
|
|
177
|
+
if (cmd_type == MIK_CMD_LOG_RESET) {
|
|
178
|
+
mik__proto_drain(transport, payload_len);
|
|
179
|
+
mik_logfile_reset();
|
|
180
|
+
mik__proto_send_ok(transport);
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
|
|
172
184
|
/* Config commands (0x40-0x42) */
|
|
173
185
|
if (cmd_type >= MIK_CMD_CONFIG_LIST && cmd_type <= MIK_CMD_CONFIG_DELETE) {
|
|
174
186
|
return mik__handle_config_command(transport, cmd_type, payload_len);
|
|
@@ -476,7 +488,7 @@ void MIK_Main(void) {
|
|
|
476
488
|
MIKRuntime* rt = create_runtime();
|
|
477
489
|
MIK_EnableTestHelpers(rt);
|
|
478
490
|
MIK_ProtocolAttach(rt);
|
|
479
|
-
int rc =
|
|
491
|
+
int rc = MIK_RunEntryErr(rt, test_paths[i], s_sup_err, sizeof(s_sup_err));
|
|
480
492
|
const char* fail_reason = nullptr;
|
|
481
493
|
if (rc == -ENOENT) {
|
|
482
494
|
fail_reason = "Test file not found";
|
|
@@ -508,10 +520,26 @@ void MIK_Main(void) {
|
|
|
508
520
|
s_sup_esc[1] = '\0';
|
|
509
521
|
}
|
|
510
522
|
}
|
|
511
|
-
|
|
523
|
+
/* Append the captured exception text (escaped) so the CLI
|
|
524
|
+
* shows the actual error, not just "Evaluation threw". */
|
|
525
|
+
s_sup_err_esc[0] = '\0';
|
|
526
|
+
if (rc == -EFAULT && s_sup_err[0] != '\0') {
|
|
527
|
+
if (mik__json_escape(s_sup_err_esc, sizeof(s_sup_err_esc), s_sup_err) < 0) {
|
|
528
|
+
s_sup_err_esc[0] = '\0';
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
int n;
|
|
532
|
+
if (s_sup_err_esc[0] != '\0') {
|
|
533
|
+
n = snprintf(s_sup_buf, sizeof(s_sup_buf),
|
|
534
|
+
"{\"e\":3,\"s\":\"<load>\",\"t\":\"%s\",\"d\":0,"
|
|
535
|
+
"\"m\":\"%s: %s\"}",
|
|
536
|
+
s_sup_esc, fail_reason, s_sup_err_esc);
|
|
537
|
+
} else {
|
|
538
|
+
n = snprintf(s_sup_buf, sizeof(s_sup_buf),
|
|
512
539
|
"{\"e\":3,\"s\":\"<load>\",\"t\":\"%s\",\"d\":0,"
|
|
513
540
|
"\"m\":\"%s\"}",
|
|
514
541
|
s_sup_esc, fail_reason);
|
|
542
|
+
}
|
|
515
543
|
if (n > 0 && n < (int)sizeof(s_sup_buf)) {
|
|
516
544
|
mik__proto_send(&transport, MIK_MSG_TEST, s_sup_buf, n);
|
|
517
545
|
}
|
|
@@ -144,6 +144,15 @@ static JSValue mik__sntp_sync(JSContext* ctx, JSValue this_val, int argc, JSValu
|
|
|
144
144
|
|
|
145
145
|
/* Create and return promise wrapped in result */
|
|
146
146
|
JSValue promise = MIK_InitPromise(ctx, &state->sync_promise);
|
|
147
|
+
if (JS_IsException(promise)) {
|
|
148
|
+
/* OOM building the promise. Tear down so we don't leave a half-started
|
|
149
|
+
* sync, and crucially do NOT set sync_pending: MIK_InitPromise leaves
|
|
150
|
+
* sync_promise.rfuncs unwritten on failure, so a later consume/destroy
|
|
151
|
+
* would free dangling values (gc_decref refcount underflow). */
|
|
152
|
+
esp_netif_sntp_deinit();
|
|
153
|
+
state->running = false;
|
|
154
|
+
return JS_EXCEPTION;
|
|
155
|
+
}
|
|
147
156
|
state->sync_pending = true;
|
|
148
157
|
|
|
149
158
|
return mik__result_ok(ctx, promise);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#include <vector>
|
|
3
3
|
|
|
4
4
|
#include "esp_event.h"
|
|
5
|
+
#include "esp_heap_caps.h"
|
|
5
6
|
#include "esp_log.h"
|
|
6
7
|
#include "esp_mac.h"
|
|
7
8
|
#include "esp_netif.h"
|
|
@@ -332,6 +333,17 @@ fail_after_init:
|
|
|
332
333
|
return err;
|
|
333
334
|
}
|
|
334
335
|
|
|
336
|
+
/* Minimum free internal (DMA-capable) RAM required before bringing up the
|
|
337
|
+
* radio. esp_wifi_start() enables the PHY, which calloc()s its RF
|
|
338
|
+
* calibration data from internal RAM and calls abort() on failure
|
|
339
|
+
* (esp_phy/src/phy_init.c: "failed to allocate memory for RF calibration
|
|
340
|
+
* data"). That hard-abort reboots the device instead of surfacing a
|
|
341
|
+
* catchable error, so we pre-flight the heap here and refuse gracefully
|
|
342
|
+
* when it's too low. The figure covers the PHY cal buffers plus the WiFi
|
|
343
|
+
* driver's start-time internal allocations with margin; it is a heuristic,
|
|
344
|
+
* not an exact bound. Tune if a healthy device ever trips it. */
|
|
345
|
+
static constexpr size_t MIK_WIFI_MIN_INTERNAL_HEAP = 40 * 1024;
|
|
346
|
+
|
|
335
347
|
/* Start the WiFi radio. Deferred from init so the radio is not active
|
|
336
348
|
* until connect() or scan() is actually called. */
|
|
337
349
|
static esp_err_t mik__wifi_ensure_started(JSContext* ctx) {
|
|
@@ -339,6 +351,13 @@ static esp_err_t mik__wifi_ensure_started(JSContext* ctx) {
|
|
|
339
351
|
if (err != ESP_OK) return err;
|
|
340
352
|
if (s_wifi_started) return ESP_OK;
|
|
341
353
|
|
|
354
|
+
/* Refuse to start under low internal RAM rather than let the PHY init
|
|
355
|
+
* abort() the whole device. The caller turns ESP_ERR_NO_MEM into a
|
|
356
|
+
* catchable StartFailed result. */
|
|
357
|
+
if (heap_caps_get_free_size(MALLOC_CAP_INTERNAL) < MIK_WIFI_MIN_INTERNAL_HEAP) {
|
|
358
|
+
return ESP_ERR_NO_MEM;
|
|
359
|
+
}
|
|
360
|
+
|
|
342
361
|
err = esp_wifi_start();
|
|
343
362
|
if (err != ESP_OK) return err;
|
|
344
363
|
|
|
@@ -167,6 +167,43 @@ static const char* esp32_get_device_id(void) {
|
|
|
167
167
|
return id;
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
+
static const char* esp32_get_reset_reason(void) {
|
|
171
|
+
switch (esp_reset_reason()) {
|
|
172
|
+
case ESP_RST_POWERON:
|
|
173
|
+
return "power-on";
|
|
174
|
+
case ESP_RST_EXT:
|
|
175
|
+
return "external";
|
|
176
|
+
case ESP_RST_SW:
|
|
177
|
+
return "software";
|
|
178
|
+
case ESP_RST_PANIC:
|
|
179
|
+
return "panic";
|
|
180
|
+
case ESP_RST_INT_WDT:
|
|
181
|
+
return "interrupt-watchdog";
|
|
182
|
+
case ESP_RST_TASK_WDT:
|
|
183
|
+
return "task-watchdog";
|
|
184
|
+
case ESP_RST_WDT:
|
|
185
|
+
return "watchdog";
|
|
186
|
+
case ESP_RST_DEEPSLEEP:
|
|
187
|
+
return "deep-sleep";
|
|
188
|
+
case ESP_RST_BROWNOUT:
|
|
189
|
+
return "brownout";
|
|
190
|
+
case ESP_RST_SDIO:
|
|
191
|
+
return "sdio";
|
|
192
|
+
case ESP_RST_USB:
|
|
193
|
+
return "usb";
|
|
194
|
+
case ESP_RST_JTAG:
|
|
195
|
+
return "jtag";
|
|
196
|
+
case ESP_RST_EFUSE:
|
|
197
|
+
return "efuse";
|
|
198
|
+
case ESP_RST_PWR_GLITCH:
|
|
199
|
+
return "power-glitch";
|
|
200
|
+
case ESP_RST_CPU_LOCKUP:
|
|
201
|
+
return "cpu-lockup";
|
|
202
|
+
default:
|
|
203
|
+
return "unknown";
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
170
207
|
static void esp32_log(int level, const char* tag, const char* fmt, ...) {
|
|
171
208
|
/* Map MIK_LOG_xxx to ESP_LOG_xxx for the runtime filter check. */
|
|
172
209
|
esp_log_level_t esp_level;
|
|
@@ -238,6 +275,7 @@ static const MIKPlatform esp32_platform = {
|
|
|
238
275
|
.stderr_write = esp32_stderr_write,
|
|
239
276
|
.stdin_read = esp32_stdin_read,
|
|
240
277
|
.get_device_id = esp32_get_device_id,
|
|
278
|
+
.get_reset_reason = esp32_get_reset_reason,
|
|
241
279
|
};
|
|
242
280
|
|
|
243
281
|
/*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikrojs/firmware",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0-pr-229.g0d8db1b",
|
|
4
4
|
"description": "Mikro.js ESP32 firmware: ESP-IDF component, build tools, and project template",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"esp-idf",
|
|
@@ -18,9 +18,6 @@
|
|
|
18
18
|
"type": "git",
|
|
19
19
|
"url": "git+https://github.com/mikrojs/mikro.git"
|
|
20
20
|
},
|
|
21
|
-
"bin": {
|
|
22
|
-
"idf.py": "./bin/idf.py"
|
|
23
|
-
},
|
|
24
21
|
"files": [
|
|
25
22
|
"components",
|
|
26
23
|
"default-app",
|
|
@@ -28,7 +25,6 @@
|
|
|
28
25
|
"sdkconfig.defaults",
|
|
29
26
|
"sdkconfig.defaults.*",
|
|
30
27
|
"partitions.csv",
|
|
31
|
-
"bin",
|
|
32
28
|
"chips.json",
|
|
33
29
|
"cmake.js",
|
|
34
30
|
"discover.js",
|
|
@@ -51,8 +47,8 @@
|
|
|
51
47
|
},
|
|
52
48
|
"dependencies": {
|
|
53
49
|
"esbuild": "^0.28.0",
|
|
54
|
-
"@mikrojs/native": "0.
|
|
55
|
-
"@mikrojs/quickjs": "0.
|
|
50
|
+
"@mikrojs/native": "0.14.0-pr-229.g0d8db1b",
|
|
51
|
+
"@mikrojs/quickjs": "0.14.0-pr-229.g0d8db1b"
|
|
56
52
|
},
|
|
57
53
|
"engines": {
|
|
58
54
|
"node": ">=24.0.0"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/sdkconfig.defaults
CHANGED
|
@@ -21,11 +21,11 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
|
|
21
21
|
# Use -Os to reduce code size (less IRAM pressure, smaller function frames)
|
|
22
22
|
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
|
23
23
|
|
|
24
|
-
# Move
|
|
25
|
-
# SRAM on single-core chips like C3/C6, so freeing IRAM also frees DRAM)
|
|
24
|
+
# Move heap functions from IRAM to flash (IRAM and DRAM share the same
|
|
25
|
+
# SRAM on single-core chips like C3/C6, so freeing IRAM also frees DRAM).
|
|
26
|
+
# FreeRTOS and esp_ringbuf functions are placed in flash by default since
|
|
27
|
+
# ESP-IDF 6.0; their *_PLACE_FUNCTIONS_INTO_FLASH options were removed.
|
|
26
28
|
CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH=y
|
|
27
|
-
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
|
28
|
-
CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y
|
|
29
29
|
|
|
30
30
|
# Trade WiFi throughput for ~15-20KB IRAM savings. Fine for mikrojs
|
|
31
31
|
# workloads (HTTP requests, small payloads — not high-throughput streaming).
|