P1 external flash API's stopped working all of a sudden. What am I doing wrong?

Hello,
The following piece of code was working fine until now. I am unable to read/write anything into external flash.

#include "flashee-eeprom.h"
using namespace Flashee;
FATFS fs;
FRESULT result;

const char * fileName = "firmware.txt";
const char * message = "Hello!";

void setup()
{
    //create memory region
    while(!Serial.available()){
      Particle.process();
    }
    result = Devices::createFATRegion(0, 4096*256, &fs);

    if(result != FR_OK){
        Serial.println("Error mounting file system");
        return;
    }else{
        Serial.println("File system success");
    }

    //FILE ATTRIBUTES
    FIL fil;
    FRESULT fr;
    UINT dw;

    /*Delete the file if it exits already*/
    fr = f_unlink(fileName);

    ((fr = f_open(&fil, fileName, FA_WRITE|FA_CREATE_NEW)) == FR_OK) &&
    ((fr = f_write(&fil, (const char *)message, strlen(message)+1, &dw)) == FR_OK) &&
    ((fr = f_close(&fil))==FR_OK);

    Serial.println("Created a file");
    Serial.printf("write: %d\n" , dw);

    char buf[128];
    memset(buf, 0, sizeof(buf));
    ((fr = f_open(&fil, fileName, FA_READ|FA_OPEN_EXISTING)) == FR_OK) &&
    ((fr = f_read(&fil, buf, sizeof(buf), &dw)) == FR_OK) &&
    ((fr = f_close(&fil)) == FR_OK);
    Serial.printf("Read: %d\n" , dw);

    Serial.printf("File contents: %s\n", buf);
}

void loop()
{}

Output:
File system success
Created a file
write: 0
Read: 0
File contents:

I am unable to read or write. Is my external flash damaged?

Thanks
Dheeraj

Hmm… @peekay123 you have some idea?

I am not familiar but does dw get a value after the f_write()?

Also, the statement fr = f_open == FR_OK… Wouldn’t that return the evaluation result, changing what fr is referenced to?

@dheerajdake

((fr = f_open(&fil, fileName, FA_WRITE|FA_CREATE_NEW)) == FR_OK) &&
    ((fr = f_write(&fil, (const char *)message, strlen(message)+1, &dw)) == FR_OK) &&
    ((fr = f_close(&fil))==FR_OK);

I agree with @kennethlimcp that this will most likely not work. I am not even sure what the purpose of the statement is as any returned error will be wiped unless it is the last statement. I would be more granular in order to handle errors more effectively:

fr = f_open(&fil, fileName, FA_WRITE|FA_CREATE_NEW);
if (fr != FR_OK) {
  Serial.printf("ERROR opening file! (error %d)", fr);
  while(1) Particle.process();  // Stop the application by looping forever!
}

fr  = f_write(&fil, (const char *)message, strlen(message)+1, &dw));
if (fr != FR_OK)  {
  Serial.printf("ERROR writing to file! (error %d)", fr);
  while(1) Particle.process();  // Stop the application by looping forever!
}

fr = f_close(&fil);
if (fr != FR_OK)  {
  Serial.printf("ERROR closing file! (error %d)", fr);
  while(1) Particle.process();  // Stop the application by looping forever!
}

In the above example, the application will stop and call `Particle.process()` to ensure OTA can continue to work.  You may want to handle the errors differently.  Exception (error) handling is crucial in any application.
1 Like

Yes, dw returns the number of bytes written to the file. I have seen that. This line

((fr = f_open(&fil, fileName, FA_WRITE|FA_CREATE_NEW)) == FR_OK);

Assigns a value to fr and if it is equal to FR_OK, the condition is true.

@peekay123

This syntax is from the example in here. The condition checks are guaranteed after every statement. Not just the last line.

I have verified the conditions checks already by reformatting the syntax as

((fr = f_open(&fil, fileName, FA_WRITE|FA_CREATE_NEW)) == FR_OK);
((fr = f_write(&fil, (const char *)message, strlen(message)+1, &dw)) == FR_OK);
((fr = f_close(&fil))==FR_OK);

All of them said fr == FR_OK. I am very sure that this worked before.

Thanks
Dheeraj

@dheerajdake, I have no doubt they work. It’s just that the code isn’t written for good exception handling. Have you tried replacing your string declarations for const char * to:

const char fileName[] = "firmware.txt";
const char message[] = "Hello!";

The array name is also the pointer to the array.

Yes I did. Still the same output.

Pinging @rickkas7

Unfortunately, I don’t have answer why it stopped working. I ran this code, on a P1 and it worked fine:

#include "Particle.h"


#include "flashee-eeprom.h"
using namespace Flashee;

// Uses:
// https://github.com/m-mcgowan/spark-flashee-eeprom
//
// Add to project.properties:
// dependencies.flashee-eeprom=0.1.8


FATFS fs;

const char * fileName = "firmware.txt";
const char * message = "Hello!";

void testFs();

void setup() {
	Serial.begin(9600);

	delay(5000);
	testFs();
}

void loop() {
}

void testFs() {
	//create memory region
	FRESULT result = Devices::createFATRegion(0, 4096*256, &fs);

	if(result != FR_OK){
		Serial.println("Error mounting file system");
		return;
	}else{
		Serial.println("File system success");
	}

	//FILE ATTRIBUTES
	FIL fil;
	FRESULT fr;
	UINT dw;

	/*Delete the file if it exits already*/
	fr = f_unlink(fileName);

	fr = f_open(&fil, fileName, FA_WRITE|FA_CREATE_NEW);
	if (fr != FR_OK) {
		Serial.printf("ERROR opening file! (error %d)", fr);
		return;
	}

	fr  = f_write(&fil, (const char *)message, strlen(message)+1, &dw);
	if (fr != FR_OK)  {
		Serial.printf("ERROR writing to file! (error %d)", fr);
		return;
	}

	fr = f_close(&fil);
	if (fr != FR_OK)  {
		Serial.printf("ERROR closing file! (error %d)", fr);
		return;
	}

	Serial.println("Created a file");
	Serial.printf("write: %d\n" , dw);

	char buf[128];
	memset(buf, 0, sizeof(buf));
	((fr = f_open(&fil, fileName, FA_READ|FA_OPEN_EXISTING)) == FR_OK) &&
			((fr = f_read(&fil, buf, sizeof(buf), &dw)) == FR_OK) &&
			((fr = f_close(&fil)) == FR_OK);
	Serial.printf("Read: %d\n" , dw);

	Serial.printf("File contents: %s\n", buf);
}

This was the serial output:

File system success
Created a file
write: 7
Read: 7
File contents: Hello!

Tested on a P1 (Sparkfun Redboard) with 0.6.2.

1 Like

That’s the same code. How do I know if my external flash is damaged?

I’d try adding the 4th parameter to the Devices::createFATRegion call, FORMAT_CMD_FORMAT. The default is to format the device as a FAT volume if it looks invalid, but maybe your flash is almost but not quite valid. Perhaps formatting it will help.

1 Like