Section type conflict and other memory error

seems to freeze for large values of N (or arrayLen).
P#48 noted that hadn't been tried AFAIK as is being desired here. Should have noted the idea to test that would be to:
> pick a working "size" amount for the read that works
-> Do a loop reading that "size" from file to PSRAM
-> incrementing as appropriate to get the whole file into PSRAM
-- Then increase that "size" and repeat for fewer larger reads until it fails as indicated with a single full file read.
-- perhaps time the reading loops for 'fun' just to see if it helps as the reads grow larger.

If this can find a problem spot/"size" it might show an issue to resolve given a sketch that others can run.
 
That's what I did in message number 45, but it seems to freeze for large values of N (or arrayLen).
Please read message 45 as it seems you answer to message 42...
I suspect the interface uses 'int' (32,767 maximum bytes) or 'unsigned int (65,535 maximum bytes) for the length. If so, you will need to do a loop to transmit say 4,096 floats (16,384 bytes, which is the last power of 2 under 32,767) at a time, and transmit the remainder after the loop.
 
I suspect the interface uses 'int' (32,767 maximum bytes) or 'unsigned int (65,535 maximum bytes) for the length. If so, you will need to do a loop to transmit say 4,096 floats (16,384 bytes, which is the last power of 2 under 32,767) at a time, and transmit the remainder after the loop.
Teensy 4 is a 32-bit platform, maximum size of a signed int is 2^31-1 and maximum size of an unsigned int is 2^32-1.
 
Ideally the SIZE should be 2^32 and not matter ... p#51 should look to confirm that.
The PSRAM testing involved crossing boundaries (with various data sizes etc) - and all tested fine - so not likely an issue there ...

Unless there is a missed overt bug in the sketch code ... it suggests there is something going wrong in the underlying code - or perhaps the 'lower level hardware' transfer execution. IIRC there is a caveat in the PSRAM doc/spec that 88 MHz is fine 'except when ... 66 MHz max'.
 
Thanks for your answers, but we don't know if it's a bug or just a problem related to PSRAM or Flash chips.
I understand that it's not easy to reproduce, because it requires a Teensy with additional PSRAM and Flash. So could anyone try to reproduce the problem?
 
could anyone try to reproduce the problem?
p #51 gave an idea to close in on the error. For anyone to understand what is showing there - a simple "copy to IDE sketch" is needed that shows the problem - having PSRAM and Flash is then easy for a few folks to try.
 
Hi, sorry for my late reply.
Here is a code that read the file parts by parts.

C++:
/*
  Test LittleFS write, read
 */
#include <LittleFS.h>
LittleFS_QPINAND myfs;  // QSPI NAND Flash attached to SPI


#include "onnx__Conv_110.h"
const int total = 921600;
const int N = 100000;
EXTMEM float data[N];
float last = 0;
elapsedMicros chrono;


void setup() {


  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    // wait for serial port to connect.
  }


  // set clock speed for PSRAM to 132 MHz
  CCM_CBCMR &= ~(CCM_CBCMR_FLEXSPI2_PODF_MASK | CCM_CBCMR_FLEXSPI2_CLK_SEL_MASK);
  CCM_CBCMR |= (CCM_CBCMR_FLEXSPI2_PODF(3) | CCM_CBCMR_FLEXSPI2_CLK_SEL(3));


  Serial.print("Initializing SPI FLASH...");


  // see if the Flash is present and can be initialized:
  if (!myfs.begin()) {
    Serial.printf("Error starting %s\n", "SPI FLASH");
    while (1)
      ;
  }
  Serial.printf("NAND Flash Memory Size =  %d bytes / ", myfs.totalSize());
  Serial.printf("%d Mbyte / ", myfs.totalSize() / 1048576);
  Serial.printf("%d Gbit\n", myfs.totalSize() * 8 / 1000000000);
  Serial.println("Flash initialized.");


  // Uncomment only the first time
  // Serial.println("Formatting SPI FLASH...");
  // myfs.lowLevelFormat('.');


  Serial.println("Searching file...");
  File dir = myfs.open("/");
  bool found = false;
  while (true) {
    File entry = dir.openNextFile();
    if (!entry) break;
    if (strcmp(entry.name(), "onnx__Conv_110.h") == 0) {
      found = true;
      Serial.printf("File exists! Size: %d\n", entry.size());
      break;
    }
    entry.close();
  }
  if (!found) {
    Serial.println("Creating file...");
    chrono = 0;
    File dataFile = myfs.open("onnx__Conv_110.h", FILE_WRITE);
    if (dataFile) {
      dataFile.write(onnx__Conv_110_output_0, 4 * total);
      Serial.printf("Execution time: %.3f ms\n", (float)chrono / 1000.0);
    } else Serial.println("error opening onnx__Conv_110.h");
    Serial.printf("Size: %d (%d)\n", dataFile.size(), total * 4);
    dataFile.close();
    delay(200);
  }
  last = onnx__Conv_110_output_0[N - 1];


  Serial.println("Now reading data...");
  chrono = 0;
  File file2 = myfs.open("onnx__Conv_110.h", FILE_READ);
  if (file2) {
    // file2.readBytes((char*)data, N * 4);
    int chunks = 128;
    for (int i = 0; i < N / chunks; i++) {
      char databytes[4 * chunks];
      file2.readBytes(databytes, 4 * chunks);
      memcpy(&data[i * chunks], &databytes, 4 * chunks);
    }
    int offset = N / chunks * chunks;
    for (int i = 0; i < N % chunks; i++) {
      uint8_t databytes[4 * chunks];
      file2.readBytes(databytes, 4 * chunks);
      memcpy(&data[offset + i * chunks], &databytes, 4 * chunks);
    }
    Serial.printf("Execution time: %.3f ms\n", (float)chrono / 1000.0);
  } else Serial.println("error opening file");
  file2.close();
  // for (int i = 0; i < N; i++)
  //   Serial.printf("i = %d data = %f\n", i, data[i]);
  Serial.printf("Checking data number %d...\nData written: %f\n", N, last);
  Serial.printf("Data read   : %f\n", data[N - 1]);
}


void loop() {
  // nope
}

I can't attach the .h file because it's too big. It is available here
Please tell me if it is not online anymore.

Thanks for your help
 
And here is a code with the loop over the number of bytes read in the file. It should crash inside the loop...

C++:
/*
  Test LittleFS write, read
 */
#include <LittleFS.h>
LittleFS_QPINAND myfs;  // QSPI NAND Flash attached to SPI

#include "onnx__Conv_110.h"
const int total = 921600;
const int N = 100000;
EXTMEM float data[N];
float last = 0;
elapsedMicros chrono;


void readthefile (int chunks, float last) {       
  chrono = 0;
  File file2 = myfs.open("onnx__Conv_110.h", FILE_READ);
  if (file2) {
    // file2.readBytes((char*)data, N * 4);
    for (int i = 0; i < N / chunks; i++) {
      char databytes[4 * chunks];
      file2.readBytes(databytes, 4 * chunks);
      memcpy(&data[i * chunks], &databytes, 4 * chunks);
    }
    int offset = N / chunks * chunks;
    for (int i = 0; i < N % chunks; i++) {
      uint8_t databytes[4 * chunks];
      file2.readBytes(databytes, 4 * chunks);
      memcpy(&data[offset + i * chunks], &databytes, 4 * chunks);
    }
    Serial.printf("Execution time: %.3f ms\n", (float)chrono / 1000.0);
  } else Serial.println("error opening file");
  file2.close();
  // for (int i = 0; i < N; i++)
  //   Serial.printf("i = %d data = %f\n", i, data[i]);
  Serial.printf("Checking data number %d...\nData written: %f\n", N, last);
  Serial.printf("Data read   : %f\n", data[N - 1]);
}


void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    // wait for serial port to connect.
  }

  // set clock speed for PSRAM to 132 MHz
  CCM_CBCMR &= ~(CCM_CBCMR_FLEXSPI2_PODF_MASK | CCM_CBCMR_FLEXSPI2_CLK_SEL_MASK);
  CCM_CBCMR |= (CCM_CBCMR_FLEXSPI2_PODF(3) | CCM_CBCMR_FLEXSPI2_CLK_SEL(3));

  Serial.print("Initializing SPI FLASH...");
  // see if the Flash is present and can be initialized:
  if (!myfs.begin()) {
    Serial.printf("Error starting %s\n", "SPI FLASH");
    while (1)
      ;
  }
  Serial.printf("NAND Flash Memory Size =  %d bytes / ", myfs.totalSize());
  Serial.printf("%d Mbyte / ", myfs.totalSize() / 1048576);
  Serial.printf("%d Gbit\n", myfs.totalSize() * 8 / 1000000000);
  Serial.println("Flash initialized.");

  // Uncomment only the first time
  // Serial.println("Formatting SPI FLASH...");
  // myfs.lowLevelFormat('.');

  Serial.println("Searching file...");
  File dir = myfs.open("/");
  bool found = false;
  while (true) {
    File entry = dir.openNextFile();
    if (!entry) break;
    if (strcmp(entry.name(), "onnx__Conv_110.h") == 0) {
      found = true;
      Serial.printf("File exists! Size: %d\n", entry.size());
      break;
    }
    entry.close();
  }
  if (!found) {
    Serial.println("Creating file...");
    chrono = 0;
    File dataFile = myfs.open("onnx__Conv_110.h", FILE_WRITE);
    if (dataFile) {
      dataFile.write(onnx__Conv_110_output_0, 4 * total);
      Serial.printf("Execution time: %.3f ms\n", (float)chrono / 1000.0);
    } else Serial.println("error opening onnx__Conv_110.h");
    Serial.printf("Size: %d (%d)\n", dataFile.size(), total * 4);
    dataFile.close();
    delay(200);
  }
  last = onnx__Conv_110_output_0[N - 1];

  Serial.println("Now reading data...");
  int chunks = 64
  for (int i = 0; i < 30; ++i) {
    chunks *= 2;
    Serial.printf("chunks = %d\n", chunks);
    readthefile(chunks, last);
    }
}

void loop() {
  // nope
}
 
Sorry, there was a mistake in the function. Here is the correct one :

C++:
void readthefile(int chunks, float last) {
  chrono = 0;
  File file2 = myfs.open("onnx__Conv_110.h", FILE_READ);
  if (file2) {
    // file2.readBytes((char*)data, N * 4);
    for (int i = 0; i < N / chunks; i++) {
      char databytes[4 * chunks];
      file2.readBytes(databytes, 4 * chunks);
      memcpy(&data[i * chunks], &databytes, 4 * chunks);
    }
    int offset = N / chunks * chunks;
    Serial.printf("Offset= %d\n", offset);
    uint8_t databytes[4 * (N % chunks)];
    file2.readBytes(databytes, 4 * (N % chunks));
    memcpy(&data[offset], &databytes, 4 * (N % chunks));
    Serial.printf("Execution time: %.3f ms\n", (float)chrono / 1000.0);
  } else Serial.println("error opening file");
  file2.close();
  // for (int i = 0; i < N; i++)
  //   Serial.printf("i = %d data = %f\n", i, data[i]);
  Serial.printf("Checking data number %d...\nData written: %f\n", N, last);
  Serial.printf("Data read   : %f\n", data[N - 1]);
}
 
I narrowed the search and changed the loop :

C++:
int chunks = 32760;
  for (int i = 0; i < 30; ++i) {
    chunks += 1;
    Serial.printf("chunks = %d\n", chunks);
    readthefile(chunks, last);
  }

This shows that the problem happens with blocks of 32768 floats (2**15):

chunks = 32766
Offset= 917448
Execution time: 229.453 ms
Checking data number 921600...
Data written: -0.004808
Data read : -0.004808
chunks = 32767
Offset= 917476
Execution time: 229.415 ms
Checking data number 921600...
Data written: -0.004808
Data read : -0.004808
chunks = 32768
 
Last edited:
Back
Top