Help me out to create partition for ESP32-WROOM-32D(8MB)

Am trying to find partition table for enabling partition scheme with boards.txt and partition.csv with ARDUINO-ESP32 CORE

Am using a 8MB flash version of ESP32-WROOM-32D from digikey.
https://www.digikey.in/product-detail/en/espressif-systems/ESP32-WROOM-32D-8MB/1904-1024-6-ND/9381749
I am trying to increase the APP size to 4MB and SPIFFS to 3MB without OTA.
how to create the partition table for the 8MB FLASH Module and create addition to BOARD.txt
Please Someone guide me.
I have arrived at these lines for scheme. will it work?


# Name,Type,SubType,Offset,Size,Flags
nvs,      data,  nvs,     0x9000,    0x5000	,
phy_init, data,  phy,     0xe000,    0x2000	,
factory,  app,   factory, 0x10000,   0x3500000	,
spiffs,   data,  spiffs,  0x3510000,  0xF0000	,

I don't know anything about this partition stuff, but if you end up with any specific questions about boards.txt, I can definitely help.

Under the Arduino IDE, you cannot extend the usable ram to PSRAM, only under the ESPRESSIF IDE will that work.

Under the Arduino IDE, Himemsys does NOT work. You will only get access to 4MB of PSRAM. I will post some code on various ways to use PSRAM.

//#include "sdkconfig.h"  //
//#include "freertos/FreeRTOS.h"
//#include "freertos/task.h"
//#include "freertos/queue.h"
//#include "esp_system.h" //This inclusion configures the peripherals in the ESP system.
#include "esp32-hal-psram.h"
#include "esp_himem.h"
// #include "esp_spiram.h"
// #include "rom/cache.h"
extern "C"
{
//#include <esp_himem.h>
#include <esp_spiram.h>
}
//extern "C"
//{
//#include <esp_himem.h>
//}

////
const int SerialDataBits = 115200;
////
struct stuTime
{
  int iSeconds = 0;
  int iMinutes = 0;
  int iHours = 0;
};
////
void setup()
{

//  Serial.begin(115200);
//
//  Serial.println("========================================");
//  Serial.printf("PSRAM total size     : %u \n", esp_spiram_get_size());
//  Serial.println("----------------------------------------");
//  Serial.printf("PSRAM first 4MB size : %u \n", ESP.getPsramSize());
//  Serial.printf("PSRAM first 4MB free : %u \n", ESP.getMaxAllocPsram());
//  Serial.printf("PSRAM HI-MEM    size : %u \n", esp_himem_get_phys_size());
//  Serial.printf("PSRAM HI-MEM    free : %u \n", esp_himem_get_free_size());
//  Serial.println("========================================");
//  Serial.printf("Internal RAM  size   : %u \n", ESP.getHeapSize()); 
//  Serial.printf("Internal RAM  free   : %u \n", ESP.getFreeHeap()); 
//  Serial.println("========================================");
//
//  Serial.println("Testing the free memory of PSRAM HI-MEM ...");
//  test_region(esp_himem_get_free_size(), 0xaaaa);
//  Serial.println("Done!");

  ////////////////////////////////////////////////////////////////////////////////
  esp_spiram_init();
  vTaskDelay(1);
//  esp_himem_handle_t mh; //Handle for the address space we're using
//    esp_himem_rangehandle_t rh; //Handle for the actual RAM.
//    esp_himem_alloc( 1024, &mh);
  // Serial.begin( SerialDataBits );
  // psramInit();
  // vTaskDelay(3);
  // esp_spiram_init();
  // vTaskDelay(1);
  //   log_i("Total heap: %u", ESP.getHeapSize());
  //   log_i("Free heap: %u", ESP.getFreeHeap());
  // log_i("Total PSRAM: %u", ESP.getPsramSize());
  // log_i("Free PSRAM: %d", ESP.getFreePsram());
  // log_i("spiram size %u", esp_spiram_get_size());
//  log_i("himem free %u", esp_himem_get_free_size());
//  log_i("himem phys %u", esp_himem_get_phys_size());
//  log_i("himem reserved %u", esp_himem_reserved_area_size());
  //
  //   int *ptr, *ptr1;
  //   int n, n1, i, sum = 0;
  //   float *ptrFloat;
  //   // Get the number of elements for the array
  //   n = 10;
  //   n1 = 20;
  //   log_i("Number of elements ptr: %d", n);
  //   log_i("Number of elements ptr1: %d", n1);
  //   log_i("Number of elements ptr1: %d\n", n1);
  //   // Dynamically allocate memory using malloc()
  //   // ptr = (int*)ps_malloc(n * sizeof(int)); //works
  //   ptr = (int*)ps_calloc( n, sizeof(int) ); // works
  //   log_i("Free PSRAM: %d", ESP.getFreePsram());
  //   ptr1 = (int*)ps_calloc( n1, sizeof(int) ); // works
  //   log_i("Free PSRAM: %d", ESP.getFreePsram());
  //    // Check if the memory has been successfully
  //    // allocated in ps_ram
  //    ptrFloat = (float*)ps_calloc( n, sizeof(float) ); // works
  //    if (ptr == NULL) {
  //      log_i(" ptr memory not allocated.\n");
  //      exit(0);
  //    }
  //    if (ptr1 == NULL)
  //    {
  //      log_i("ptr1 memory not allocated.\n");
  //      exit(0);
  //    }
  //    else
  //    {
  //       // Memory has been successfully allocated
  //      // log_i("ps_ram memory successfully allocated using ps_calloc.");
  //      // put elements into ps_ram array
  //      for (i = 0; i < n; ++i)
  //      {
  //        ptr[i] = i + 1;
  //      }
  //      for (i = 0; i < n1; ++i)
  //      {

I used the above sketch to learn how to use PSRAM.

DO NOT USE malloc() to map PSRAM or Himemory. malloc() is not multi threading or multiprocessor aware. ESPRESSIF has wrote a set of wrappers to make malloc() aware of its environment; such as ps_malloc().

See ESP32 API: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/index.html, I would be wise to read about using the PSRAM area in the API docs.

Do not allow 2 threads to access a single PSRAM location at the same time, use the OS freeRTOS, built into the ESP32, and semaphores to protect the PSRAM locations from multiple access.

code part 2

//        ptr1[i] = i + 2;
 //      }
  //      for (i = 0; i < n; ++i)
  //      {
  //        ptrFloat[i] = (float)i + 1.06555f;
  //      }
  //      // Print the elements of the array
  //      log_i("The elements of the ptr array are: ");
  //      for (i = 0; i < n; ++i) {
  //        log_i("%d, ", ptr[i]);
  //      }
  //      log_i("The elements of the ptr1 array are: ");
  //      for (i = 0; i < n1; ++i) {
  //        log_i("%d, ", ptr1[i]);
  //      }
  //      log_i("The elements of the ptrFloat array are: ");
  //      for (i = 0; i < n1; ++i) {
  //        log_i("%f, ", ptrFloat[i]);
  //      }
  //    }
  //    //
  //    // put a structure into psram. Works.
  //    struct stuTime *ptrStuTime;
  //    log_i("size of structure: %d", sizeof(struct stuTime) );
  //     //
  //    ptrStuTime = (struct stuTime *)ps_malloc(sizeof(struct stuTime));
  //    log_i("Free PSRAM after structure: %d", ESP.getFreePsram());
  //    ptrStuTime->iSeconds = 10;
  //    ptrStuTime->iMinutes = 60;
  //    ptrStuTime->iHours = 100;
  //    log_i("Seconds: %d Minutes: %d Hours: %d", ptrStuTime->iSeconds, ptrStuTime->iMinutes, ptrStuTime->iHours );
  //    free(ptr);
  // free(ptr1);
  //    free(ptrStuTime);
  //    // works
  //    log_i("Free PSRAM before String: %d", ESP.getFreePsram());
  //    char *str;
  //    char OneChar = 'a';
  //    char TwoChar = 'b';
  //    char ThreeChar = 'c';
  //    str = (char *)ps_calloc(300, sizeof(char) );
  //    log_i("Free PSRAM after String: %d", ESP.getFreePsram());
  //    // concantenate one char variable to end of char array to the str
  //    strncat( str, &OneChar, 1 ); //works
  //    strncat( str, &TwoChar, 1 );
  //    strncat( str, &ThreeChar, 1 );
  //    //
  //    //*(str+0) = 'G';  // works
  //    //*(str+1) = 'f';
  //    //*(str+2) = 'G';
  //    //*(str+3) = '\0';
  //    log_i("%s", str );
  //    free(str);

  ///////
  //size_t memfree=esp_himem_get_free_size();
  //log_i( "himemFree %d", memfree );
  //  int memcnt=esp_himem_get_phys_size();
  // int memfree=esp_himem_get_free_size();
  //  log_i( "SpiRamPhysSize %d", memcnt );
  //  log_i( "SpiRamFree %d", memfree );
  // esp_himem_get_phys_size(void)
  // esp_himem_handle_t mh; //Handle for the address space we're using
  // esp_himem_rangehandle_t rh; //Handle for the actual RAM.
  // esp_err_t intError = esp_himem_alloc( 4095, &mh);
  // log_i( "%s", esp_err_to_name( intError) );
  // log_i("spiram size %u", esp_spiram_get_size());
  // log_i( "Handle %d", mh );


} // setup()
////
/* possible adds to the config
   #define CONFIG_ESP32_SPIRAM_SUPPORT 1
  #define CONFIG_SPIRAM_BOOT_INIT 1
  #define CONFIG_SPIRAM_IGNORE_NOTFOUND 0
  #define CONFIG_SPIRAM_USE_MALLOC 1
  #define CONFIG_SPIRAM_TYPE_AUTO 1
  #define CONFIG_SPIRAM_SIZE -1
  #define CONFIG_SPIRAM_SPEED_40M 1
  #define CONFIG_SPIRAM_MEMTEST 1
  #define CONFIG_SPIRAM_CACHE_WORKAROUND 1
  #define CONFIG_SPIRAM_BANKSWITCH_ENABLE 1
  #define CONFIG_SPIRAM_BANKSWITCH_RESERVE 4
*/
void loop() {}
////
static void fill_mem_seed(int seed, void *mem, int len)
{
    uint32_t *p = (uint32_t *)mem;
    unsigned int rseed = seed ^ 0xa5a5a5a5;
    for (int i = 0; i < len / 4; i++) {
        *p++ = rand_r(&rseed);
    }
}

//Check the memory filled by fill_mem_seed. Returns true if the data matches the data
//that fill_mem_seed wrote (when given the same seed).
//Returns true if there's a match, false when the region differs from what should be there.
static bool check_mem_seed(int seed, void *mem, int len, int phys_addr)
{
    uint32_t *p = (uint32_t *)mem;
    unsigned int rseed = seed ^ 0xa5a5a5a5;
    for (int i = 0; i < len / 4; i++) {
        uint32_t ex = rand_r(&rseed);
        if (ex != *p) {
            printf("check_mem_seed: %x has 0x%08x expected 0x%08x\n", phys_addr+((char*)p-(char*)mem), *p, ex);
            return false;
        }
        p++;
    }
    return true;
}

//Allocate a himem region, fill it with data, check it and release it.
static bool test_region(int check_size, int seed)
{
    esp_himem_handle_t mh; //Handle for the address space we're using
    esp_himem_rangehandle_t rh; //Handle for the actual RAM.
    bool ret = true;

    //Allocate the memory we're going to check.
    ESP_ERROR_CHECK(esp_himem_alloc(check_size, &mh));
    //Allocate a block of address range
    ESP_ERROR_CHECK(esp_himem_alloc_map_range(ESP_HIMEM_BLKSZ, &rh));
    for (int i = 0; i < check_size; i += ESP_HIMEM_BLKSZ) {
        uint32_t *ptr = NULL;
        //Map in block, write pseudo-random data, unmap block.
        ESP_ERROR_CHECK(esp_himem_map(mh, rh, i, 0, ESP_HIMEM_BLKSZ, 0, (void**)&ptr));
        fill_mem_seed(i ^ seed, ptr, ESP_HIMEM_BLKSZ); //
        ESP_ERROR_CHECK(esp_himem_unmap(rh, ptr, ESP_HIMEM_BLKSZ));
    }
    vTaskDelay(5); //give the OS some time to do things so the task watchdog doesn't bark
    for (int i = 0; i < check_size; i += ESP_HIMEM_BLKSZ) {
        uint32_t *ptr;
        //Map in block, check against earlier written pseudo-random data, unmap block.
        ESP_ERROR_CHECK(esp_himem_map(mh, rh, i, 0, ESP_HIMEM_BLKSZ, 0, (void**)&ptr));
        if (!check_mem_seed(i ^ seed, ptr, ESP_HIMEM_BLKSZ, i)) {
            printf("Error in block %d\n", i / ESP_HIMEM_BLKSZ);
            ret = false;
        }
        ESP_ERROR_CHECK(esp_himem_unmap(rh, ptr, ESP_HIMEM_BLKSZ));
        if (!ret) break; //don't check rest of blocks if error occurred
    }
    //Okay, all done!
    ESP_ERROR_CHECK(esp_himem_free(mh));
    ESP_ERROR_CHECK(esp_himem_free_map_range(rh));
    return ret;
}