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
bool "malloc() can also allocate in SPI SRAM"
depends on !MEMMAP_SPIRAM_NO_HEAPALLOC
default "n"
help
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;
}
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.
static void disable_mem_region(void *from, void *to) {
int i;

View file

@ -86,6 +86,26 @@ size_t xPortGetFreeHeapSizeCaps( 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

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)
{
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);
if (err != 0) {
errno = err;

View file

@ -31,7 +31,6 @@
#include "esp_spi_flash.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_restore_cache(uint32_t cpuid, uint32_t saved_state);

View file

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

View file

@ -31,6 +31,7 @@
#include "esp_spi_flash.h"
#include "esp_log.h"
#include "cache_utils.h"
#include "esp_heap_alloc_caps.h"
/* bytes erased by SPIEraseBlock() ROM function */
#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()
{
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) {
s_flash_guard_ops->start();
}

View file

@ -21,12 +21,10 @@ CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y
CONFIG_LOG_BOOTLOADER_LEVEL=2
#
# Secure boot configuration
# Security features
#
CONFIG_SECURE_BOOTLOADER_DISABLED=y
# CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH is not set
# CONFIG_SECURE_BOOTLOADER_REFLASHABLE is not set
# CONFIG_SECURE_BOOTLOADER_ENABLED is not set
# CONFIG_SECURE_BOOT_ENABLED is not set
# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
#
# Serial flasher config
@ -100,14 +98,12 @@ CONFIG_AWS_IOT_MQTT_PORT=8883
CONFIG_BT_RESERVE_DRAM=0
#
# ESP32-specific config
# ESP32-specific
#
# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set
# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
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_TRACEMEM is not set
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_NONE=y
# 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_FOUR_MAC_ADDRESS_FROM_EFUSE=y
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_TASK_STACK_SIZE=2048
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_INIT_DATA_IN_PARTITION is not set
CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
CONFIG_ESP32_PHY_MAX_TX_POWER=20
# CONFIG_ETHERNET is not set
@ -172,7 +171,6 @@ CONFIG_ESP32_PHY_MAX_TX_POWER=20
# CONFIG_FREERTOS_UNICORE is not set
CONFIG_FREERTOS_CORETIMER_0=y
# CONFIG_FREERTOS_CORETIMER_1 is not set
# CONFIG_FREERTOS_CORETIMER_2 is not set
CONFIG_FREERTOS_HZ=1000
CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
@ -209,7 +207,13 @@ CONFIG_LOG_COLORS=y
CONFIG_LWIP_MAX_SOCKETS=4
CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX=0
# CONFIG_LWIP_SO_REUSE is not set
# CONFIG_LWIP_SO_RCVBUF is not set
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
@ -223,6 +227,13 @@ CONFIG_MBEDTLS_HARDWARE_SHA=y
CONFIG_MBEDTLS_HAVE_TIME=y
# 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
#