aboutsummaryrefslogtreecommitdiff
path: root/src/systemcmds/mtd
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2014-01-16 12:46:20 +1100
committerLorenz Meier <lm@inf.ethz.ch>2014-01-16 07:58:45 +0100
commite5ad3c31e01680ccd18fe64d113ecf05de080e71 (patch)
treea84b1dcd1564301b90162d5d454fa5a75664bd4f /src/systemcmds/mtd
parentff59aa9a0f856826682eb5099b1ec2525c5f7ba6 (diff)
downloadpx4-firmware-e5ad3c31e01680ccd18fe64d113ecf05de080e71.tar.gz
px4-firmware-e5ad3c31e01680ccd18fe64d113ecf05de080e71.tar.bz2
px4-firmware-e5ad3c31e01680ccd18fe64d113ecf05de080e71.zip
mtd: added "mtd readtest" and "mtd rwtest"
this allows for verification of MTD operation on startup
Diffstat (limited to 'src/systemcmds/mtd')
-rw-r--r--src/systemcmds/mtd/mtd.c115
1 files changed, 113 insertions, 2 deletions
diff --git a/src/systemcmds/mtd/mtd.c b/src/systemcmds/mtd/mtd.c
index 8bc18b3c2..a2a0c109c 100644
--- a/src/systemcmds/mtd/mtd.c
+++ b/src/systemcmds/mtd/mtd.c
@@ -89,6 +89,8 @@ static void at24xxx_attach(void);
static void mtd_start(char *partition_names[], unsigned n_partitions);
static void mtd_test(void);
static void mtd_erase(char *partition_names[], unsigned n_partitions);
+static void mtd_readtest(char *partition_names[], unsigned n_partitions);
+static void mtd_rwtest(char *partition_names[], unsigned n_partitions);
static void mtd_print_info();
static int mtd_get_geometry(unsigned long *blocksize, unsigned long *erasesize, unsigned long *neraseblocks,
unsigned *blkpererase, unsigned *nblocks, unsigned *partsize, unsigned n_partitions);
@@ -118,6 +120,22 @@ int mtd_main(int argc, char *argv[])
if (!strcmp(argv[1], "test"))
mtd_test();
+ if (!strcmp(argv[1], "readtest")) {
+ if (argc >= 3) {
+ mtd_readtest(argv + 2, argc - 2);
+ } else {
+ mtd_readtest(partition_names_default, n_partitions_default);
+ }
+ }
+
+ if (!strcmp(argv[1], "rwtest")) {
+ if (argc >= 3) {
+ mtd_rwtest(argv + 2, argc - 2);
+ } else {
+ mtd_rwtest(partition_names_default, n_partitions_default);
+ }
+ }
+
if (!strcmp(argv[1], "status"))
mtd_status();
@@ -130,7 +148,7 @@ int mtd_main(int argc, char *argv[])
}
}
- errx(1, "expected a command, try 'start', 'erase' or 'test'");
+ errx(1, "expected a command, try 'start', 'erase', 'status', 'readtest', 'rwtest' or 'test'");
}
struct mtd_dev_s *ramtron_initialize(FAR struct spi_dev_s *dev);
@@ -318,6 +336,21 @@ int mtd_get_geometry(unsigned long *blocksize, unsigned long *erasesize, unsigne
return ret;
}
+/*
+ get partition size in bytes
+ */
+static ssize_t mtd_get_partition_size(void)
+{
+ unsigned long blocksize, erasesize, neraseblocks;
+ unsigned blkpererase, nblocks, partsize = 0;
+
+ int ret = mtd_get_geometry(&blocksize, &erasesize, &neraseblocks, &blkpererase, &nblocks, &partsize, n_partitions_current);
+ if (ret != OK) {
+ errx(1, "Failed to get geometry");
+ }
+ return partsize;
+}
+
void mtd_print_info()
{
if (!attached)
@@ -370,7 +403,7 @@ mtd_erase(char *partition_names[], unsigned n_partitions)
if (fd == -1) {
errx(1, "Failed to open partition");
}
- while (write(fd, &v, sizeof(v)) == sizeof(v)) {
+ while (write(fd, v, sizeof(v)) == sizeof(v)) {
count += sizeof(v);
}
printf("Erased %lu bytes\n", (unsigned long)count);
@@ -379,4 +412,82 @@ mtd_erase(char *partition_names[], unsigned n_partitions)
exit(0);
}
+/*
+ readtest is useful during startup to validate the device is
+ responding on the bus. It relies on the driver returning an error on
+ bad reads (the ramtron driver does return an error)
+ */
+void
+mtd_readtest(char *partition_names[], unsigned n_partitions)
+{
+ ssize_t expected_size = mtd_get_partition_size();
+
+ uint8_t v[128];
+ for (uint8_t i = 0; i < n_partitions; i++) {
+ uint32_t count = 0;
+ printf("reading %s expecting %u bytes\n", partition_names[i], expected_size);
+ int fd = open(partition_names[i], O_RDONLY);
+ if (fd == -1) {
+ errx(1, "Failed to open partition");
+ }
+ while (read(fd, v, sizeof(v)) == sizeof(v)) {
+ count += sizeof(v);
+ }
+ if (count != expected_size) {
+ errx(1,"Failed to read partition - got %u/%u bytes", count, expected_size);
+ }
+ close(fd);
+ }
+ printf("readtest OK\n");
+ exit(0);
+}
+
+/*
+ rwtest is useful during startup to validate the device is
+ responding on the bus for both reads and writes. It reads data in
+ blocks and writes the data back, then reads it again, failing if the
+ data isn't the same
+ */
+void
+mtd_rwtest(char *partition_names[], unsigned n_partitions)
+{
+ ssize_t expected_size = mtd_get_partition_size();
+
+ uint8_t v[128], v2[128];
+ for (uint8_t i = 0; i < n_partitions; i++) {
+ uint32_t count = 0;
+ off_t offset = 0;
+ printf("rwtest %s testing %u bytes\n", partition_names[i], expected_size);
+ int fd = open(partition_names[i], O_RDWR);
+ if (fd == -1) {
+ errx(1, "Failed to open partition");
+ }
+ while (read(fd, v, sizeof(v)) == sizeof(v)) {
+ count += sizeof(v);
+ if (lseek(fd, offset, SEEK_SET) != offset) {
+ errx(1, "seek failed");
+ }
+ if (write(fd, v, sizeof(v)) != sizeof(v)) {
+ errx(1, "write failed");
+ }
+ if (lseek(fd, offset, SEEK_SET) != offset) {
+ errx(1, "seek failed");
+ }
+ if (read(fd, v2, sizeof(v2)) != sizeof(v2)) {
+ errx(1, "read failed");
+ }
+ if (memcmp(v, v2, sizeof(v2)) != 0) {
+ errx(1, "memcmp failed");
+ }
+ offset += sizeof(v);
+ }
+ if (count != expected_size) {
+ errx(1,"Failed to read partition - got %u/%u bytes", count, expected_size);
+ }
+ close(fd);
+ }
+ printf("rwtest OK\n");
+ exit(0);
+}
+
#endif