mirror of
https://github.com/xoseperez/espurna.git
synced 2026-03-04 23:44:20 +01:00
Change the underlying command line handling: - switch to a custom parser, inspired by redis / sds - update terminalRegisterCommand signature, pass only bare minimum - clean-up `help` & `commands`. update settings `set`, `get` and `del` - allow our custom test suite to run command-line tests - clean-up Stream IO to allow us to print large things into debug stream (for example, `eeprom.dump`) - send parsing errors to the debug log As a proof of concept, introduce `TERMINAL_MQTT_SUPPORT` and `TERMINAL_WEB_API_SUPPORT` - MQTT subscribes to the `<root>/cmd/set` and sends response to the `<root>/cmd`. We can't output too much, as we don't have any large-send API. - Web API listens to the `/api/cmd?apikey=...&line=...` (or PUT, params inside the body). This one is intended as a possible replacement of the `API_SUPPORT`. Internals introduce a 'task' around the AsyncWebServerRequest object that will simulate what WiFiClient does and push data into it continuously, switching between CONT and SYS. Both are experimental. We only accept a single command and not every command is updated to use Print `ctx.output` object. We are also somewhat limited by the Print / Stream overall, perhaps I am overestimating the usefulness of Arduino compatibility to such an extent :) Web API handler can also sometimes show only part of the result, whenever the command tries to yield() by itself waiting for something. Perhaps we would need to create a custom request handler for that specific use-case.
108 lines
2.4 KiB
C++
108 lines
2.4 KiB
C++
/*
|
|
|
|
RTMEM MODULE
|
|
|
|
Copyright (C) 2019 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
|
|
|
|
*/
|
|
|
|
#include "rtcmem.h"
|
|
|
|
volatile RtcmemData* Rtcmem = reinterpret_cast<volatile RtcmemData*>(RTCMEM_ADDR);
|
|
|
|
bool _rtcmem_status = false;
|
|
|
|
void _rtcmemErase() {
|
|
auto ptr = reinterpret_cast<volatile uint32_t*>(RTCMEM_ADDR);
|
|
const auto end = ptr + RTCMEM_BLOCKS;
|
|
DEBUG_MSG_P(PSTR("[RTCMEM] Erasing start=%p end=%p\n"), ptr, end);
|
|
do {
|
|
*ptr = 0;
|
|
} while (++ptr != end);
|
|
}
|
|
|
|
void _rtcmemInit() {
|
|
_rtcmemErase();
|
|
Rtcmem->magic = RTCMEM_MAGIC;
|
|
}
|
|
|
|
// Treat memory as dirty on cold boot, hardware wdt reset and rst pin
|
|
bool _rtcmemStatus() {
|
|
bool readable;
|
|
|
|
switch (systemResetReason()) {
|
|
case REASON_EXT_SYS_RST:
|
|
case REASON_WDT_RST:
|
|
case REASON_DEFAULT_RST:
|
|
readable = false;
|
|
break;
|
|
default:
|
|
readable = true;
|
|
}
|
|
|
|
readable = readable and (RTCMEM_MAGIC == Rtcmem->magic);
|
|
|
|
return readable;
|
|
}
|
|
|
|
#if TERMINAL_SUPPORT
|
|
|
|
void _rtcmemInitCommands() {
|
|
terminalRegisterCommand(F("RTCMEM.REINIT"), [](const terminal::CommandContext&) {
|
|
_rtcmemInit();
|
|
});
|
|
|
|
#if DEBUG_SUPPORT
|
|
terminalRegisterCommand(F("RTCMEM.DUMP"), [](const terminal::CommandContext&) {
|
|
|
|
DEBUG_MSG_P(PSTR("[RTCMEM] boot_status=%u status=%u blocks_used=%u\n"),
|
|
_rtcmem_status, _rtcmemStatus(), RtcmemSize);
|
|
|
|
String line;
|
|
line.reserve(96);
|
|
char buffer[16] = {0};
|
|
|
|
auto addr = reinterpret_cast<volatile uint32_t*>(RTCMEM_ADDR);
|
|
|
|
uint8_t block = 1;
|
|
uint8_t offset = 0;
|
|
uint8_t start = 0;
|
|
|
|
do {
|
|
|
|
offset = block - 1;
|
|
|
|
snprintf(buffer, sizeof(buffer), "%08x ", *(addr + offset));
|
|
line += buffer;
|
|
|
|
if ((block % 8) == 0) {
|
|
DEBUG_MSG_P(PSTR("%02u %p: %s\n"), start, addr+start, line.c_str());
|
|
start = block;
|
|
line = "";
|
|
}
|
|
|
|
++block;
|
|
|
|
} while (block<(RTCMEM_BLOCKS+1));
|
|
|
|
});
|
|
#endif
|
|
}
|
|
|
|
#endif
|
|
|
|
bool rtcmemStatus() {
|
|
return _rtcmem_status;
|
|
}
|
|
|
|
void rtcmemSetup() {
|
|
_rtcmem_status = _rtcmemStatus();
|
|
if (!_rtcmem_status) {
|
|
_rtcmemInit();
|
|
}
|
|
|
|
#if TERMINAL_SUPPORT
|
|
_rtcmemInitCommands();
|
|
#endif
|
|
}
|