| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- /*
- * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /*
- This code tests the interaction between PSRAM and SPI flash routines.
- */
- #include <esp_types.h>
- #include <stdio.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/semphr.h"
- #include "freertos/queue.h"
- #include "unity.h"
- #include <stdint.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "esp_heap_caps.h"
- #include "spi_flash_mmap.h"
- #include "esp_partition.h"
- #include "test_utils.h"
- #include "soc/soc.h"
- #if CONFIG_SPIRAM
- #if CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC
- #define USE_CAPS_ALLOC 1
- #endif // CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC
- #define TSTSZ (16*1024)
- #if !CONFIG_FREERTOS_UNICORE
- volatile static int res[2], err[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);
- }
- 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]);
- err[xPortGetCoreID()]++;
- }
- }
- p++;
- res[xPortGetCoreID()]++;
- }
- }
- TEST_CASE("Spiram cache flush on mmap", "[spiram]")
- {
- void *mem[2];
- res[0]=0; res[1]=0;
- #if USE_CAPS_ALLOC
- printf("Allocating SPI RAM chunk...\n");
- mem[0]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM);
- mem[1]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM);
- #else
- mem[0]=(void*)SOC_EXTRAM_DATA_LOW;
- mem[1]=(void*)SOC_EXTRAM_DATA_LOW+TSTSZ;
- #endif
- assert(mem[0]);
- assert(mem[1]);
- TaskHandle_t th[2];
- err[0]=0; err[1]=0;
- printf("Creating tasks\n");
- xTaskCreatePinnedToCore(tstMem , "tskone" , 2048, mem[0], 3, &th[0], 0);
- xTaskCreatePinnedToCore(tstMem , "tsktwo" , 2048, mem[1], 3, &th[1], 1);
- for (int l=0; l<10; l++) {
- for (int p=0; p<4096*1024; p+=65536) {
- const void *out;
- spi_flash_mmap_handle_t h;
- spi_flash_mmap(p, 65536, SPI_FLASH_MMAP_DATA, &out, &h);
- spi_flash_munmap(h);
- }
- }
- printf("Checked memory %d and %d times. Errors: %d and %d\n", res[0], res[1], err[0], err[1]);
- vTaskDelete(th[0]);
- vTaskDelete(th[1]);
- #if USE_CAPS_ALLOC
- free(mem[0]);
- free(mem[1]);
- #endif
- TEST_ASSERT(err[0]==0);
- TEST_ASSERT(err[1]==0);
- }
- #define CYCLES 1024
- TEST_CASE("Spiram cache flush on write/read", "[spiram]")
- {
- void *mem[2];
- res[0]=0; res[1]=0;
- #if USE_CAPS_ALLOC
- printf("Allocating SPI RAM chunk...\n");
- mem[0]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM);
- mem[1]=heap_caps_malloc(TSTSZ, MALLOC_CAP_SPIRAM);
- #else
- mem[0]=(void*)SOC_EXTRAM_DATA_LOW;
- mem[1]=(void*)SOC_EXTRAM_DATA_LOW+TSTSZ;
- #endif
- assert(mem[0]);
- assert(mem[1]);
- TaskHandle_t th[2];
- const esp_partition_t* part = get_test_data_partition();
- assert(part!=NULL);
- printf("Erasing sector...\n");
- esp_partition_erase_range(part, 0, 64*1024);
- printf("Erased.\n");
- 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];
- const void *out;
- spi_flash_mmap_handle_t handle;
- esp_partition_mmap(part, 0, 512, SPI_FLASH_MMAP_DATA, &out, &handle);
- for (int i=0; i<CYCLES; i++) {
- esp_partition_write(part, 0, buf, 512);
- esp_partition_read(part, 0, buf, 512);
- vTaskDelay(1);
- }
- spi_flash_munmap(handle);
- printf("Checked memory %d and %d times.\n", res[0], res[1]);
- vTaskDelete(th[0]);
- vTaskDelete(th[1]);
- #if USE_CAPS_ALLOC
- free(mem[0]);
- free(mem[1]);
- #endif
- }
- #endif // !CONFIG_FREERTOS_UNICORE
- IRAM_ATTR TEST_CASE("Spiram memcmp weirdness at 80MHz", "[spiram]") {
- char *mem1=malloc(0x10000);
- #if USE_CAPS_ALLOC
- char *mem2=heap_caps_malloc(0x10000, MALLOC_CAP_SPIRAM);
- #else
- char *mem2=(void*)SOC_EXTRAM_DATA_LOW;
- #endif
- #if !CONFIG_SPIRAM_SPEED_80M
- printf("**** WARNING **** Spi memory isn't running at 80MHz, so this test is somewhat meaningless.\n");
- #endif
- printf("RAM: Got %p and %p\n", mem1, mem2);
- assert(mem1);
- assert(mem2);
- for (int i=0; i<0x10000; i++) mem1[i]=i^0xAAAAAAAA;
- for (int cycle=1; cycle<100; cycle++) {
- memcpy(mem2, mem1, 0x10000);
- if (memcmp(mem1, mem2, 0x10000)!=0) {
- printf("Memcmp failed! Cycle %d\n", cycle);
- for (int i=0; i<0x10000; i++) {
- if (mem1[i]!=mem2[i]) {
- printf("Found real difference at index %d: 0x%x vs 0x%x\n", i, mem1[i], mem2[i]);
- break;
- }
- }
- }
- }
- free(mem1);
- #if USE_CAPS_ALLOC
- free(mem2);
- #endif
- }
- #endif // CONFIG_SPIRAM
|