Merge branch 'bugfix/ram_loadable_elf_flash_mmap_issue' into 'master'

Fix flash mmap data integrity issue for RAM loadable ELF case

See merge request espressif/esp-idf!22802
This commit is contained in:
Mahavir Jain 2023-03-23 12:13:35 +08:00
commit 86b6f87d68
5 changed files with 41 additions and 1 deletions

View File

@ -372,11 +372,19 @@ void IRAM_ATTR call_start_cpu0(void)
}
#if CONFIG_ESP_ROM_NEEDS_SET_CACHE_MMU_SIZE
#if CONFIG_APP_BUILD_TYPE_ELF_RAM
// For RAM loadable ELF case, we don't need to reserve IROM/DROM as instructions and data
// are all in internal RAM. If the RAM loadable ELF has any requirement to memory map the
// external flash then it should use flash or partition mmap APIs.
uint32_t cache_mmu_irom_size = 0;
__attribute__((unused)) uint32_t cache_mmu_drom_size = 0;
#else // CONFIG_APP_BUILD_TYPE_ELF_RAM
uint32_t _instruction_size = (uint32_t)&_instruction_reserved_end - (uint32_t)&_instruction_reserved_start;
uint32_t cache_mmu_irom_size = ((_instruction_size + SPI_FLASH_MMU_PAGE_SIZE - 1) / SPI_FLASH_MMU_PAGE_SIZE) * sizeof(uint32_t);
uint32_t _rodata_size = (uint32_t)&_rodata_reserved_end - (uint32_t)&_rodata_reserved_start;
__attribute__((unused)) uint32_t cache_mmu_drom_size = ((_rodata_size + SPI_FLASH_MMU_PAGE_SIZE - 1) / SPI_FLASH_MMU_PAGE_SIZE) * sizeof(uint32_t);
#endif // !CONFIG_APP_BUILD_TYPE_ELF_RAM
/* Configure the Cache MMU size for instruction and rodata in flash. */
Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);

View File

@ -74,6 +74,7 @@ menu "SPI Flash driver"
choice SPI_FLASH_DANGEROUS_WRITE
bool "Writing to dangerous flash regions"
default SPI_FLASH_DANGEROUS_WRITE_ALLOWED if APP_BUILD_TYPE_RAM
default SPI_FLASH_DANGEROUS_WRITE_ABORTS
help
SPI flash APIs can optionally abort or return a failure code

View File

@ -19,6 +19,7 @@ Feature Supported by ESP-IDF but not in Chip-ROM
- :ref:`CONFIG_SPI_FLASH_VERIFY_WRITE`, enabling this option helps you detect bad writing.
- :ref:`CONFIG_SPI_FLASH_LOG_FAILED_WRITE`, enabling this option will print the bad writing.
- :ref:`CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE`, enabling this option will check if you're writing zero to one.
- :ref:`CONFIG_SPI_FLASH_DANGEROUS_WRITE`, enabling this option will check for flash programming to certain protected regions like bootloader, partition table or application itself.
:esp32h2 or esp32c6: - Flash MMAP driver isn't ready in Chip-ROM.

View File

@ -5,6 +5,7 @@
*/
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
@ -12,6 +13,10 @@
#include "esp_chip_info.h"
#include "hal/mmu_hal.h"
#include "soc/soc.h"
#include "unity.h"
#include "spi_flash_mmap.h"
#include "esp_flash.h"
#include "esp_err.h"
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
@ -35,6 +40,30 @@ static void s_test_ext_vaddr(void)
assert(my_var || my_var == 0);
}
}
static void s_test_flash_mmap_data_integrity(void)
{
char src_p_1[32] = "Test data pattern 123456789";
char src_p_2[32] = "Test data pattern 987654321";
char buf[32];
const int addr = 0x10000;
spi_flash_mmap_handle_t handle1;
const void *ptr1;
TEST_ESP_OK(spi_flash_mmap(addr, SPI_FLASH_SEC_SIZE, SPI_FLASH_MMAP_DATA, &ptr1, &handle1));
TEST_ESP_OK(esp_flash_erase_region(NULL, addr, SPI_FLASH_SEC_SIZE));
TEST_ESP_OK(esp_flash_write(NULL, src_p_1, addr, sizeof(src_p_1)));
memcpy(buf, ptr1, sizeof(buf));
TEST_ASSERT_EQUAL(0, memcmp(buf, src_p_1, sizeof(buf)));
TEST_ESP_OK(esp_flash_erase_region(NULL, addr, SPI_FLASH_SEC_SIZE));
TEST_ESP_OK(esp_flash_write(NULL, src_p_2, addr, sizeof(src_p_2)));
memcpy(buf, ptr1, sizeof(buf));
TEST_ASSERT_EQUAL(0, memcmp(buf, src_p_2, sizeof(buf)));
spi_flash_munmap(handle1);
}
#endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
void app_main(void)
@ -56,6 +85,7 @@ void app_main(void)
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
s_test_ext_vaddr();
s_test_flash_mmap_data_integrity();
#endif
uint32_t uptime = 0;

View File

@ -27,4 +27,4 @@ def test_pure_ram_loadable_app(dut: IdfDut) -> None:
@pytest.mark.parametrize('config', ['defaults',], indirect=True,)
def test_ram_loadable_app(dut: IdfDut) -> None:
dut.expect('spi_flash: detected chip', timeout=10)
dut.expect('Time since boot: 3 seconds...', timeout=10)
dut.expect('Time since boot: 3 seconds...', timeout=30)