2. Using file I/O¶
In this tutorial we will see how to read and write files on an SD card.
Mono has a Micro SD Card slot and currently supports communicating with an SD card using an SPI interface. We have included both SD card I/O and FAT32 file system I/O in our framework. As soon as you have setup the SD card I/O you can use the familiar stdio.h
file I/O.
Get an SD Card¶
First order of business is for you to obtain a MicroSD Card and format it in good ol’ FAT32. Then insert the card into Mono’s slot and fire up a new project:
$ monomake project fileIO --bare
Creating new bare mono project: fileIO...
* fileIO/app_controller.h
* fileIO/app_controller.cpp
Writing Makefile: fileIO/Makefile...
Atom Project Settings: Writing Auto complete includes...
Note
Notice that we use the switch --bare
when we created the project. This option strips all comments from the template code. This way you have a less verbose starting point.
Now cd
into the fileIO
directory and open the code files in your favourite code editor.
Initalizing the SD Card¶
Open app_controller.h and add these lines:
#include <mono.h>
// import the SD card and FS definitions
#include <io/file_system.h>
#include <stdio.h>
class AppController : public mono::IApplication {
public:
mono::io::FileSystem fs; // create an instance of the FS I/O
AppController();
Here we include the definitions for the both the SD card I/O and the file I/O. Next, we need to contruct the fs
object in AppController
‘s constructor. Go to app_controller.cpp:
AppController::AppController() :
fs("sd")
{
}
Here we initialize the file system and provide the library for communicating with the SD Card. The parameter "sd"
is the mount point. This means the SD Card is mounted at /sd
.
Writing to a file¶
Let us write a file in the SD card. We use the standard C library functions fopen
and fwrite
, that you might know - if you ever coded in C.
So, to write some data to a file we insert the following code in the monoWakeFromReset
method:
void AppController::monoWakeFromReset()
{
FILE *file = fopen("/sd/new_file.txt", "w");
if (file == 0) {
printf("Could not open write file!\r\n");
return;
}
else {
const char *str = "Hello file system!\nRemember coding in C?";
int written = fwrite(str, 1, strlen(str), file);
printf("Wrote %d bytes\r\n",written);
fclose(file);
}
}
Here we open/create a file on the SD card called new_file.txt
. The fopen
function returns a file descriptor (FILE*
) that is 0
if an error occurs.
If file
is not 0
we write some text to it and finally close (fclose
) the file to flush the written data to the disk. You should always close files when you are done writing to them. If you don’t, you risk losing your written data.
Reading from a file¶
So we just written to a file, now let us read what we just wrote. Append the following to the monoWakeFromReset
method:
FILE *rFile = fopen("/sd/new_file.txt", "r");
if (rFile == 0) {
printf("Could not open read file!\r\n");
return;
}
char buffer[100];
memset(buffer, 0, 100);
int read = fread(buffer, 1, 100, rFile);
printf("Read %d bytes from file\r\n", read);
printf("%s\r\n", buffer);
fclose(rFile);
Here we first open the file we previously written. Then, we create a byte buffer to hold the data we read from the file. Because the initial content of buffer
is nondeterministic, we zero its contents with the memset
call.
Note
We do this because printf
needs a string terminator. A string terminator is a 0
character. Upon accounting a 0
printf
will know that the end of the string has been reached.
The fread
function reads the data from the file. It reads the first 100 bytes or until EOF is reached. Then we just print the contents of buffer, which is the content of the file.
Standard C Library¶
As mentioned earlier, you have access to the file I/O of stdlib
. This means you can use the familiar stdlib file I/O API’s.
These include:
fprintf
fscanf
fseek
ftell
fflush
fgetc
fputc
- etc.
When you for example read or write from the serial port (using printf
), you in fact just use the stdout
and stdin
global pointers. (stderr
just maps to stdout
.)
See the API for the stdlib file I/O here: www.cplusplus.com/reference/cstdio