ESP32/components/app_console/cmd_system.c

165 lines
6.1 KiB
C

/*
* cmd_system.c
*
* Copyright (c) 2025 Umber Networks & Robert McMahon
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "esp_log.h"
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "esp_system.h"
#include "esp_chip_info.h"
#include "esp_mac.h"
#include "esp_heap_caps.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "app_console.h"
static const char *TAG = "CMD_SYS";
// ============================================================================
// COMMAND: system (Reboot, Info, Heap)
// ============================================================================
static struct {
struct arg_lit *reboot;
struct arg_lit *info;
struct arg_lit *heap;
struct arg_lit *help;
struct arg_end *end;
} sys_args;
static const char* get_chip_model_string(esp_chip_model_t model) {
switch (model) {
case CHIP_ESP32: return "ESP32";
case CHIP_ESP32S2: return "ESP32-S2";
case CHIP_ESP32S3: return "ESP32-S3";
case CHIP_ESP32C3: return "ESP32-C3";
case CHIP_ESP32C2: return "ESP32-C2";
case CHIP_ESP32C6: return "ESP32-C6";
case CHIP_ESP32H2: return "ESP32-H2";
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0))
case CHIP_ESP32C5: return "ESP32-C5"; // Requires recent IDF
case CHIP_ESP32P4: return "ESP32-P4";
#endif
default: return "Unknown";
}
}
static int cmd_system(int argc, char **argv) {
int nerrors = arg_parse(argc, argv, (void **)&sys_args);
if (nerrors > 0) {
arg_print_errors(stderr, sys_args.end, argv[0]);
return 1;
}
if (sys_args.help->count > 0) {
printf("Usage: system [--reboot|--info|--heap]\n");
printf(" --reboot Restart the device immediately\n");
printf(" --info Show chip model, revision, and MAC\n");
printf(" --heap Show current memory statistics\n");
return 0;
}
// --- HEAP STATS ---
if (sys_args.heap->count > 0) {
uint32_t free_heap = esp_get_free_heap_size();
uint32_t min_heap = esp_get_minimum_free_heap_size();
printf("Heap Summary:\n");
printf(" Free Heap: %" PRIu32 " bytes\n", free_heap);
printf(" Min Free Ever: %" PRIu32 " bytes\n", min_heap);
uint32_t internal = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
uint32_t dma = heap_caps_get_free_size(MALLOC_CAP_DMA);
printf(" Internal (SRAM): %" PRIu32 " bytes\n", internal);
printf(" DMA Capable: %" PRIu32 " bytes\n", dma);
}
// --- CHIP INFO ---
if (sys_args.info->count > 0) {
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
printf("Hardware Info:\n");
printf(" Model: %s\n", get_chip_model_string(chip_info.model));
printf(" Cores: %d\n", chip_info.cores);
// Revision format is typically MXX (Major, Minor)
printf(" Revision: v%d.%02d\n", chip_info.revision / 100, chip_info.revision % 100);
printf(" Features: ");
if (chip_info.features & CHIP_FEATURE_WIFI_BGN) printf("WiFi-BGN ");
if (chip_info.features & CHIP_FEATURE_BLE) printf("BLE ");
if (chip_info.features & CHIP_FEATURE_BT) printf("BT ");
if (chip_info.features & CHIP_FEATURE_EMB_FLASH) printf("Emb-Flash ");
if (chip_info.features & CHIP_FEATURE_IEEE802154) printf("802.15.4 (Zigbee/Thread) ");
printf("\n");
uint8_t mac[6];
if (esp_read_mac(mac, ESP_MAC_WIFI_STA) == ESP_OK) {
printf(" MAC (STA): %02x:%02x:%02x:%02x:%02x:%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
if (esp_read_mac(mac, ESP_MAC_WIFI_SOFTAP) == ESP_OK) {
printf(" MAC (AP): %02x:%02x:%02x:%02x:%02x:%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
}
// --- REBOOT ---
if (sys_args.reboot->count > 0) {
ESP_LOGW(TAG, "Reboot requested by user.");
printf("Rebooting system in 1 second...\n");
vTaskDelay(pdMS_TO_TICKS(1000));
esp_restart();
}
return 0;
}
void register_system_cmd(void) {
sys_args.reboot = arg_lit0(NULL, "reboot", "Reboot device");
sys_args.info = arg_lit0(NULL, "info", "Chip Info");
sys_args.heap = arg_lit0(NULL, "heap", "Memory Info");
sys_args.help = arg_lit0("h", "help", "Help");
sys_args.end = arg_end(1);
const esp_console_cmd_t cmd = {
.command = "system",
.help = "System Management (Reboot, Info, Heap)",
.func = &cmd_system,
.argtable = &sys_args
};
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
}