Fix up tests for stack not in psram on flash, add small testcase

This commit is contained in:
Jeroen Domburg 2017-03-08 20:42:57 +08:00
parent 05237496c2
commit 9f86a00fc3
9 changed files with 184 additions and 16 deletions

View file

@ -141,6 +141,7 @@ config MEMMAP_SPIRAM_TEST
config MEMMAP_SPIRAM_ENABLE_MALLOC config MEMMAP_SPIRAM_ENABLE_MALLOC
bool "malloc() can also allocate in SPI SRAM" bool "malloc() can also allocate in SPI SRAM"
depends on !MEMMAP_SPIRAM_NO_HEAPALLOC
default "n" default "n"
help help
If enabled, malloc() will return pointers to both internal as well as external If enabled, malloc() will return pointers to both internal as well as external

View file

@ -149,6 +149,30 @@ void heap_alloc_enable_nonos_stack_tag()
nonos_stack_in_use=false; nonos_stack_in_use=false;
} }
bool esp32_ptr_has_memory_caps(void *ptr, int caps) {
int tag=-1;
//Look up region tag of pointer
for (int i=0; regions[i].xSizeInBytes!=0; i++) {
if (regions[i].xTag != -1 &&
(uint8_t*)ptr >= regions[i].pucStartAddress &&
(uint8_t*)ptr < regions[i].pucStartAddress+regions[i].xSizeInBytes) {
tag=regions[i].xTag;
break;
}
}
if (tag==-1) return false;
//Mask off all the caps the tag does have. What should remain is the caps the tag does not have.
for (int i=0; i<NO_PRIOS; i++) caps&=~(tag_desc[tag].prio[i]);
//If any remain, ptr does not have all given caps.
return (caps==0);
}
bool esp32_task_stack_is_internal() {
int i;
return esp32_ptr_has_memory_caps(&i, MALLOC_CAP_INTERNAL);
}
//Modify regions array to disable the given range of memory. //Modify regions array to disable the given range of memory.
static void disable_mem_region(void *from, void *to) { static void disable_mem_region(void *from, void *to) {
int i; int i;

View file

@ -86,6 +86,26 @@ size_t xPortGetFreeHeapSizeCaps( uint32_t caps );
*/ */
size_t xPortGetMinimumEverFreeHeapSizeCaps( uint32_t caps ); size_t xPortGetMinimumEverFreeHeapSizeCaps( uint32_t caps );
/**
* @brief Checks if a memory address resides in a memory region satisfying the given capabilities
*
* Given a pointer, this routine will look up the region it resides in. If the region
* has _all_ the capabilities given in caps, it will return true. If this is not the case,
* or the pointer address is unknown , false is returned.
*
* @param ptr Pointer to be investigated
* @param caps Bitwise OR of MALLOC_CAP_* flags
*
* @return True if pointer region has all the given capabilities
*/
bool esp32_ptr_has_memory_caps(void *ptr, int caps);
/**
* @brief Convenience function to check if stack of currently-running task resides in internal memory
*
* @returns true if stack is in internal memory
*/
bool esp32_task_stack_is_internal();
#endif #endif

View file

@ -0,0 +1,110 @@
/*
This code triggers a psram-related silicon bug in rev0 silicon. The bug is fixed in rev1 silicon.
*/
#include <esp_types.h>
#include <stdio.h>
#include "rom/ets_sys.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "unity.h"
#include "soc/dport_reg.h"
#include "soc/io_mux_reg.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "rom/ets_sys.h"
#include "esp_heap_alloc_caps.h"
#include "esp_spi_flash.h"
#define TSTSZ (16*1024)
volatile static int res[2];
void tstMem(void *arg) {
volatile unsigned char *mem=(volatile unsigned char*)arg;
int p=0;
while(1) {
for (int i=0; i<TSTSZ; i++) {
mem[i]=(i^p);
}
// vTaskDelay(1);
for (int i=0; i<TSTSZ; i++) {
if (mem[i]!=((i^p)&0xff)) {
printf("Core %d mem err! Got %x espected %x at addr %p\n", xPortGetCoreID(), mem[i], (i^p)&0xff, &mem[i]);
}
}
p++;
res[xPortGetCoreID()]++;
}
}
TEST_CASE("PSram cache flush on mmap", "[psram][ignore]")
{
void *mem[2];
res[0]=0; res[1]=0;
mem[0]=pvPortMallocCaps(TSTSZ, MALLOC_CAP_SPIRAM);
mem[1]=pvPortMallocCaps(TSTSZ, MALLOC_CAP_SPIRAM);
TaskHandle_t th[2];
printf("Creating tasks\n");
xTaskCreatePinnedToCore(tstMem , "tskone" , 2048, mem[0], 3, &th[0], 0);
xTaskCreatePinnedToCore(tstMem , "tsktwo" , 2048, mem[1], 3, &th[1], 1);
char buf[512];
for (int i=0; i<4*1024*1024; i+=512) {
spi_flash_read(i, buf, 512);
vTaskDelay(1);
}
printf("Checked memory %d and %d times.\n", res[0], res[1]);
vTaskDelete(th[0]);
vTaskDelete(th[1]);
free(mem[0]);
free(mem[1]);
}
#define FLASHPOS (2*1024*1024-512)
#define CYCLES 1024
TEST_CASE("PSram cache flush on write/read", "[psram][ignore]")
{
void *mem[2];
res[0]=0; res[1]=0;
mem[0]=pvPortMallocCaps(TSTSZ, MALLOC_CAP_SPIRAM);
mem[1]=pvPortMallocCaps(TSTSZ, MALLOC_CAP_SPIRAM);
TaskHandle_t th[2];
printf("Creating tasks\n");
xTaskCreatePinnedToCore(tstMem , "tskone" , 2048, mem[0], 3, &th[0], 0);
xTaskCreatePinnedToCore(tstMem , "tsktwo" , 2048, mem[1], 3, &th[1], 1);
char buf[512];
printf("Erasing sector...\n");
spi_flash_erase_sector(FLASHPOS/4096);
printf("Erased.\n");
for (int i=0; i<CYCLES; i++) {
printf("%d/%d\n", i, CYCLES);
spi_flash_write(FLASHPOS, buf, 512);
spi_flash_read(i, buf, 512);
vTaskDelay(1);
//if ((i%31)==0)
}
printf("Checked memory %d and %d times.\n", res[0], res[1]);
vTaskDelete(th[0]);
vTaskDelete(th[1]);
free(mem[0]);
free(mem[1]);
}

View file

@ -510,7 +510,7 @@ static int vfs_fat_closedir(void* ctx, DIR* pdir)
static struct dirent* vfs_fat_readdir(void* ctx, DIR* pdir) static struct dirent* vfs_fat_readdir(void* ctx, DIR* pdir)
{ {
vfs_fat_dir_t* fat_dir = (vfs_fat_dir_t*) pdir; vfs_fat_dir_t* fat_dir = (vfs_fat_dir_t*) pdir;
struct dirent* out_dirent; struct dirent* out_dirent=NULL;
int err = vfs_fat_readdir_r(ctx, pdir, &fat_dir->cur_dirent, &out_dirent); int err = vfs_fat_readdir_r(ctx, pdir, &fat_dir->cur_dirent, &out_dirent);
if (err != 0) { if (err != 0) {
errno = err; errno = err;

View file

@ -31,7 +31,6 @@
#include "esp_spi_flash.h" #include "esp_spi_flash.h"
#include "esp_log.h" #include "esp_log.h"
static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_state); static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_state);
static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state); static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state);

View file

@ -32,6 +32,7 @@
#include "esp_log.h" #include "esp_log.h"
#include "cache_utils.h" #include "cache_utils.h"
#include "esp_psram.h" #include "esp_psram.h"
#include "esp_heap_alloc_caps.h"
#ifndef NDEBUG #ifndef NDEBUG
// Enable built-in checks in queue.h in debug builds // Enable built-in checks in queue.h in debug builds

View file

@ -31,6 +31,7 @@
#include "esp_spi_flash.h" #include "esp_spi_flash.h"
#include "esp_log.h" #include "esp_log.h"
#include "cache_utils.h" #include "cache_utils.h"
#include "esp_heap_alloc_caps.h"
/* bytes erased by SPIEraseBlock() ROM function */ /* bytes erased by SPIEraseBlock() ROM function */
#define BLOCK_ERASE_SIZE 65536 #define BLOCK_ERASE_SIZE 65536
@ -102,6 +103,7 @@ size_t IRAM_ATTR spi_flash_get_chip_size()
static inline void IRAM_ATTR spi_flash_guard_start() static inline void IRAM_ATTR spi_flash_guard_start()
{ {
assert(esp32_task_stack_is_internal() && "SPI operation called from task which has its stack in external memory");
if (s_flash_guard_ops && s_flash_guard_ops->start) { if (s_flash_guard_ops && s_flash_guard_ops->start) {
s_flash_guard_ops->start(); s_flash_guard_ops->start();
} }

View file

@ -21,12 +21,10 @@ CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y
CONFIG_LOG_BOOTLOADER_LEVEL=2 CONFIG_LOG_BOOTLOADER_LEVEL=2
# #
# Secure boot configuration # Security features
# #
CONFIG_SECURE_BOOTLOADER_DISABLED=y # CONFIG_SECURE_BOOT_ENABLED is not set
# CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH is not set # CONFIG_FLASH_ENCRYPTION_ENABLED is not set
# CONFIG_SECURE_BOOTLOADER_REFLASHABLE is not set
# CONFIG_SECURE_BOOTLOADER_ENABLED is not set
# #
# Serial flasher config # Serial flasher config
@ -100,14 +98,12 @@ CONFIG_AWS_IOT_MQTT_PORT=8883
CONFIG_BT_RESERVE_DRAM=0 CONFIG_BT_RESERVE_DRAM=0
# #
# ESP32-specific config # ESP32-specific
# #
# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set
# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240
# CONFIG_ESP32_ENABLE_STACK_WIFI is not set
# CONFIG_ESP32_ENABLE_STACK_BT is not set
CONFIG_MEMMAP_SMP=y CONFIG_MEMMAP_SMP=y
# CONFIG_MEMMAP_TRACEMEM is not set # CONFIG_MEMMAP_TRACEMEM is not set
CONFIG_TRACEMEM_RESERVE_DRAM=0x0 CONFIG_TRACEMEM_RESERVE_DRAM=0x0
@ -115,14 +111,16 @@ CONFIG_TRACEMEM_RESERVE_DRAM=0x0
# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set
CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y
# CONFIG_ESP32_ENABLE_COREDUMP is not set # CONFIG_ESP32_ENABLE_COREDUMP is not set
CONFIG_MEMMAP_SPIRAM_ENABLE=y
CONFIG_MEMMAP_SPIRAM_TYPE_ESPPSRAM32=y
CONFIG_MEMMAP_SPIRAM_SIZE=4194304
# CONFIG_MEMMAP_SPIRAM_NO_HEAPALLOC is not set
CONFIG_MEMMAP_SPIRAM_TEST=y
CONFIG_MEMMAP_SPIRAM_ENABLE_MALLOC=y
CONFIG_MEMMAP_SPIRAM_ALLOC_LIMIT_INTERNAL=40960
# CONFIG_TWO_MAC_ADDRESS_FROM_EFUSE is not set # CONFIG_TWO_MAC_ADDRESS_FROM_EFUSE is not set
CONFIG_FOUR_MAC_ADDRESS_FROM_EFUSE=y CONFIG_FOUR_MAC_ADDRESS_FROM_EFUSE=y
CONFIG_NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE=4 CONFIG_NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE=4
CONFIG_MEMMAP_SPIRAM_ENABLE=y
CONFIG_MEMMAP_SPIRAM_TYPE_ESPPSRAM32=y
CONFIG_MEMMAP_SPIRAM_TEST=y
CONFIG_MEMMAP_SPIRAM_ENABLE_MALLOC=y
CONFIG_MEMMAP_SPIRAM_ALLOC_LIMIT_INTERNAL=1024
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2048 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2048
CONFIG_MAIN_TASK_STACK_SIZE=4096 CONFIG_MAIN_TASK_STACK_SIZE=4096
@ -163,6 +161,7 @@ CONFIG_PHY_ENABLED=y
# #
CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y
# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set
CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
CONFIG_ESP32_PHY_MAX_TX_POWER=20 CONFIG_ESP32_PHY_MAX_TX_POWER=20
# CONFIG_ETHERNET is not set # CONFIG_ETHERNET is not set
@ -172,7 +171,6 @@ CONFIG_ESP32_PHY_MAX_TX_POWER=20
# CONFIG_FREERTOS_UNICORE is not set # CONFIG_FREERTOS_UNICORE is not set
CONFIG_FREERTOS_CORETIMER_0=y CONFIG_FREERTOS_CORETIMER_0=y
# CONFIG_FREERTOS_CORETIMER_1 is not set # CONFIG_FREERTOS_CORETIMER_1 is not set
# CONFIG_FREERTOS_CORETIMER_2 is not set
CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_HZ=1000
CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
@ -209,7 +207,13 @@ CONFIG_LOG_COLORS=y
CONFIG_LWIP_MAX_SOCKETS=4 CONFIG_LWIP_MAX_SOCKETS=4
CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX=0 CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX=0
# CONFIG_LWIP_SO_REUSE is not set # CONFIG_LWIP_SO_REUSE is not set
# CONFIG_LWIP_SO_RCVBUF is not set
CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1
# CONFIG_LWIP_IP_FRAG is not set
# CONFIG_LWIP_IP_REASSEMBLY is not set
CONFIG_TCP_MAXRTX=12
CONFIG_TCP_SYNMAXRTX=6
CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
# #
# mbedTLS # mbedTLS
@ -223,6 +227,13 @@ CONFIG_MBEDTLS_HARDWARE_SHA=y
CONFIG_MBEDTLS_HAVE_TIME=y CONFIG_MBEDTLS_HAVE_TIME=y
# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
#
# OpenSSL
#
# CONFIG_OPENSSL_DEBUG is not set
CONFIG_OPENSSL_ASSERT_DO_NOTHING=y
# CONFIG_OPENSSL_ASSERT_EXIT is not set
# #
# SPI Flash driver # SPI Flash driver
# #