Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SD card access and Read Only FAT32 file system support #360

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

alees24
Copy link
Contributor

@alees24 alees24 commented Nov 28, 2024

CI failures are expected; there is no microSD card( image) in either simulationor FPGA testing at present.

This PR does the following:

Commit 1:

  • Introduces SD card support on top of the SPI driver
  • Adds a manual 'check' program called 'sdraw_check' that insists upon manual insertion of a card that may be corrupted by the test, and then performs a number of randomised block writes and reads to check that these occur successfully.

Commit 2:

  • Introduces Read Only support for a single FAT32 partition (as SD cards are typically shipped by manufacturers).
  • Adds SD card testing to the 'test_runner' regression test in CI to test (i) SD card presence, (ii) the ability to read the card properties, (iii) the ability to read a sample text file from the root directory of a FAT32 partition on the SD card (iv) that it matches against a reference copy.

Whilst 'sdraw_check' may be run against any modern microSD card of suitable capacity that does not contain data you wish to keep, the test program in the second commit requires that the card be prepared with a suitable file 'LOREM.IPS' (with that exact name and capitalisation at present). Detailed instructions may be found in the source file sw/cheri/tests/sdcard_tests.hh; in outline, modify that file by setting 'emitText = true' before running it for the first time and it will emit the instructions and the sample text that must be used in setting up the microSD card.

Create a single FAT32 partition on the card, using the 'Master Boot Record' scheme and not 'GPT.' Newly-purchased cards should already be suitable although only 32GiB and 64GiB cards have been tried to date.

Still to come, and probably required before we can merge this (to keep the FPGA and simulation consistent):
1. DPI model of a SPI-connected SD card; this allows the above test to pass in simulation too.

Still on the 'TODO' list - but perhaps may be left - until a later PR are:
1. Improved filename matching within directories, including Long FileName support.
2. A fresh attempt to get multiple block read/write operations working; these are presently implemented using repeated single block reads.

Copy link
Contributor

@marnovandermaas marnovandermaas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together. I just left a few comments while reading through the code. We'll need to get CI to pass before merging, but this is good enough to share around to people that want to get started with SD cards.

Comment on lines +23 to +26
// clang-format off
#include <ds/xoroshiro.h>
#include <cheri.hh>
// clang-format on
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you turn off clang format for these?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied/mimicked code; it's done in other files. I think we even still have a source file that #includes a single file twice, once inside those comments and once outside!

static int compare_bytes(const uint8_t *ref, const uint8_t *data, size_t len, Log &log) {
unsigned mismatches = 0u;
while (len-- > 0u) {
mismatches += *ref++ != *data++;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice line of C ;)

sw/cheri/checks/sdraw_check.cc Outdated Show resolved Hide resolved
sw/cheri/checks/sdraw_check.cc Outdated Show resolved Hide resolved
sw/cheri/common/sdcard-utils.hh Outdated Show resolved Hide resolved
static uint8_t fileBuffer[BLOCK_LEN];

// Dump out a sequence of bytes as hexadecimal and ASCII text.
static void dump_bytes(const uint8_t *buf, size_t blkBytes, Log &log) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the same as the one in the sdcard check? Can we re-use them somehow?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are presently 3 copies, and one has a comment about moving this into console.hh; I'll move it there unless you can think of a better home?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved it to console.hh as proposed.

sw/cheri/tests/sdcard_tests.hh Outdated Show resolved Hide resolved
// Check each of the read bytes against what we tried to write.
failures += compare_bytes(write_data, read_data, kBlockLen, log);
}
write_test_result(log, failures);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this function only used for tests, or can it also be used in a check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is precedent for using it in checks and I'm not aware of any reason not to do so.

@GregAC
Copy link
Contributor

GregAC commented Nov 29, 2024

Thanks for this @alees24.

I'm keen we do not spend significant time on this right now so let's not worry about spending time on an SD card DPI model. As we already have the test code it's reasonable for us to include the test in CI to run against the real FPGA.

We also need to consider how to to best use this in sonata-software. It's important we have a working example in there, so where shall sdcard-utils.hh live? We could hopefully refactor things so it can work both in the bare metal environment and CHERIoT RTOS environment. I think it's best left in this repository so we don't introduce a new sonata-system -> sonata-software dependency. We have a sonata-software -> sonata-system link though it's done via nix. In order to provide easy code access for people who aren't using the nix environment (i.e. we want a way to build an SD card example in sonata-software without relying on some nix magic to pull the sdcard-utils.hh into the right place) either we bring sonata-system in as a sub-module or we just make a copy of it/vendor it in sonata-software. I think I favour the latter as it's just one file and we don't really want the whole of sonata-system as a big submodule.

We could also just say no sd card util at all in sonata-system to simplify things. That would mean no testing of sd card functionality in CI though. I don't think it's that important as it's just a plain SPI device but would mean if we mess up something do with the pinmux/pin mapping it would get flagged.

@alees24
Copy link
Contributor Author

alees24 commented Nov 29, 2024

The DPI model already exists and works; sdcard_tests.hh works in sim and it's even possible to play video files to the simulated LCD; that was done a couple of weeks ago. I guess it wasn't clear that I meant only that it needs a little tidying before inclusion, so it's not in this PR.

@GregAC
Copy link
Contributor

GregAC commented Nov 29, 2024

The DPI model already exists and works;

Awesome. May as well leverage it then.

re: example in sonata-software I think the thing to do is get this PR merged ignoring that issue. We can then deal with that separately.

@alees24 alees24 marked this pull request as ready for review November 29, 2024 23:30
@alees24
Copy link
Contributor Author

alees24 commented Nov 29, 2024

Right, I think this is ready to go; long filename support and directory traversal/matching could use some more testing but it works well enough for our present needs.

The DPI model is now present, and although the FPGA system presently has problems, 'test_runner' should pass on this PR when they have been resolved. For simulation, however, we have an issue.....it needs an 'sd.img' file that is ca. 1GiB (see the instructions I've added in 'doc/guide/sdcard-setup.md') which currently won't be present when the simulation runs, presumably....suggestions welcome, please!

Note that this manual test will corrupt the contents of
the card so it can only be run manually and will intentionally
insist that you wilfully insert an SD card before it performs
any writes to the card. This is to avoid inadvertent data loss.
SD card test checks for the presence of a microSD card in the
slot, reads and reports the card properties and then proceeds
to check the contents of a test file `LOREM.IPS` in the root
directory of a FAT32-formatted card against its internal
reference.

See the source for directions on how to set up a microSD card
with a suitable file; set 'emitText' to true on the first run
and it will emit the sample text with instructions.

Support for Long FileNames.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants