mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-10 12:53:29 +00:00
spi_flash: Remove 16KB free internal heap limit for esp_flash_read() into PSRAM
Allocation of the temporary internal buffer will now repeat until a small enough buffer can be allocated, and only fail if less than a 256 byte block of internal RAM is free. Adds unit test for the same, and generic test utility for creating memory pressure.
This commit is contained in:

committed by
Angus Gratton

parent
af4c6ac0f3
commit
c38c3ff3f0
@@ -497,11 +497,25 @@ esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t add
|
||||
bool direct_read = chip->host->supports_direct_read(chip->host, buffer);
|
||||
uint8_t* temp_buffer = NULL;
|
||||
|
||||
//each time, we at most read this length
|
||||
//after that, we release the lock to allow some other operations
|
||||
size_t read_chunk_size = MIN(MAX_READ_CHUNK, length);
|
||||
|
||||
if (!direct_read) {
|
||||
uint32_t length_to_allocate = MIN(MAX_READ_CHUNK, length);
|
||||
length_to_allocate = (length_to_allocate+3)&(~3);
|
||||
temp_buffer = heap_caps_malloc(length_to_allocate, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
ESP_LOGV(TAG, "allocate temp buffer: %p (%d)", temp_buffer, length_to_allocate);
|
||||
/* Allocate temporary internal buffer to use for the actual read. If the preferred size
|
||||
doesn't fit in free internal memory, allocate the largest available free block.
|
||||
|
||||
(May need to shrink read_chunk_size and retry due to race conditions with other tasks
|
||||
also allocating from the heap.)
|
||||
*/
|
||||
unsigned retries = 5;
|
||||
while(temp_buffer == NULL && retries--) {
|
||||
read_chunk_size = MIN(read_chunk_size, heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT));
|
||||
read_chunk_size = (read_chunk_size + 3) & ~3;
|
||||
temp_buffer = heap_caps_malloc(read_chunk_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
}
|
||||
ESP_LOGV(TAG, "allocate temp buffer: %p (%d)", temp_buffer, read_chunk_size);
|
||||
|
||||
if (temp_buffer == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
@@ -516,9 +530,9 @@ esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t add
|
||||
}
|
||||
//if required (dma buffer allocated), read to the buffer instead of the original buffer
|
||||
uint8_t* buffer_to_read = (temp_buffer)? temp_buffer : buffer;
|
||||
//each time, we at most read this length
|
||||
//after that, we release the lock to allow some other operations
|
||||
uint32_t length_to_read = MIN(MAX_READ_CHUNK, length);
|
||||
|
||||
// Length we will read this iteration is either the chunk size or the remaining length, whichever is smaller
|
||||
size_t length_to_read = MIN(read_chunk_size, length);
|
||||
|
||||
if (err == ESP_OK) {
|
||||
err = chip->chip_drv->read(chip, buffer_to_read, address, length_to_read);
|
||||
|
Reference in New Issue
Block a user