@mikrojs/firmware 0.12.0-next.9.g2e06437 → 0.13.0

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.
@@ -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: could not connect to %s (%s, errno=%d, "
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;
@@ -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 + 128];
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 = MIK_RunEntry(rt, test_paths[i]);
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
- int n = snprintf(s_sup_buf, sizeof(s_sup_buf),
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
  }
@@ -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.12.0-next.9.g2e06437",
3
+ "version": "0.13.0",
4
4
  "description": "Mikro.js ESP32 firmware: ESP-IDF component, build tools, and project template",
5
5
  "keywords": [
6
6
  "esp-idf",
@@ -51,8 +51,8 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "esbuild": "^0.28.0",
54
- "@mikrojs/native": "0.12.0-next.9.g2e06437",
55
- "@mikrojs/quickjs": "0.12.0-next.9.g2e06437"
54
+ "@mikrojs/native": "0.13.0",
55
+ "@mikrojs/quickjs": "0.13.0"
56
56
  },
57
57
  "engines": {
58
58
  "node": ">=24.0.0"
Binary file
Binary file
Binary file
Binary file
Binary file