Important update: Arm Announces End of Life Timeline for Mbed. This site will be archived in July 2026. Read the full announcement.
Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
Fopen not opening/creating files on SD card
Hello Denwis,
Try to modify your code as below:
... // fs.mount(&sd); // // Check if file was opened for some reason // if(fp != NULL) // { // pc.printf("File was opened, closing it\n\r"); // fclose(fp); // } // fp = fopen("/sd/mytest/sdtest.txt", "w"); // if(fp == NULL) { // pc.printf("Could not open file for write\n\r"); // } // fprintf(fp, "Hello fun SD Card World!"); // for (int i = 0; i < 20; i++){ // printf("Writing decimal numbers to a file (%d/20)\r\n", i); // fprintf(fp, "%d\r\n", i); // } // pc.printf("Writing decimal numbers to a file (20/20) done.\r\n"); // pc.printf("Closing file.\n\r"); // fclose(fp); // return 0; int err = fs.mount(&sd); pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); if (err) return err; // Open the file. pc.printf("Opening file '/sd/mytest/sdtest.txt'... "); fp = fopen("/sd/mytest/sdtest.txt", "w+"); pc.printf("%s\r\n", (!fp ? "Failed :(\r\n" : "OK\r\n")); if (!fp) { // Check whether directory '/sd/mytest' exists. pc.printf("\r\nChecking directory '/sd/mytest'...\r\n"); struct stat info; err = stat("/sd/mytest", &info); if (err) { pc.printf("Directory '/sd/mytest' does not exist.\r\n"); pc.printf("Trying to create it..."); err = mkdir("/sd/mytest", 0777); pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); if (err) return err; } // Create a new 'sdtest.txt' file. pc.printf("File not found, creating a new one...\r\n"); fp = fopen("/sd/mytest/sdtest.txt", "w+"); pc.printf("%s\r\n", (!fp ? "Failed :(" : "OK")); if (!fp) { error("error: %s (%d)\r\n", strerror(errno), -errno); return errno; } } for (int i = 0; i < 10; i++) { pc.printf("Writing numbers (%d/%d)... ", i, 10); err = fprintf(fp, " %d\r\n", i); if (err < 0) { pc.printf("Fail :(\r\n"); error("error: %s (%d)\r\n", strerror(errno), -errno); } else pc.printf("OK\r\n"); } pc.printf("Writing numbers (%d/%d)... OK\r\n\r\n", 10, 10); err = fclose(fp); pc.printf("Closing file '/sd/mytest/sdtest.txt'... "); pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); if (err) return err; return 0;
- Before using it remember to format your SD card for the FAT file system for example with the SD Formatter utility.
- To test the code above I have connected an SD card to my mbed board according to this schematic and it worked fine.
Thanks for your input,
I get errors saying " Error: Incomplete type is not allowed "struct stat info;"" " Error: Incomplete type is not allowed "err = stat("/sd/mytest", &info);"" Am I missing a library for stat?
If it helps, I am using mbed os version 5.5.7 for mDot uses.
I double checked my SD card and it is in FAT32 format. I formatted it again just in case.
This is what I'm following for my SD card breakout board
MOSI - 11 - Green, MISO - 12 - Red, CLK - 13 - Yellow, CS - 8 - Blue
I have tested the code with mbed-os- 5.7.7:
- The data type
struct stat
and functionint stat(const char *path, struct stat *st)
are declared in theplatform/mbed-retarget.h
file of the mbed-os library. - The
int stat(const char *path, struct stat *st)
function is defined inplatform/mbed-retarget.cpp
file of the mbed-os library.
Unfortunately it seems that older versions do not include stat
support. In such case I would recommend to either create the /sdtest
directory in advance on a PC or to simply use the SD card root directory instead of the /sdtest
one.
There is mismatch between the code and wiring:
- The CS signal supposed to be connected to pin D10
SDBlockDevice sd(D11, D12, D13, D10); // mosi, miso, sclk, cs
- However, on the picture above it is connected to pin D8.
Ok I've created my own struct stat
as shown below.
Now the problem is that mount() never exits.
I have my signals at the correct pins. Sorry it wasn't clear that the signals I gave were to show which wires came from which pin on the arduino, which I used as a guide to how I should wire my SD card breakout board.
EDIT: Nevermind, it does exit mount() and outputs "Failed :(" after a very long time but it doesn't go anywhere else after. Added the sd card code you provided.
stat
#include "platform/FilePath.h" // For struct stat typedef unsigned int dev_t; ///< Device ID type typedef unsigned long ino_t; ///< File serial number typedef unsigned int nlink_t; ///< Number of links to a file typedef unsigned int uid_t; ///< User ID typedef unsigned int gid_t; ///< Group ID typedef signed long off_t; ///< Offset in a data stream struct mbed::stat { dev_t st_dev; ///< Device ID containing file ino_t st_ino; ///< File serial number mode_t st_mode; ///< Mode of file nlink_t st_nlink; ///< Number of links to file uid_t st_uid; ///< User ID gid_t st_gid; ///< Group ID off_t st_size; ///< Size of file in bytes time_t st_atime; ///< Time of last access time_t st_mtime; ///< Time of last data modification time_t st_ctime; ///< Time of last status change }; int mystat(const char *path, struct stat *st) { FilePath fp(path); FileSystemHandle *fs = fp.fileSystem(); if (fs == NULL) { errno = ENODEV; return -1; } int err = fs->stat(fp.fileName(), st); if (err < 0) { errno = -err; return -1; } else { return 0; } }
sdCardTest
int err = fs.mount(&sd); pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); if (err) return err; pc.printf("Error for mounting was %d\n\r", err); // Open the file. pc.printf("Opening file '/sd/mytest/sdtest.txt'... "); fp = fopen("/sd/mytest/sdtest.txt", "w+"); pc.printf("%s\r\n", (!fp ? "Failed :(\r\n" : "OK\r\n")); if (!fp) { // Check whether directory '/sd/mytest' exists. pc.printf("\r\nChecking directory '/sd/mytest'...\r\n"); struct stat info; err = mystat("/sd/mytest", &info); if (err) { pc.printf("Directory '/sd/mytest' does not exist.\r\n"); pc.printf("Trying to create it..."); err = mkdir("/sd/mytest", 0777); pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); if (err) return err; } // Create a new 'sdtest.txt' file. pc.printf("File not found, creating a new one...\r\n"); fp = fopen("/sd/mytest/sdtest.txt", "w+"); pc.printf("%s\r\n", (!fp ? "Failed :(" : "OK")); if (!fp) { error("error: %s (%d)\r\n", strerror(errno), -errno); return errno; } } for (int i = 0; i < 10; i++) { pc.printf("Writing numbers (%d/%d)... ", i, 10); err = fprintf(fp, " %d\r\n", i); if (err < 0) { pc.printf("Fail :(\r\n"); error("error: %s (%d)\r\n", strerror(errno), -errno); } else pc.printf("OK\r\n"); } pc.printf("Writing numbers (%d/%d)... OK\r\n\r\n", 10, 10); err = fclose(fp); pc.printf("Closing file '/sd/mytest/sdtest.txt'... "); pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); if (err) return err; return 0;
The reason why mount
fails could be that the lowest SPI frequency of your mbed board is higher than 100 kHz, so the SD card is not getting initialized properly.
See https://os.mbed.com/forum/bugs-suggestions/topic/27511/
According to the sd-driver library, the most current version, sd-driver-0.1.2, uses mbed-os-5.6.1, and I am now using mbed-os-5.7.4 which the current mdot-3.1.0 uses. This now allows me to use struct stat without problems.
According to that bug topic, I've tried to look for what my board's minimum frequency is and I am having trouble looking for it. I've looked at targets/TARGET_STM/TARGET_STM32F4/spi_api.c
and it has a function to get spi frequency, so I think I can pass a SPI object to it to find my minimum frequency. My device is actually 96MHz according to this information: https://os.mbed.com/platforms/MTS-mDot-F411/ but I can't find what the lowesit SPI frequency is.
I also found this topic: https://os.mbed.com/teams/ST/wiki/SPI-output-clock-frequency and I think that it might help me figure out what I should change the default frequency to, but I am confused as to find which SPI_1 or SPI_2.....and from there I am lost.
Everything works now. I think it was the microSD card to SD card adapter that was the problem. I got a new SD card which is a SanDisk 8GB SDHC card, and it worked perfectly once I put it in the breakout board.
No need to change the default spi frequency in the sd-driver library.
Using mbed version 5.7.4.
Hello I'm back.
So sd card is not working again. It is very inconsistent as I've tried 2 different FAT32 formatted sd cards.
This was my process:
I wired the breakout board to an arduino with the same wiring schematics as I've posted before. I tried 6 different sd cards to see which ones were being read correctly. I formatted the cards and 2 were showing files and folders consistently 10/10 tries so I thought they would work when I wire the breakout board to my mDot.
I wire the sd card reader breakout board to my mDot and upload my mbed code to it and it worked initializing, mounting, and creating directory and file. Great. Then I reset my mDot and it initializes and mounts successfully and tries to open the newly created file, but it then just freezes there. I reset again, and it does the same thing.
I then decide to delete the created folder from my PC and put the sd card back to the sd card reader breakout board. This time, it freezes in the initializing stage. I tried again with my other SD card that worked when trying on arduino and it did the same thing, freezes in initializing line.
I wire the breakout board to the arduino again and it reads everything consistently. I don't think it's the breakout board, or the breadbaord, or the wiring. I also tried to use the sd-driver-hs version but that doesn't work either.
I've tried to use SDFileSystem that some people have changed and they don't work. At this point, could it be my mDot? Maybe the high frequency with SPI. Mind you I am using the online compiler. I tried to import ARM's sd-driver 1.2 from github to the online compiler and still same results. I've been using the sd-driver library that is available from the online compiler import function.
I do not use mDot so I'm not able to verify whether it could interfere with the sd-driver. Just a few tips:
- I was recently struggling with a faulty SD card slot too. So I think it's a good idea to test also the slot with Arduino before using it in mbed application.
- Make sure that each file in your code was closed before removing the SD card from a slot.
- Try to simplify your program as much as possible to see which part could cause the problem.
Hi,
So I am trying to create an unexisting text file in my SD card and I am unable to fopen my path or file. I am using this SD card breakout from sparkfun: https://www.sparkfun.com/products/12941
My init() function for the Blockdevice is successful.
I've tried to use the SDFileSystem library but apparently it isn't supported anymore: https://os.mbed.com/questions/77743/stm32f769NI-SDFileSystem-Error/
I'm using a microSD card adapter. I don't know if this may be causing the errors and I am using a mDot.
And I am following along this code: https://os.mbed.com/teams/University-of-Plymouth-Stage-2-and-3/code/ELEC350-SD_Card_Demo/file/528e42a15d44/main.cpp/
Thanks.
SDCardTest