Implement support for ESP32 C6 and P4 SOCs (#421)

- Implement generic ESP32 devices
- Updated GitHub Actions to first build the SDKs. These are now based on the generic device implementations and the build act as a filter before compiling the dozens of other devices. It should save on resources when boards fail to compile.
- Adapted code to C6 and P4 differences, heavily borrowed from from https://github.com/ByteWelder/Tactility/pull/394 written by @marciogranzotto, with some changes of my own
- Updated `device.py` to make the `[display]` section optional
This commit is contained in:
Ken Van Hoeylandt 2025-11-24 19:28:07 +01:00 committed by GitHub
parent fec8033fd7
commit b565d56029
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 279 additions and 72 deletions

View File

@ -1,26 +0,0 @@
name: Build SDK
on:
push:
branches:
- main
pull_request:
types: [ opened, synchronize, reopened ]
permissions: read-all
jobs:
Build:
strategy:
matrix:
board: [
{ id: cyd-2432s028r, arch: esp32 },
{ id: lilygo-tdeck, arch: esp32s3 },
]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: "Build"
uses: ./.github/actions/build-sdk
with:
board_id: ${{ matrix.board.id }}
arch: ${{ matrix.board.arch }}

View File

@ -11,7 +11,24 @@ on:
permissions: read-all permissions: read-all
jobs: jobs:
Build: BuildSdk:
strategy:
matrix:
board: [
{ id: generic-esp32, arch: esp32 },
{ id: generic-esp32c6, arch: esp32c6 },
{ id: generic-esp32p4, arch: esp32p4 },
{ id: generic-esp32s3, arch: esp32s3 },
]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: "Build SDK"
uses: ./.github/actions/build-sdk
with:
board_id: ${{ matrix.board.id }}
arch: ${{ matrix.board.arch }}
BuildFirmware:
strategy: strategy:
matrix: matrix:
board: [ board: [
@ -52,30 +69,31 @@ jobs:
{ id: waveshare-s3-touch-lcd-43, arch: esp32s3 } { id: waveshare-s3-touch-lcd-43, arch: esp32s3 }
] ]
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [ BuildSdk ]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: "Build" - name: "Build Firmware"
uses: ./.github/actions/build-firmware uses: ./.github/actions/build-firmware
with: with:
board_id: ${{ matrix.board.id }} board_id: ${{ matrix.board.id }}
arch: ${{ matrix.board.arch }} arch: ${{ matrix.board.arch }}
Bundle: BundleFirmware:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [ Build ] needs: [ BuildFirmware ]
if: | if: |
(github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'push' && github.ref == 'refs/heads/main') ||
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: "Bundle" - name: "Bundle Firmware"
uses: ./.github/actions/bundle-firmware uses: ./.github/actions/bundle-firmware
PublishSnapshot: PublishFirmwareSnapshot:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [ Bundle ] needs: [ BundleFirmware ]
if: (github.event_name == 'push' && github.ref == 'refs/heads/main') if: (github.event_name == 'push' && github.ref == 'refs/heads/main')
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: "Publish Snapshot" - name: "Publish Firmware Snapshot"
env: env:
CDN_ID: ${{ secrets.CDN_ID }} CDN_ID: ${{ secrets.CDN_ID }}
CDN_TOKEN_NAME: ${{ secrets.CDN_TOKEN_NAME }} CDN_TOKEN_NAME: ${{ secrets.CDN_TOKEN_NAME }}
@ -83,13 +101,13 @@ jobs:
uses: ./.github/actions/publish-firmware uses: ./.github/actions/publish-firmware
with: with:
cdn_version: snapshot cdn_version: snapshot
PublishRelease: PublishFirmwareStable:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [ Bundle ] needs: [ BundleFirmware ]
if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: "Publish Stable" - name: "Publish Firmware Stable"
env: env:
CDN_ID: ${{ secrets.CDN_ID }} CDN_ID: ${{ secrets.CDN_ID }}
CDN_TOKEN_NAME: ${{ secrets.CDN_TOKEN_NAME }} CDN_TOKEN_NAME: ${{ secrets.CDN_TOKEN_NAME }}

View File

@ -48,7 +48,11 @@ if (DEFINED ENV{ESP_IDF_VERSION})
set(EXCLUDE_COMPONENTS "Simulator") set(EXCLUDE_COMPONENTS "Simulator")
idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=esp_panic_handler" APPEND) # Panic handler wrapping is only available on Xtensa architecture
if (CONFIG_IDF_TARGET_ARCH_XTENSA)
idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=esp_panic_handler" APPEND)
endif ()
idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=lv_button_create" APPEND) idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=lv_button_create" APPEND)
idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=lv_dropdown_create" APPEND) idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=lv_dropdown_create" APPEND)
idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=lv_list_create" APPEND) idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=lv_list_create" APPEND)

View File

@ -0,0 +1,7 @@
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
idf_component_register(
SRCS ${SOURCE_FILES}
INCLUDE_DIRS "Source"
REQUIRES Tactility
)

View File

@ -0,0 +1,3 @@
#include <Tactility/hal/Configuration.h>
extern const tt::hal::Configuration hardwareConfiguration = {};

View File

@ -0,0 +1,9 @@
[general]
vendor=Generic
name=ESP32
[hardware]
target=ESP32
flashSize=4MB
spiRam=false

View File

@ -0,0 +1,7 @@
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
idf_component_register(
SRCS ${SOURCE_FILES}
INCLUDE_DIRS "Source"
REQUIRES Tactility
)

View File

@ -0,0 +1,3 @@
#include <Tactility/hal/Configuration.h>
extern const tt::hal::Configuration hardwareConfiguration = {};

View File

@ -0,0 +1,9 @@
[general]
vendor=Generic
name=ESP32-C6
[hardware]
target=ESP32C6
flashSize=4MB
spiRam=false

View File

@ -0,0 +1,7 @@
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
idf_component_register(
SRCS ${SOURCE_FILES}
INCLUDE_DIRS "Source"
REQUIRES Tactility
)

View File

@ -0,0 +1,3 @@
#include <Tactility/hal/Configuration.h>
extern const tt::hal::Configuration hardwareConfiguration = {};

View File

@ -0,0 +1,9 @@
[general]
vendor=Generic
name=ESP32-P4
[hardware]
target=ESP32P4
flashSize=4MB
spiRam=false

View File

@ -0,0 +1,7 @@
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
idf_component_register(
SRCS ${SOURCE_FILES}
INCLUDE_DIRS "Source"
REQUIRES Tactility
)

View File

@ -0,0 +1,3 @@
#include <Tactility/hal/Configuration.h>
extern const tt::hal::Configuration hardwareConfiguration = {};

View File

@ -0,0 +1,9 @@
[general]
vendor=Generic
name=ESP32-S3
[hardware]
target=ESP32S3
flashSize=4MB
spiRam=false

View File

@ -1,9 +1,21 @@
dependencies: dependencies:
espressif/esp_lcd_ili9341: "2.0.1" espressif/esp_lcd_ili9341:
atanisoft/esp_lcd_ili9488: "1.0.10" version: "2.0.1"
teriyakigod/esp_lcd_st7735: "0.0.1" rules:
- if: "target in [esp32, esp32s3]"
atanisoft/esp_lcd_ili9488:
version: "1.0.10"
rules:
- if: "target in [esp32, esp32s3]"
teriyakigod/esp_lcd_st7735:
version: "0.0.1"
rules:
- if: "target in [esp32, esp32s3]"
espressif/esp_lcd_touch: "1.1.2" espressif/esp_lcd_touch: "1.1.2"
atanisoft/esp_lcd_touch_xpt2046: "1.0.5" atanisoft/esp_lcd_touch_xpt2046:
version: "1.0.5"
rules:
- if: "target in [esp32, esp32s3]"
espressif/esp_lcd_touch_cst816s: "1.0.3" espressif/esp_lcd_touch_cst816s: "1.0.3"
espressif/esp_lcd_touch_gt911: "1.1.3" espressif/esp_lcd_touch_gt911: "1.1.3"
espressif/esp_lcd_touch_ft5x06: "1.0.6~1" espressif/esp_lcd_touch_ft5x06: "1.0.6~1"
@ -15,6 +27,8 @@ dependencies:
- if: "target in [esp32s3, esp32p4]" - if: "target in [esp32s3, esp32p4]"
espressif/esp_lcd_st7796: espressif/esp_lcd_st7796:
version: "1.3.4" version: "1.3.4"
rules:
- if: "target in [esp32, esp32s3]"
espressif/esp_lcd_gc9a01: "2.0.3" espressif/esp_lcd_gc9a01: "2.0.3"
espressif/esp_lcd_panel_io_additions: "1.0.1" espressif/esp_lcd_panel_io_additions: "1.0.1"
espressif/esp_tinyusb: espressif/esp_tinyusb:

View File

@ -1,5 +1,10 @@
#pragma once #pragma once
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#include <sdkconfig.h>
#endif
#ifdef CONFIG_ESP_WIFI_ENABLED
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>

View File

@ -1,9 +1,13 @@
#pragma once #pragma once
#ifdef ESP_PLATFORM
#include "Tactility/MessageQueue.h" #ifdef ESP_PLATFORM
#include "Tactility/service/Service.h" #include <sdkconfig.h>
#include "Tactility/service/espnow/EspNow.h" #endif
#ifdef CONFIG_ESP_WIFI_ENABLED
#include <Tactility/service/Service.h>
#include <Tactility/service/espnow/EspNow.h>
#include <Tactility/Mutex.h> #include <Tactility/Mutex.h>
@ -13,8 +17,6 @@ namespace tt::service::espnow {
class EspNowService final : public Service { class EspNowService final : public Service {
private:
struct ReceiverSubscriptionData { struct ReceiverSubscriptionData {
ReceiverSubscription id; ReceiverSubscription id;
std::function<void(const esp_now_recv_info_t* receiveInfo, const uint8_t* data, int length)> onReceive; std::function<void(const esp_now_recv_info_t* receiveInfo, const uint8_t* data, int length)> onReceive;

View File

@ -1,5 +1,11 @@
#pragma once #pragma once
#ifdef ESP_PLATFORM
#include <sdkconfig.h>
#endif
#ifdef CONFIG_ESP_WIFI_ENABLED
#include "Tactility/service/espnow/EspNow.h" #include "Tactility/service/espnow/EspNow.h"
namespace tt::service::espnow { namespace tt::service::espnow {
@ -9,3 +15,5 @@ bool initWifi(const EspNowConfig& config);
bool deinitWifi(); bool deinitWifi();
} }
#endif

View File

@ -1,3 +1,7 @@
#ifdef ESP_PLATFORM
#include <sdkconfig.h>
#endif
#include <Tactility/Tactility.h> #include <Tactility/Tactility.h>
#include <Tactility/TactilityConfig.h> #include <Tactility/TactilityConfig.h>
@ -38,6 +42,8 @@ namespace service {
namespace sdcard { extern const ServiceManifest manifest; } namespace sdcard { extern const ServiceManifest manifest; }
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
namespace development { extern const ServiceManifest manifest; } namespace development { extern const ServiceManifest manifest; }
#endif
#ifdef CONFIG_ESP_WIFI_ENABLED
namespace espnow { extern const ServiceManifest manifest; } namespace espnow { extern const ServiceManifest manifest; }
#endif #endif
// Secondary (UI) // Secondary (UI)
@ -64,7 +70,9 @@ namespace app {
namespace applist { extern const AppManifest manifest; } namespace applist { extern const AppManifest manifest; }
namespace appsettings { extern const AppManifest manifest; } namespace appsettings { extern const AppManifest manifest; }
namespace boot { extern const AppManifest manifest; } namespace boot { extern const AppManifest manifest; }
#ifdef CONFIG_ESP_WIFI_ENABLED
namespace chat { extern const AppManifest manifest; } namespace chat { extern const AppManifest manifest; }
#endif
namespace development { extern const AppManifest manifest; } namespace development { extern const AppManifest manifest; }
namespace display { extern const AppManifest manifest; } namespace display { extern const AppManifest manifest; }
namespace files { extern const AppManifest manifest; } namespace files { extern const AppManifest manifest; }
@ -135,8 +143,11 @@ static void registerInternalApps() {
addAppManifest(app::screenshot::manifest); addAppManifest(app::screenshot::manifest);
#endif #endif
#ifdef ESP_PLATFORM #ifdef CONFIG_ESP_WIFI_ENABLED
addAppManifest(app::chat::manifest); addAppManifest(app::chat::manifest);
#endif
#ifdef ESP_PLATFORM
addAppManifest(app::crashdiagnostics::manifest); addAppManifest(app::crashdiagnostics::manifest);
addAppManifest(app::development::manifest); addAppManifest(app::development::manifest);
#endif #endif
@ -231,6 +242,9 @@ static void registerAndStartPrimaryServices() {
addService(service::wifi::manifest); addService(service::wifi::manifest);
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
addService(service::development::manifest); addService(service::development::manifest);
#endif
#ifdef CONFIG_ESP_WIFI_ENABLED
addService(service::espnow::manifest); addService(service::espnow::manifest);
#endif #endif
} }

View File

@ -1,4 +1,8 @@
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#include <sdkconfig.h>
#endif
#ifdef CONFIG_ESP_WIFI_ENABLED
#include <Tactility/app/AppManifest.h> #include <Tactility/app/AppManifest.h>
#include <Tactility/lvgl/Toolbar.h> #include <Tactility/lvgl/Toolbar.h>

View File

@ -1,20 +1,29 @@
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#include "Tactility/app/crashdiagnostics/QrUrl.h" #include <Tactility/app/crashdiagnostics/QrUrl.h>
#include <Tactility/kernel/PanicHandler.h> #include <Tactility/kernel/PanicHandler.h>
#include <sstream> #include <sstream>
#include <vector>
#if CONFIG_IDF_TARGET_ARCH_XTENSA
#include <esp_cpu_utils.h> #include <esp_cpu_utils.h>
#else
#include <esp_cpu.h>
#endif
#include <sdkconfig.h> #include <sdkconfig.h>
std::string getUrlFromCrashData() { std::string getUrlFromCrashData() {
auto crash_data = getRtcCrashData(); auto crash_data = getRtcCrashData();
auto* stack_buffer = (uint32_t*) malloc(crash_data.callstackLength * 2 * sizeof(uint32_t)); std::vector<uint32_t> stack_buffer(crash_data.callstackLength * 2);
for (int i = 0; i < crash_data.callstackLength; ++i) { for (int i = 0; i < crash_data.callstackLength; ++i) {
const CallstackFrame&frame = crash_data.callstack[i]; const CallstackFrame&frame = crash_data.callstack[i];
#if CONFIG_IDF_TARGET_ARCH_XTENSA
uint32_t pc = esp_cpu_process_stack_pc(frame.pc); uint32_t pc = esp_cpu_process_stack_pc(frame.pc);
#else
uint32_t pc = frame.pc; // No processing needed on RISC-V
#endif
#if CRASH_DATA_INCLUDES_SP #if CRASH_DATA_INCLUDES_SP
uint32_t sp = frame.sp; uint32_t sp = frame.sp;
#endif #endif
@ -41,8 +50,6 @@ std::string getUrlFromCrashData() {
#endif #endif
} }
free(stack_buffer);
return stream.str(); return stream.str();
} }

View File

@ -1,4 +1,8 @@
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#include <soc/soc_caps.h>
#endif
#if defined(ESP_PLATFORM) && defined(SOC_SDMMC_HOST_SUPPORTED)
#include <Tactility/hal/sdcard/SdmmcDevice.h> #include <Tactility/hal/sdcard/SdmmcDevice.h>
#include <Tactility/Log.h> #include <Tactility/Log.h>

View File

@ -1,4 +1,8 @@
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#include <sdkconfig.h>
#endif
#ifdef CONFIG_ESP_WIFI_ENABLED
#include "Tactility/service/espnow/EspNow.h" #include "Tactility/service/espnow/EspNow.h"
#include "Tactility/service/espnow/EspNowService.h" #include "Tactility/service/espnow/EspNowService.h"

View File

@ -1,4 +1,8 @@
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#include <sdkconfig.h>
#endif
#ifdef CONFIG_ESP_WIFI_ENABLED
#include <Tactility/Tactility.h> #include <Tactility/Tactility.h>
#include <Tactility/service/espnow/EspNowService.h> #include <Tactility/service/espnow/EspNowService.h>

View File

@ -1,4 +1,8 @@
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#include <sdkconfig.h>
#endif
#ifdef CONFIG_ESP_WIFI_ENABLED
#include "Tactility/service/espnow/EspNow.h" #include "Tactility/service/espnow/EspNow.h"
#include "Tactility/service/wifi/Wifi.h" #include "Tactility/service/wifi/Wifi.h"

View File

@ -1,4 +1,8 @@
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#include <sdkconfig.h>
#endif
#ifdef CONFIG_ESP_WIFI_ENABLED
#include <Tactility/service/wifi/Wifi.h> #include <Tactility/service/wifi/Wifi.h>

View File

@ -1,4 +1,4 @@
#ifndef ESP_PLATFORM #ifndef CONFIG_ESP_WIFI_ENABLED
#include <Tactility/service/wifi/Wifi.h> #include <Tactility/service/wifi/Wifi.h>

View File

@ -1,3 +1,5 @@
#ifndef CONFIG_IDF_TARGET_ESP32P4
#include <private/elf_symbol.h> #include <private/elf_symbol.h>
#include <cstddef> #include <cstddef>
@ -282,3 +284,5 @@ const esp_elfsym gcc_soft_float_symbols[] = {
ESP_ELFSYM_END ESP_ELFSYM_END
}; };
#endif

View File

@ -28,10 +28,12 @@
#include "symbols/esp_event.h" #include "symbols/esp_event.h"
#include "symbols/esp_http_client.h" #include "symbols/esp_http_client.h"
#include "symbols/gcc_soft_float.h"
#include "symbols/pthread.h" #include "symbols/pthread.h"
#include "symbols/stl.h" #include "symbols/stl.h"
#include "symbols/cplusplus.h" #include "symbols/cplusplus.h"
#ifndef CONFIG_IDF_TARGET_ESP32P4
#include "symbols/gcc_soft_float.h"
#endif
#include <cstring> #include <cstring>
#include <ctype.h> #include <ctype.h>
@ -591,7 +593,9 @@ uintptr_t resolve_symbol(const esp_elfsym* source, const char* symbolName) {
uintptr_t tt_symbol_resolver(const char* symbolName) { uintptr_t tt_symbol_resolver(const char* symbolName) {
static const std::vector all_symbols = { static const std::vector all_symbols = {
main_symbols, main_symbols,
#ifndef CONFIG_IDF_TARGET_ESP32P4
gcc_soft_float_symbols, gcc_soft_float_symbols,
#endif
stl_symbols, stl_symbols,
cplusplus_symbols, cplusplus_symbols,
esp_event_symbols, esp_event_symbols,

View File

@ -1,3 +1,7 @@
#ifdef ESP_PLATFORM
#include <sdkconfig.h>
#endif
#include "Tactility/CpuAffinity.h" #include "Tactility/CpuAffinity.h"
#include <Tactility/Check.h> #include <Tactility/Check.h>
@ -6,25 +10,39 @@ namespace tt {
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#ifdef CONFIG_ESP_WIFI_ENABLED
static CpuAffinity getEspWifiAffinity() { static CpuAffinity getEspWifiAffinity() {
#ifdef CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0 #if CONFIG_FREERTOS_NUMBER_OF_CORES == 1
return 0; return 0;
#elif defined(CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1) #elif defined(CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0)
return 0;
#elif defined(CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1)
return 1; return 1;
#else // Assume core 0 (risky, but safer than "None")
return 0;
#endif #endif
} }
#endif
// Warning: Must watch ESP WiFi, as this task is used by WiFi // Warning: Must watch ESP WiFi, as this task is used by WiFi
static CpuAffinity getEspMainSchedulerAffinity() { static CpuAffinity getEspMainSchedulerAffinity() {
#ifdef CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0 #if CONFIG_FREERTOS_NUMBER_OF_CORES == 1
return 0; return 0;
#elif defined(CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1) #elif defined(CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0)
return 0;
#elif defined(CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1)
return 1; return 1;
#else
return None;
#endif #endif
} }
static CpuAffinity getFreeRtosTimerAffinity() { static CpuAffinity getFreeRtosTimerAffinity() {
#if defined(CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY) #if CONFIG_FREERTOS_NUMBER_OF_CORES == 1
return 0;
#elif defined(CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY)
return None; return None;
#elif defined(CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0) #elif defined(CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0)
return 0; return 0;
@ -48,7 +66,11 @@ static const CpuAffinityConfiguration esp = {
static const CpuAffinityConfiguration esp = { static const CpuAffinityConfiguration esp = {
.system = 0, .system = 0,
.graphics = 1, .graphics = 1,
#ifdef CONFIG_ESP_WIFI_ENABLED
.wifi = getEspWifiAffinity(), .wifi = getEspWifiAffinity(),
#else
.wifi = 0,
#endif
.mainDispatcher = getEspMainSchedulerAffinity(), .mainDispatcher = getEspMainSchedulerAffinity(),
.apps = 1, .apps = 1,
.timer = getFreeRtosTimerAffinity() .timer = getFreeRtosTimerAffinity()

View File

@ -1,11 +1,13 @@
#ifdef ESP_PLATFORM #if defined(ESP_PLATFORM) && defined(CONFIG_IDF_TARGET_ARCH_XTENSA)
#include "Tactility/kernel/PanicHandler.h" #include "Tactility/kernel/PanicHandler.h"
#include <esp_debug_helpers.h> #include <esp_debug_helpers.h>
#include <esp_attr.h> #include <esp_attr.h>
#include <esp_memory_utils.h> #include <esp_memory_utils.h>
#include <esp_cpu.h>
#include <esp_cpu_utils.h> #include <esp_cpu_utils.h>
#include <xtensa/xtruntime.h>
extern "C" { extern "C" {
@ -35,10 +37,15 @@ void __wrap_esp_panic_handler(void* info) {
#endif #endif
crashData.callstackLength++; crashData.callstackLength++;
crashData.callstackCorrupted = !(esp_stack_ptr_is_sane(frame.sp) && uint32_t processed_pc = esp_cpu_process_stack_pc(frame.pc);
(esp_ptr_executable((void *)esp_cpu_process_stack_pc(frame.pc)) || bool pc_is_valid = esp_ptr_executable((void *)processed_pc);
/* Ignore the first corrupted PC in case of InstrFetchProhibited */
(frame.exc_frame && ((XtExcFrame *)frame.exc_frame)->exccause == EXCCAUSE_INSTR_PROHIBITED))); /* Ignore the first corrupted PC in case of InstrFetchProhibited on Xtensa */
if (frame.exc_frame && ((XtExcFrame *)frame.exc_frame)->exccause == EXCCAUSE_INSTR_PROHIBITED) {
pc_is_valid = true;
}
crashData.callstackCorrupted = !(esp_stack_ptr_is_sane(frame.sp) && pc_is_valid);
while ( while (
frame.next_pc != 0 && frame.next_pc != 0 &&
@ -46,6 +53,14 @@ void __wrap_esp_panic_handler(void* info) {
&& crashData.callstackLength < CRASH_DATA_CALLSTACK_LIMIT && crashData.callstackLength < CRASH_DATA_CALLSTACK_LIMIT
) { ) {
if (esp_backtrace_get_next_frame(&frame)) { if (esp_backtrace_get_next_frame(&frame)) {
// Validate the current frame
uint32_t processed_frame_pc = esp_cpu_process_stack_pc(frame.pc);
bool frame_pc_is_valid = esp_ptr_executable((void *)processed_frame_pc);
if (!esp_stack_ptr_is_sane(frame.sp) || !frame_pc_is_valid) {
crashData.callstackCorrupted = true;
break;
}
crashData.callstack[crashData.callstackLength].pc = frame.pc; crashData.callstack[crashData.callstackLength].pc = frame.pc;
#if CRASH_DATA_INCLUDES_SP #if CRASH_DATA_INCLUDES_SP
crashData.callstack[crashData.callstackLength].sp = frame.sp; crashData.callstack[crashData.callstackLength].sp = frame.sp;
@ -66,4 +81,15 @@ void __wrap_esp_panic_handler(void* info) {
const CrashData& getRtcCrashData() { return crashData; } const CrashData& getRtcCrashData() { return crashData; }
#elif defined(ESP_PLATFORM)
// Stub implementation for RISC-V and other architectures
// TODO: Implement crash data collection for RISC-V using frame pointer or EH frame
#include <Tactility/kernel/PanicHandler.h>
static CrashData emptyCrashData = {};
const CrashData& getRtcCrashData() { return emptyCrashData; }
#endif #endif

View File

@ -52,6 +52,9 @@ def read_device_properties(device_id):
exit_with_error(f"Device file not found: {device_file_path}") exit_with_error(f"Device file not found: {device_file_path}")
return read_properties_file(device_file_path) return read_properties_file(device_file_path)
def has_group(properties: ConfigParser, group: str):
return group in properties.sections()
def get_property_or_exit(properties: ConfigParser, group: str, key: str): def get_property_or_exit(properties: ConfigParser, group: str, key: str):
if group not in properties.sections(): if group not in properties.sections():
exit_with_error(f"Device properties does not contain group: {group}") exit_with_error(f"Device properties does not contain group: {group}")
@ -171,13 +174,15 @@ def write_performance_improvements(output_file, device_properties: ConfigParser)
output_file.write("CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y\n") output_file.write("CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y\n")
def write_lvgl_variables(output_file, device_properties: ConfigParser): def write_lvgl_variables(output_file, device_properties: ConfigParser):
dpi = get_property_or_exit(device_properties, "display", "dpi")
output_file.write("# LVGL\n") output_file.write("# LVGL\n")
if has_group(device_properties, "display"):
dpi = get_property_or_exit(device_properties, "display", "dpi")
output_file.write(f"CONFIG_LV_DPI_DEF={dpi}\n")
if has_group(device_properties, "lvgl"):
color_depth = get_property_or_exit(device_properties, "lvgl", "colorDepth")
output_file.write(f"CONFIG_LV_COLOR_DEPTH={color_depth}\n")
output_file.write(f"CONFIG_LV_COLOR_DEPTH_{color_depth}=y\n")
output_file.write("CONFIG_LV_DISP_DEF_REFR_PERIOD=10\n") output_file.write("CONFIG_LV_DISP_DEF_REFR_PERIOD=10\n")
output_file.write(f"CONFIG_LV_DPI_DEF={dpi}\n")
color_depth = get_property_or_exit(device_properties, "lvgl", "colorDepth")
output_file.write(f"CONFIG_LV_COLOR_DEPTH={color_depth}\n")
output_file.write(f"CONFIG_LV_COLOR_DEPTH_{color_depth}=y\n")
theme = get_property_or_none(device_properties, "lvgl", "theme") theme = get_property_or_none(device_properties, "lvgl", "theme")
if theme is None or theme == "DefaultDark": if theme is None or theme == "DefaultDark":
output_file.write("CONFIG_LV_THEME_DEFAULT_DARK=y\n") output_file.write("CONFIG_LV_THEME_DEFAULT_DARK=y\n")
@ -212,10 +217,10 @@ def write_properties(output_file, device_properties: ConfigParser, device_id: st
write_flash_variables(output_file, device_properties) write_flash_variables(output_file, device_properties)
write_partition_table(output_file, device_properties, is_dev) write_partition_table(output_file, device_properties, is_dev)
write_spiram_variables(output_file, device_properties) write_spiram_variables(output_file, device_properties)
write_lvgl_variables(output_file, device_properties)
write_performance_improvements(output_file, device_properties) write_performance_improvements(output_file, device_properties)
write_usb_variables(output_file, device_properties) write_usb_variables(output_file, device_properties)
write_custom_sdkconfig(output_file, device_properties) write_custom_sdkconfig(output_file, device_properties)
write_lvgl_variables(output_file, device_properties)
def main(device_id: str, is_dev: bool): def main(device_id: str, is_dev: bool):
device_properties_path = get_properties_file_path(device_id) device_properties_path = get_properties_file_path(device_id)