8000 Allow use of CONFIG_SPIRAM_USE_CAPS_ALLOC · n3o59hf/circuitpython@5e26862 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5e26862

Browse files
committed
Allow use of CONFIG_SPIRAM_USE_CAPS_ALLOC
.. and switch makerfabs tft7 over to it as a test. We have our existing way of "reserving" PSRAM for esp-idf (we actually control it all but add back the "reserved" part). However, this does not work with off the shelf esp_lcd, which only will allocate a framebuffer in PSRAM if CONFIG_SPIRAM_USE_CAPS_ALLOC (or CONFIG_SPIRAM_USE_ALLOC) is defined, not if CONFIG_SPIRAM_USE_MEMMAP is. This new way is possibly compatible with more esp-idf code, but it complicates CircuitPython's initial startup since nothing until port_heap_init is permitted to use the CP heap or supervisor allocator. In practice this seems to be OK today. Right now this doesn't change the setting across all boards with PSRAM and so it does not revert esp-idf to its prior state. Instead, what I'm thinking is that we can do it during or just after the IDF5 update when sdkconfig files will be getting an overhaul anyway.
1 parent b7d1147 commit 5e26862

File tree

5 files changed

+64
-27
lines changed

5 files changed

+64
-27
lines changed

main.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,10 @@ int __attribute__((used)) main(void) {
10421042
set_safe_mode(SAFE_MODE_NO_CIRCUITPY);
10431043
}
10441044

1045+
// We maybe can't initialize the heap until here, because on espressif port we need to be able to check for reserved psram in settings.toml
1046+
// (but it's OK if this is a no-op due to the heap beinig initialized in port_init())
1047+
set_safe_mode(port_heap_init(get_safe_mode()));
1048+
10451049
#if CIRCUITPY_ALARM
10461050
// Record which alarm woke us up, if any.
10471051
// common_hal_alarm_record_wake_alarm() should return a static, non-heap object
@@ -1171,6 +1175,13 @@ void gc_collect(void) {
11711175
MP_WEAK void port_gc_collect() {
11721176
}
11731177

1178+
// A port may initialize the heap in port_init but if it cannot (for instance
1179+
// in espressif it must be done after CIRCUITPY is mounted) then it must provde
1180+
// an implementation of this function.
1181+
MP_WEAK safe_mode_t port_heap_init(safe_mode_t safe_mode_in) {
1182+
return safe_mode_in;
1183+
}
1184+
11741185
void NORETURN nlr_jump_fail(void *val) {
11751186
reset_into_safe_mode(SAFE_MODE_NLR_JUMP_FAIL);
11761187
while (true) {

ports/espressif/boards/makerfabs_tft7/sdkconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ CONFIG_SPIRAM_SPEED_80M=y
2121
CONFIG_SPIRAM=y
2222
CONFIG_SPIRAM_BOOT_INIT=y
2323
# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set
24-
CONFIG_SPIRAM_USE_MEMMAP=y
25-
# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set
24+
#CONFIG_SPIRAM_USE_MEMMAP=y
25+
CONFIG_SPIRAM_USE_CAPS_ALLOC=y
2626
# CONFIG_SPIRAM_USE_MALLOC is not set
2727
CONFIG_SPIRAM_MEMTEST=y
2828
#

ports/espressif/common-hal/espidf/__init__.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ bool common_hal_espidf_set_reserved_psram(size_t amount) {
7979
supervisor_allocation *psram_for_idf;
8080

8181
void common_hal_espidf_reserve_psram(void) {
82-
#ifdef CONFIG_SPIRAM
82+
#ifdef CONFIG_SPIRAM_USE_MEMMAP
8383
if (!psram_for_idf) {
8484
ESP_LOGI(TAG, "Reserving %d bytes of psram", reserved_psram);
8585
if (reserved_psram == 0) {

ports/espressif/supervisor/port.c

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -299,22 +299,62 @@ safe_mode_t port_init(void) {
299299
#endif
300300
#endif
301301

302-
#ifdef CONFIG_SPIRAM
302+
_never_reset_spi_ram_flash();
303+
304+
esp_reset_reason_t reason = esp_reset_reason();
305+
switch (reason) {
306+
case ESP_RST_BROWNOUT:
307+
return SAFE_MODE_BROWNOUT;
308+
case ESP_RST_PANIC:
309+
return SAFE_MODE_HARD_FAULT;
310+
case ESP_RST_INT_WDT:
311+
// The interrupt watchdog is used internally to make sure that latency sensitive
312+
// interrupt code isn't blocked. User watchdog resets come through ESP_RST_WDT.
313+
return SAFE_MODE_WATCHDOG;
314+
case ESP_RST_WDT:
315+
default:
316+
break;
317+
}
318+
319+
return SAFE_MODE_NONE;
320+
}
321+
322+
safe_mode_t port_heap_init(safe_mode_t sm) {
323+
mp_int_t reserved = 0;
324+
if (filesystem_present() && common_hal_os_getenv_int("CIRCUITPY_RESERVED_PSRAM", &reserved) == GETENV_OK) {
325+
common_hal_espidf_set_reserved_psram(reserved);
326+
}
327+
328+
#ifdef CONFIG_SPIRAM_USE_MEMMAP
303329
{
304330
intptr_t heap_start = common_hal_espidf_get_psram_start();
305331
intptr_t heap_end = common_hal_espidf_get_psram_end();
306332
size_t spiram_size = heap_end - heap_start;
307333
if (spiram_size > 0) {
308334
heap = (uint32_t 6D47 *)heap_start;
309335
heap_size = (heap_end - heap_start) / sizeof(uint32_t);
336+
common_hal_espidf_reserve_psram();
310337
} else {
311-
ESP_LOGE(TAG, "CONFIG_SPIRAM enabled but no spiram heap available");
338+
ESP_LOGE(TAG, "CONFIG_SPIRAM_USE_MMAP enabled but no spiram heap available");
339+
}
340+
}
341+
#elif CONFIG_SPIRAM_USE_CAPS_ALLOC
342+
{
343+
intptr_t psram_start = common_hal_espidf_get_psram_start();
344+
intptr_t psram_end = common_hal_espidf_get_psram_end();
345+
size_t psram_amount = psram_end - psram_start;
346+
size_t biggest_block = heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM);
347+
size_t try_alloc = MIN(biggest_block, psram_amount - common_hal_espidf_get_reserved_psram());
348+
heap = heap_caps_malloc(try_alloc, MALLOC_CAP_SPIRAM);
349+
350+
if (heap) {
351+
heap_size = try_alloc;
352+
} else {
353+
ESP_LOGE(TAG, "CONFIG_SPIRAM_USE_CAPS_ALLOC but no spiram heap available");
312354
}
313355
}
314356
#endif
315357

316-
_never_reset_spi_ram_flash();
317-
318358
if (heap == NULL) {
319359
size_t heap_total = heap_caps_get_total_size(MALLOC_CAP_8BIT);
320360
heap_size = MIN(heap_caps_get_largest_free_block(MALLOC_CAP_8BIT), heap_total / 2);
@@ -326,22 +366,8 @@ safe_mode_t port_init(void) {
326366
return SAFE_MODE_NO_HEAP;
327367
}
328368

329-
esp_reset_reason_t reason = esp_reset_reason();
330-
switch (reason) {
331-
case ESP_RST_BROWNOUT:
332-
return SAFE_MODE_BROWNOUT;
333-
case ESP_RST_PANIC:
334-
return SAFE_MODE_HARD_FAULT;
335-
case ESP_RST_INT_WDT:
336-
// The interrupt watchdog is used internally to make sure that latency sensitive
337-
// interrupt code isn't blocked. User watchdog resets come through ESP_RST_WDT.
338-
return SAFE_MODE_WATCHDOG;
339-
case ESP_RST_WDT:
340-
default:
341-
break;
342-
}
369+
return sm;
343370

344-
return SAFE_MODE_NONE;
345371
}
346372

347373
void reset_port(void) {
@@ -533,11 +559,6 @@ void port_idle_until_interrupt(void) {
533559

534560
void port_post_boot_py(bool heap_valid) {
535561
if (!heap_valid && filesystem_present()) {
536-
mp_int_t reserved;
537-
if (common_hal_os_getenv_int("CIRCUITPY_RESERVED_PSRAM", &reserved) == GETENV_OK) {
538-
common_hal_espidf_set_reserved_psram(reserved);
539-
}
540-
common_hal_espidf_reserve_psram();
541562
}
542563
}
543564

supervisor/port.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ extern uint32_t _ebss;
4343

4444
safe_mode_t port_init(void);
4545

46+
// If the port does not initialize the heap during port_init(), it must provide
47+
// this function which is called after CIRCUITPY is mounted.
48+
// If not required, a default (weak) implementation that does nothing is used.
49+
safe_mode_t port_heap_init(safe_mode_t);
50+
4651
// Reset the microcontroller completely.
4752
void reset_cpu(void) NORETURN;
4853

0 commit comments

Comments
 (0)
0