espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.68k stars 7.42k forks source link

psram in wrover kit #1644

Closed manecolooper closed 5 years ago

manecolooper commented 6 years ago

HI, now that psram is supported, i'm trying to use it, i want to store a large amount of 8 b its a/d convertions, as internal mamory crashed above 90 k ... i'm using this command:

" byte sDelayBuffer0 = ( byte ) ps_malloc( 480000 ); "

i requested the amount of ram available and it shows above 4 megas with the command

Serial.println(ESP.getFreeHeap());

but it crashes

any ideas?

stickbreaker commented 6 years ago

@manecolooper shouldn't the code be:

byte *sDelayBuffer0 = (byte*)ps_malloc(480000);

your code defines a byte then tries to stuff four bytes into it?

Chuck.

manecolooper commented 6 years ago

Thanks Chuck, that's exactly my code, don´t know why the asteriscs did not show...

stickbreaker commented 6 years ago

@manecolooper describe your crash in more detail. You do realize that the PSDRAM is external to the ESP32? All data to and from it must move over the SPI bus? So, there are interrupt and timing considerations.

And there are limitation how data pointers can be passed through functions. There are limitations on accessing these PSDRAM buffers during interrupts.

How are you actually using the buffer? And how it is crashing?

Chuck.

manecolooper commented 6 years ago

thanks again! let me see i read and convert to 8 bits from ad converter x = analogRead( InPin ); x = x/2 ;

byte loByte = lowByte(x);

in_ADC0=loByte;

then when a timer interrupt arrives ( at around 40khz )

i write the value to the ram buffer

sDelayBuffer0[DelayCounter] = in_ADC0 ;

delay counter is a pointer that gets incremented at each write operation

the reset i get is this, continuosly

4485964 (here the free memory) Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. Core 1 register dump: PC : 0x40081323 PS : 0x00060031 A0 : 0x80081c14 A1 : 0x3ffc0bc0
A2 : 0x00000001 A3 : 0x00000000 A4 : 0x00000001 A5 : 0x00000001
A6 : 0x3ffc24a0 A7 : 0x00000064 A8 : 0x00000000 A9 : 0x00000001
A10 : 0x00000001 A11 : 0x3ff5f000 A12 : 0xe00a1400 A13 : 0x3ff5f000
A14 : 0xe00a1000 A15 : 0x0044734c SAR : 0x00000004 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000001 LBEG : 0x400d0e8c LEND : 0x400d0e98 LCOUNT : 0x00000000
Core 1 was running in ISR context: EPC1 : 0x40081323 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x40082af7

Backtrace: 0x40081323:0x3ffc0bc0 0x40081c11:0x3ffc0be0 0x400820fd:0x3ffc0c00 0x400e6f5a:0x00000000

Rebooting... ets Jun 8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x3e (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0018,len:4 load:0x3fff001c,len:952 load:0x40078000,len:6084 load:0x40080000,len:7936 entry 0x40080310

lbernstone commented 6 years ago

Does this code work if you don't use PSRAM? Are you running an ADC read in an ISR? That is very likely to take too long for the watchdog even if it doesn't have to write the results out over SPI.

stickbreaker commented 6 years ago

@manecolooper you were writing to the buffer inside of a interrupt context:

4485964 (here the free memory) Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. Core 1 was running in ISR context:

Don't try to access/write to the PSDRAM buffer during an interrupt context. update a RAM buffer in the ISR, in foreground code move from RAM to PSDRAM

#define RAMBUFSIZE 512
#define PSDRAMBUFSIZE 480000
#define RAMBUFCOUNT 2
volatile static byte ramBuffer[RAMBUFCOUNT][RAMBUFSIZE];
volatile bool flush[RAMBUFCOUNT] ={false,false};
volatile uint16_t pos[RAMBUFCOUNT]={0,0};
volatile uint16_t currentRAM=0;
byte* psdRamBuffer = (byte*)ps_malloc(PSDRAMBUFSIZE);
uint32_t psdPos=0;

void ISR(){
if((currentRAM<RAMBUFCOUNT)&&(pos[currentRAM]<RAMBUFSIZE)) {
  ramBuffer[currentRAM][pos[currentRAM]++] = sample;
  if(pos[currentRAM] ==RAMBUFSIZE){ // nxt buf, mark dirty
    flush[currentRAM] = true;
    pos[currentRAM] = 0; // ready for nexttime
    currentRAM++;
    if(currentRAM == RAMBUFCOUNT) {
      currentRAM = 0;
    }
    if( flush[currentRAM]) {
      log_e("buffer overrun %d",currentRAM);
      abort();
      }
  }
}

void loop(){
for(uint8_t a = 0; a<RAMBUFCOUNT; a++){
   if( flush[a]){ // move to PSDRAM
     memmove((uint8_t*)&psdRamBuffer[psdPos],(uint8_t*)&ramBuffer[a][0],RAMBUFSIZE);
     flush[a] = false;
     psdPos += RAMBUFSIZE;
     }
  }
}

(untested / uncompiled code, use at your own risk) :grinning:

Chuck

manecolooper commented 6 years ago

Wow, thanks Chuck! lots of work to do... my sketch Works as long as i use internal ram and no more tan 90000 bytes...i'll try to adapt this to my code thanks again!

sticilface commented 6 years ago

I'm very new to the PSRAM (about 20 mins). I've managed to use it and allocate 1,000,000 bytes using ps_malloc, so that is all good. however...

running ESP.getFreeHeap() gives 4485540 and there is mention in the IDF that you can

Initialize RAM, add it to the capability allocator and add memory to the pool of RAM that can be returned by malloc(). This allows any application to use the external RAM without having to rewrite the code to use heap_caps_malloc.

as the psram is returned with freeheap is arduino ESP32 default configured to work like that... why then does plain char * data = (char*)malloc( sizeof(char) * 1000000); and char * data = new char[1000000]; fail? malloc does nothing, using new causes...

abort() was called at PC 0x400e46e3 on core 1

Backtrace: 0x4008a42c:0x3ffb1ea0 0x4008a62f:0x3ffb1ec0 0x400e46e3:0x3ffb1ee0 0x400e472a:0x3ffb1f00 0x400e47d7:0x3ffb1f20 0x400e4856:0x3ffb1f40 0x400e3f49:0x3ffb1f60 0x400d0b0b:0x3ffb1f80 0x400e4cd3:0x3ffb1fa0

I would like to be educated?

Thanks

me-no-dev commented 6 years ago

then why not just ask in gitter? come there and I'll answer :P this is an issue tracker after all

tobozo commented 5 years ago

Turns out googling 'esp32 ps_malloc' or 'esp32 psram' yields this page, and while I'm also recommending gitter, seeing the only indexed discussion end that way gives to this issue a taste of Stackoverflow :D

image

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 5 years ago

This stale issue has been automatically closed. Thank you for your contributions.