5 years, 9 months ago.

blockDevice.erase() function not working - doesn't seem to do anything

Hi, I'm working with an SDHC card using the SDBlockDevice and FATFileSystem libraries. My code is at the moment working generally as I expect it to, I've managed to write to files on the card. I'm trying to use the mbed (LPC1768) to erase all the data from the card and time how long it takes to do that. (It's not a hugely essential task but I wasn't expecting it to take long and now I'm worried I might be missing something important).

My problem is that the erase function does not appear to be doing anything - it doesn't return any errors, but all the data and files are still on the SD card afterwards. Can anyone tell me why?

  • Side note, not sure if relevant: I can't seem to get this code to work by starting a file from scratch - if I open a new example and copy-paste the code (into either of the "blinky" templates and with the mbed_app.json added) it will usually not compile, complaining about not knowing what "SDBlockDevice.h" is. I assume it's to do with versions of the mbed-os, but I could be wrong, and I'm not sure how to make it work from scratch. I've been working around it by always starting with cloned versions of the example code from the comment on this question: https://os.mbed.com/questions/84254/Is-it-true-that-handling-of-SD-cards-is-/#answer15937

My code:

main.cpp

#include "mbed.h"
#include <stdio.h>
#include <errno.h>

// Block device
#include "SDBlockDevice.h"

// File system
#include "FATFileSystem.h"

// Physical block device, can be any device that supports the BlockDevice API
SDBlockDevice   blockDevice(p5, p6, p7, p8);
// File system declaration
FATFileSystem   fileSystem("fs");
// Serial connection to pc
Serial pc(USBTX, USBRX);

void erase()
{
    int err = blockDevice.init();
    if (err) {
        error("error: %s (%d)\n", strerror(-err), err);
    }
    fflush(stdout);
    err = blockDevice.erase(0, blockDevice.size());
    if (err) {
        error("error: %s (%d)\n", strerror(-err), err);
    }
    fflush(stdout);
    err = blockDevice.deinit();
    if (err) {
        error("error: %s (%d)\n", strerror(-err), err);
    }
}

void disp_directory()
{
    int err;
     // Display the root directory
    pc.printf("Opening the root directory... \r\n");
    DIR*    d = opendir("/fs/");
    pc.printf("%s\n", (!d ? "Fail :(" : "OK"));
    if (!d) {
        error("error: %s (%d)\n", strerror(errno), -errno);
    }
    pc.printf("root directory:\r\n");
    while (true) {
        struct dirent*  e = readdir(d);
        if (!e) {
            break;
        }
        printf("    %s\r\n", e->d_name);
    }
    printf("Closing the root directory... \r\n");
    err = closedir(d);
    printf("%s\r\n", (err < 0 ? "Fail :(" : "OK"));
    if (err < 0) {
        error("error: %s (%d)\n", strerror(errno), -errno);
    }
}

int main()
{
    
    Timer t;
    // Try to mount the filesystem
    int err = fileSystem.mount(&blockDevice);
    if (err) {
        // Reformat if we can't mount the filesystem
        // this should only happen on the first boot
        printf("No filesystem found, formatting... ");
        fflush(stdout);
        err = fileSystem.reformat(&blockDevice);
        printf("%s\n", (err ? "Fail :(" : "OK"));
        if (err) {
            error("error: %s (%d)\n", strerror(-err), err);
        }
    }
    
    disp_directory();
    
    err = blockDevice.init();
    if (err) {
        error("error: %s (%d)\n", strerror(-err), err);
    }
    
    t.start();
    //printf("Erasing the block device... ");
    //fflush(stdout);
    blockDevice.erase(0, blockDevice.get_erase_size());
    printf("%s\n", (err ? "Fail :(" : "OK"));
    if (err) {
        error("error: %s (%d)\n", strerror(-err), err);
    }
    t.stop();
    pc.printf("Time to erase SD card: %d \r\n", t.read_us());
    
    err = blockDevice.deinit();
    printf("%s\n", (err ? "Fail :(" : "OK"));
    if (err) {
        error("error: %s (%d)\n", strerror(-err), err);
    }
    
    disp_directory();
}

The output of this is:

  • Opening the root directory...
  • OK
  • root directory:
  • System Volume Information
  • myfile.txt
  • numbers.txt
  • newfile.txt
  • Closing the root directory...
  • OK
  • OK
  • Time to erase SD card: 26
  • OK
  • Opening the root directory...
  • OK
  • root directory:
  • System Volume Information
  • myfile.txt
  • numbers.txt
  • newfile.txt
  • Closing the root directory...
  • OK

2 Answers

5 years, 9 months ago.

Erase on SD devices is no-op. Erase() is designed to prepare for write or programming. It doesn't mean the storage is written with a specific value. On certain flash devices, a page erase is required prior to programming so erase() on these devices is implemented.

Lin, team Mbed

Thank you for the explanation. Now it's clear. But it was a bit confusing because one would assume that it was designed to delete files from the SDBlockDevice. But in this case what's the point of calling the erase() function on a button event in the FATFileSystem example. What is it suppose to demonstrate?

posted by Zoltan Hudak 03 Mar 2019
5 years, 9 months ago.

I modified the SDCard example. Now erase runs as last step in the main program rather than to be launched manually by pushing a button. Try it again, it works fine for me.

Hello, many thanks for all your help with this. Unfortunately this is still not working for me, when I run your code then check the card by putting it into my laptop it still contains all the files that were in it before the erase. How does the erase work? Does it actually remove the stored data, or does it simply mark the blocks that have been written to as "available for writing on"? The description in the reference says that an erased block is "undefined" so I wouldn't expect the files to still be readable by my PC, but I can't find where the function is actually implemented. SDBlockDevice inherits (I hope that's the right word) from BlockDevice, and I don't think it reimplements erase(). I can't find a .cpp file for either BlockDevice in general or SDBlockDevice, even though there are .cpp files for a lot of the other things that inherit from BlockDevice here: https://github.com/ARMmbed/mbed-os/tree/master/features/storage/blockdevice. I'm not sure if i'm missing something to do with mbed-os versions or something, but it's frustrating. Thanks again for the help, if you can suggest any other steps to work out what's going wrong it would be lovely, I'm a little stumped.

posted by Frances Conboy 15 Feb 2019

I'm very sorry Frances that I failed to check my SD card. You are right. The erase function does not work and there seems to be no implementation for the SDBlockDevice.

posted by Zoltan Hudak 16 Feb 2019