Community
cancel
Showing results for 
Search instead for 
Did you mean: 
KKaes
Beginner
1,609 Views

How can I write on the SD card of the galileo board when booted from SD card?

Jump to solution

Hello,

With the following sketch (from the examples) I am able to write a file on the SD card, if it is not bootable.

As soon as I put an image on it and boot the galileo gen2 board from it, I get an error during initalisation.

if (!SD.begin(4)) {

Serial.println("initialization failed!");

return;

}

Serial.println("initialization done.");

if(!SD.exists("test.txt")){

Serial.println("test.txt does not exist, creating.");

system("touch /media/mmcblk0p1/test.txt");

}

// open the file. note that only one file can be open at a time,

// so you have to close this one before opening another.

myFile = SD.open("Text.txt", FILE_WRITE);

// if the file opened okay, write to it:

if (myFile) {

Serial.print("Writing to Text.txt...");

myFile.println("testing 1, 2, 3.");

// close the file:

myFile.close();

Serial.println("done.");

} else {

// if the file didn't open, print an error:

Serial.println("error opening Text.txt");

}

}

What do I have to change that the sketch will work when booted from SD card?

1 Solution
FTinetti
Honored Contributor I
136 Views

Hi,

Provided you are booting from an SD card I'd suggest to completely avoid using the SD library. More specifically,

SD.begin(4);

will fail because the SD card is not connected to the SPI interface in Galileo. The SD card hardware is not an Arduino SD shield. Even more specifically, the SD.begin() argument (4 in your example) is the reference to the specific chip select - SPI pin (take a look at the SD library documentation found in the Arduino site).

Also, given you are booting from the SD, the complete filesystem and the SD itself is already available, so use it via the Linux filesystem calls.

A modified version of your code should work, at least for testing purposes:

// The file to write in

FILE *myFile;

void setup()

{

// Just to have some time to open the serial monitor...

sleep(3);

Serial.begin(9600);

Serial.println("Arduino Code start...");

// Create the file

system("touch /media/mmcblk0p1/test.txt");

// open the file, Linux open, so you can open many files

myFile = fopen("/media/mmcblk0p1/test.txt", "a");

// if the file opened okay, write to it:

if (myFile)

{

Serial.print("Writing to test.txt...");

fputs("testing 1, 2, 3.\n", myFile);

// close the file:

fclose(myFile);

Serial.println("done.");

} else {

// if the file didn't open, print an error:

Serial.println("error opening Text.txt");

}

}

void loop()

{

}

Take into account that

myFile = fopen("/media/mmcblk0p1/test.txt", "a");

maybe "similar" but not exactly the same as

myFile = SD.open("test.txt", FILE_WRITE);

since "a" (Linux filesystem) does not necessarily has the same semantics as the Arduino SD library FILE_WRITE (I didn't check)

HTH,

Fernando.

Edit: I was testing the Intel Arduino IDE and I was wrong about

"

SD.begin(4);

will fail

"

it doesn't... even when the SD in Galileo is not connected to the SPI. I still suggest to avoid using the SD library in general. Now that I experimented with the Intel Arduino IDE SD library examples I think it would be useful to take advantage of some File class operations which are not directly available in Linux,e.g. println().

I've changed a little bit the ReadWrite example to

/*

SD card read/write

Example changes (Fernando G. Tinetti):

No # include

No SD.begin

No pinMode(10, OUTPUT)

*/

# include

File myFile;

void setup()

{

// Some time to open serial monitor

delay(3000);

// Open serial communications and wait for port to open:

Serial.begin(9600);

while (!Serial) {

; // wait for serial port to connect. Needed for Leonardo only

}

Serial.print("Initializing SD card...");

// open the file. note that only one file can be open at a time,

// so you have to close this one before opening another.

myFile = SD.open("test.txt", FILE_WRITE);

// if the file opened okay, write to it:

if (myFile) {

Serial.print("Writing to test.txt...");

myFile.println("testing 1, 2, 3.");

// close the file:

myFile.close();

Serial.println("done.");

} else {

// if the file didn't open, print an error:

Serial.println("error opening test.txt");

}

// re-open the file for reading:

myFile = SD.open("test.txt");

if (myFile) {

Serial.println("test.txt:");

// read from the file until there's nothing else in it:

while (myFile.available()) {

Serial.write(myFile.read());

}

// close the file:

myFile.close();

} else {

// if the file didn't open, print an error:

Serial.println("error opening test.txt");

}

}

void loop()

{

// nothing happens after setup

}

( I learned to include code!)

BTW: the file is created/opened at

/media/mmcblk0p1

I assume I could use some specific path, though.

HTH,

Fernando.

View solution in original post

15 Replies
asss
Valued Contributor II
136 Views

Hi,

how about this code?

byte buffer[4096];

SD.begin();

system("touch /media/mmcblk0p1/test.txt");

myfile = SD.open("test.txt", FILE_WRITE);

if(myfile){

myfile.write(buffer,4096);

myfile.flush();

myfile.close();

}

BR,

xbolshe

BBOUC2
New Contributor II
136 Views

Hello xbolshe,

the code you provide works only with SD cards connected to the SPI bus of the Arduino. It does not work with the Yocto SD card, which is connected on specific SPI bus of the Quark.

To use the Linux Yocto SD card, you have to use Linux / C file handling functions (see my previous post)

Benoit

asss
Valued Contributor II
136 Views

Hi Benoit,

I cannot agree with you. My code perfectly works on both Galileo boards with Yocto Linux and Quark CPU as well as Edison board.

If you want to check it I recommend you to analyze my project https://github.com/xbolshe/galiprog xbolshe/galiprog · GitHub

Also it may be interesting a code located in Your_Intel_Arduino_IDE\libraries\SD\src\SD.cpp

It contains information how SD card interface communicates with Yocto Linux

BR,

xbolshe

BBOUC2
New Contributor II
136 Views

Hi xbolshe,

I made some investigations here, and apparently, I have a problem with one of my IDE installation. When I compile the code with the SD library on this machine, it fails completely on my Galileo.

I tried another machine and... tadaaaaa : it works

I suspect that there is a kind of library conflict or something like that on the first machine, and it loads/use a wrong library. I will investigate this later today.

But clearly, the issue is on my side (but anyway, the C file functions are also working - as an answer to Karl100)

Benoit

Pablo_M_Intel
Employee
136 Views

Hi Karl100,

In addition to xbolshe's reply, I would suggest you to check this thread /thread/46635 https://communities.intel.com/thread/46635. The discussion is not exactly about writing on the SD card, but it's a related issue and some of the posts might be of help to you.

Regards,

PabloM_Intel

FTinetti
Honored Contributor I
137 Views

Hi,

Provided you are booting from an SD card I'd suggest to completely avoid using the SD library. More specifically,

SD.begin(4);

will fail because the SD card is not connected to the SPI interface in Galileo. The SD card hardware is not an Arduino SD shield. Even more specifically, the SD.begin() argument (4 in your example) is the reference to the specific chip select - SPI pin (take a look at the SD library documentation found in the Arduino site).

Also, given you are booting from the SD, the complete filesystem and the SD itself is already available, so use it via the Linux filesystem calls.

A modified version of your code should work, at least for testing purposes:

// The file to write in

FILE *myFile;

void setup()

{

// Just to have some time to open the serial monitor...

sleep(3);

Serial.begin(9600);

Serial.println("Arduino Code start...");

// Create the file

system("touch /media/mmcblk0p1/test.txt");

// open the file, Linux open, so you can open many files

myFile = fopen("/media/mmcblk0p1/test.txt", "a");

// if the file opened okay, write to it:

if (myFile)

{

Serial.print("Writing to test.txt...");

fputs("testing 1, 2, 3.\n", myFile);

// close the file:

fclose(myFile);

Serial.println("done.");

} else {

// if the file didn't open, print an error:

Serial.println("error opening Text.txt");

}

}

void loop()

{

}

Take into account that

myFile = fopen("/media/mmcblk0p1/test.txt", "a");

maybe "similar" but not exactly the same as

myFile = SD.open("test.txt", FILE_WRITE);

since "a" (Linux filesystem) does not necessarily has the same semantics as the Arduino SD library FILE_WRITE (I didn't check)

HTH,

Fernando.

Edit: I was testing the Intel Arduino IDE and I was wrong about

"

SD.begin(4);

will fail

"

it doesn't... even when the SD in Galileo is not connected to the SPI. I still suggest to avoid using the SD library in general. Now that I experimented with the Intel Arduino IDE SD library examples I think it would be useful to take advantage of some File class operations which are not directly available in Linux,e.g. println().

I've changed a little bit the ReadWrite example to

/*

SD card read/write

Example changes (Fernando G. Tinetti):

No # include

No SD.begin

No pinMode(10, OUTPUT)

*/

# include

File myFile;

void setup()

{

// Some time to open serial monitor

delay(3000);

// Open serial communications and wait for port to open:

Serial.begin(9600);

while (!Serial) {

; // wait for serial port to connect. Needed for Leonardo only

}

Serial.print("Initializing SD card...");

// open the file. note that only one file can be open at a time,

// so you have to close this one before opening another.

myFile = SD.open("test.txt", FILE_WRITE);

// if the file opened okay, write to it:

if (myFile) {

Serial.print("Writing to test.txt...");

myFile.println("testing 1, 2, 3.");

// close the file:

myFile.close();

Serial.println("done.");

} else {

// if the file didn't open, print an error:

Serial.println("error opening test.txt");

}

// re-open the file for reading:

myFile = SD.open("test.txt");

if (myFile) {

Serial.println("test.txt:");

// read from the file until there's nothing else in it:

while (myFile.available()) {

Serial.write(myFile.read());

}

// close the file:

myFile.close();

} else {

// if the file didn't open, print an error:

Serial.println("error opening test.txt");

}

}

void loop()

{

// nothing happens after setup

}

( I learned to include code!)

BTW: the file is created/opened at

/media/mmcblk0p1

I assume I could use some specific path, though.

HTH,

Fernando.

View solution in original post

KKaes
Beginner
136 Views

Thank you for this helpful explanation!

Karl

BBOUC2
New Contributor II
136 Views

Hello Karl,

simply said, you do not need anything special to write/read files on the SD card. Do not forget that it is a mounted volume for Linux (a "hard disk" for Linux if you prefer), so you can write and read any files at any place using the C system calls. Just google for fopen, fclose, fwrite, fread C functions. You can call them directly from any Galileo sketch.

However, take care about 2 things :

- the file location. I recommend you to create a dedicated subdirectory and use it for your own files. Avoid writing in system directories (the Linux will allow you to do it, but if you make a mistake in your code with file creation/deletion, you may get very bad surprizes if you delete/rename a system file by accident

- the Flash write limitation : the SD card is a Flash memory, and Flash memories have a limited number of write cycles (around 100.000 for each sector). Linux will take care of that and will use a specific algorithm to use a new sector each time you write something (even if it's the same file). This will limit the impact, and for 99.999% of the cases, the Flash will not reach the limit of writing cycles until hundreds of years (do not forget : it's "per sector", not "the whole Flash". It's not writing 100.000 times in the Flash, it's writing 100.000 times in the same sector ). Once again, it's only a problem if you write big files every second for example.

There is no limitation in reading the files, you can do it billions of times of course, it has no impact on the Flash life

By the way, I recommend you to use ssh to check what your sketch is doing with the file. You will then be able to see what happens in the file system when your sketch is running.

Benoit

FTinetti
Honored Contributor I
136 Views

You're welcome.

I've edited my reply, since I've experimented a little bit more with the SD library

I don't have an Arduino SD shield, though, which would be good for comparison purposes (semantic, mostly, Arduino SD vs. Galileo SD).

Fernando.

thass1
New Contributor I
136 Views

Hi FGT,

I tried your code and It is working. Thanks!! Do you know how to write files on Linux home directory instead of media? I have to use Arduino IDE.

FTinetti
Honored Contributor I
136 Views

taha82 wrote:

Hi FGT,

I tried your code and It is working. Thanks!! Do you know how to write files on Linux home directory instead of media? I have to use Arduino IDE.

You're welcome.

It's good to know someone finds the code useful.

About writing files in home directory (or any other directory, actually): I wrote in my previous reply:

FGT wrote:

BTW: the file is created/opened at

/media/mmcblk0p1

I assume I could use some specific path, though.

and elaborating a little bit more, I think everything in the filesystem beyond /media/mmcblk0p1 would be stored in the .ext3 file which contains the ext3 filesystem, i.e. will be in the filesystem but would be readable only by some ext3 filesystem software "manager" (including all Linux versions, of course). I think it will not be readable as a standard file in the SD card when mounted in a windows computer (as the files created in /media/mmcblk0p1 can be used in a windows computer). Furthermore, the .elf file created and stored by the Arduino IDE is in the .ext3 file, for example, which is the way a sketch is "made" persistent.

HTH,

Fernando.

thass1
New Contributor I
136 Views

Alright. Thanks for your reply. I will try to use the C File functions as BenKissBox mentioned.

Pablo_M_Intel
Employee
136 Views

Hi taha82,

Have you been able to try the C file functions? Do you have updates?

Regards,

Pablo

thass1
New Contributor I
136 Views

Hi,

yeah I was able to create a file with the bellow mentioned code in tmp folder

# include

# include

# include

using namespace std;

string filename = "/tmp/filename.txt";

int main() {

std::ofstream o(filename.c_str());

o << "Hello, World\n" << std::endl;

return 0;

}

So that means we can create text file other then SD card.

thass1
New Contributor I
136 Views

and that also works

# include

int main()

{

FILE * pFile;

char buffer [100];

pFile = fopen ("/tmp/filename.txt" , "r");

if (pFile == NULL) perror ("Error opening file");

else

{

while ( ! feof (pFile) )

{

if ( fgets (buffer , 100 , pFile) == NULL ) break;

fputs (buffer , stdout);

}

fclose (pFile);

}

return 0;

}

Reply