Skip to content

Commit 11ecd5d

Browse files
authored
Merge pull request #87 from stamp/crashDump
Add /rest/coreDump endpoint
2 parents 606f1ad + b86622d commit 11ecd5d

File tree

6 files changed

+168
-2
lines changed

6 files changed

+168
-2
lines changed

lib/framework/CoreDump.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* ESP32 SvelteKit
3+
*
4+
* A simple, secure and extensible framework for IoT projects for ESP32 platforms
5+
* with responsive Sveltekit front-end built with TailwindCSS and DaisyUI.
6+
* https://github.com/theelims/ESP32-sveltekit
7+
*
8+
* Copyright (C) 2018 - 2023 rjwats
9+
* Copyright (C) 2023 - 2024 theelims
10+
*
11+
* All Rights Reserved. This software may be modified and distributed under
12+
* the terms of the LGPL v3 license. See the LICENSE file for details.
13+
**/
14+
15+
#include <CoreDump.h>
16+
#include <esp32-hal.h>
17+
18+
#include "esp_core_dump.h"
19+
#include "esp_partition.h"
20+
21+
static const char *TAG = "CoreDump";
22+
#define MIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
23+
24+
CoreDump::CoreDump(PsychicHttpServer *server,
25+
SecurityManager *securityManager) : _server(server),
26+
_securityManager(securityManager) {
27+
}
28+
29+
void CoreDump::begin() {
30+
_server->on(CORE_DUMP_SERVICE_PATH,
31+
HTTP_GET,
32+
_securityManager->wrapRequest(std::bind(&CoreDump::coreDump, this, std::placeholders::_1),
33+
AuthenticationPredicates::IS_AUTHENTICATED));
34+
35+
ESP_LOGV("CoreDump", "Registered GET endpoint: %s", CORE_DUMP_SERVICE_PATH);
36+
}
37+
38+
esp_err_t CoreDump::coreDump(PsychicRequest *request) {
39+
size_t coredump_addr;
40+
size_t coredump_size;
41+
esp_err_t err = esp_core_dump_image_get(&coredump_addr, &coredump_size);
42+
if (err != ESP_OK) {
43+
request->reply(500, "application/json", "{\"status\":\"error\",\"message\":\"core dump not available\"}");
44+
return err;
45+
}
46+
size_t const chunk_len = 3 * 16; // must be multiple of 3
47+
size_t const b64_len = chunk_len / 3 * 4 + 4;
48+
uint8_t *const chunk = (uint8_t *)malloc(chunk_len);
49+
char *const b64 = (char *)malloc(b64_len);
50+
assert(chunk && b64);
51+
52+
/*if (write_cfg->start) {
53+
if ((err = write_cfg->start(write_cfg->priv)) != ESP_OK) {
54+
return err;
55+
}
56+
}*/
57+
58+
ESP_LOGI(TAG, "Coredump is %u bytes", coredump_size);
59+
httpd_resp_set_status(request->request(), "200 OK");
60+
PsychicResponse response(request);
61+
response.setCode(200);
62+
response.setContentType("text/plain");
63+
response.sendHeaders();
64+
for (size_t offset = 0; offset < coredump_size; offset += chunk_len) {
65+
uint const read_len = MIN(chunk_len, coredump_size - offset);
66+
if (esp_flash_read(esp_flash_default_chip, chunk, coredump_addr + offset, read_len)) {
67+
ESP_LOGE(TAG, "Coredump read failed");
68+
break;
69+
}
70+
err = response.sendChunk(chunk, read_len);
71+
if (err != ESP_OK) {
72+
break;
73+
}
74+
}
75+
free(chunk);
76+
free(b64);
77+
78+
err = response.finishChunking();
79+
80+
/*uint32_t sec_num = coredump_size / SPI_FLASH_SEC_SIZE;
81+
if (coredump_size % SPI_FLASH_SEC_SIZE) {
82+
sec_num++;
83+
}
84+
err = esp_flash_erase_region(esp_flash_default_chip, coredump_addr, sec_num * SPI_FLASH_SEC_SIZE);
85+
if (err != ESP_OK) {
86+
ESP_LOGE(TAG, "Failed to erase coredump (%d)!", err);
87+
}*/
88+
return err;
89+
}

lib/framework/CoreDump.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef CoreDump_h
2+
#define CoreDump_h
3+
4+
/**
5+
* ESP32 SvelteKit
6+
*
7+
* A simple, secure and extensible framework for IoT projects for ESP32 platforms
8+
* with responsive Sveltekit front-end built with TailwindCSS and DaisyUI.
9+
* https://github.com/theelims/ESP32-sveltekit
10+
*
11+
* Copyright (C) 2018 - 2023 rjwats
12+
* Copyright (C) 2023 - 2024 theelims
13+
*
14+
* All Rights Reserved. This software may be modified and distributed under
15+
* the terms of the LGPL v3 license. See the LICENSE file for details.
16+
**/
17+
18+
#include <ArduinoJson.h>
19+
#include <ESPFS.h>
20+
#include <PsychicHttp.h>
21+
#include <SecurityManager.h>
22+
#include <WiFi.h>
23+
24+
#define CORE_DUMP_SERVICE_PATH "/rest/coreDump"
25+
26+
class CoreDump {
27+
public:
28+
CoreDump(PsychicHttpServer *server, SecurityManager *securityManager);
29+
30+
void begin();
31+
32+
private:
33+
PsychicHttpServer *_server;
34+
SecurityManager *_securityManager;
35+
esp_err_t coreDump(PsychicRequest *request);
36+
};
37+
38+
#endif // end CoreDump_h

lib/framework/ESP32SvelteKit.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ ESP32SvelteKit::ESP32SvelteKit(PsychicHttpServer *server, unsigned int numberEnd
5353
#endif
5454
_restartService(server, &_securitySettingsService),
5555
_factoryResetService(server, &ESPFS, &_securitySettingsService),
56-
_systemStatus(server, &_securitySettingsService)
56+
_systemStatus(server, &_securitySettingsService),
57+
_coreDump(server, &_securitySettingsService)
5758
{
5859
}
5960

@@ -147,6 +148,7 @@ void ESP32SvelteKit::begin()
147148
_wifiSettingsService.begin();
148149
_wifiScanner.begin();
149150
_wifiStatus.begin();
151+
_coreDump.begin();
150152

151153
#if FT_ENABLED(FT_UPLOAD_FIRMWARE)
152154
_uploadFirmwareService.begin();

lib/framework/ESP32SvelteKit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <SecuritySettingsService.h>
3939
#include <SleepService.h>
4040
#include <SystemStatus.h>
41+
#include <CoreDump.h>
4142
#include <WiFiScanner.h>
4243
#include <WiFiSettingsService.h>
4344
#include <WiFiStatus.h>
@@ -241,6 +242,7 @@ class ESP32SvelteKit
241242
RestartService _restartService;
242243
FactoryResetService _factoryResetService;
243244
SystemStatus _systemStatus;
245+
CoreDump _coreDump;
244246

245247
String _appName = APP_NAME;
246248

platformio.ini

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ extra_scripts =
7777
pre:scripts/generate_cert_bundle.py
7878
scripts/merge_bin.py
7979
scripts/rename_fw.py
80+
scripts/save_elf.py
8081
lib_deps =
8182
ArduinoJson@>=7.0.0
8283
elims/PsychicMqttClient@^0.2.2
@@ -120,4 +121,4 @@ board_upload.before_reset = usb_reset
120121
build_flags =
121122
${env.build_flags}
122123
-DARDUINO_USB_CDC_ON_BOOT=1
123-
-DARDUINO_USB_MODE=1
124+
-DARDUINO_USB_MODE=1

scripts/save_elf.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import shutil
2+
import re
3+
import os
4+
Import("env")
5+
import hashlib
6+
7+
8+
OUTPUT_DIR = "build{}elf{}".format(os.path.sep,os.path.sep)
9+
10+
def elf_copy(source, target, env):
11+
# check if output directories exist and create if necessary
12+
if not os.path.isdir("build"):
13+
os.mkdir("build")
14+
15+
if not os.path.isdir(OUTPUT_DIR):
16+
os.mkdir(OUTPUT_DIR)
17+
18+
with open(str(target[0]),"rb") as f:
19+
result = hashlib.sha256(f.read())
20+
21+
# create string with location and file names based on variant
22+
elf_file = "{}{}.elf".format(OUTPUT_DIR, result.hexdigest())
23+
24+
# check if new target files exist and remove if necessary
25+
for f in [elf_file]:
26+
if os.path.isfile(f):
27+
os.remove(f)
28+
29+
print("Saving ELF file to "+elf_file)
30+
31+
# copy firmware.bin to firmware/<variant>.bin
32+
shutil.copy(str(target[0]), elf_file)
33+
34+
env.AddPostAction("$BUILD_DIR/${PROGNAME}.elf", [elf_copy])

0 commit comments

Comments
 (0)