aboutsummaryrefslogtreecommitdiff
path: root/src/systemcmds/mtd/mtd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemcmds/mtd/mtd.c')
-rw-r--r--src/systemcmds/mtd/mtd.c159
1 files changed, 111 insertions, 48 deletions
diff --git a/src/systemcmds/mtd/mtd.c b/src/systemcmds/mtd/mtd.c
index 43e42c951..baef9dccc 100644
--- a/src/systemcmds/mtd/mtd.c
+++ b/src/systemcmds/mtd/mtd.c
@@ -66,7 +66,7 @@ __EXPORT int mtd_main(int argc, char *argv[]);
#ifndef CONFIG_MTD_RAMTRON
-/* create a fake command with decent message to not confuse users */
+/* create a fake command with decent warnx to not confuse users */
int mtd_main(int argc, char *argv[])
{
errx(1, "RAMTRON not enabled, skipping.");
@@ -75,34 +75,49 @@ int mtd_main(int argc, char *argv[])
#else
static void mtd_attach(void);
-static void mtd_start(void);
-static void mtd_erase(void);
-static void mtd_ioctl(unsigned operation);
-static void mtd_save(const char *name);
-static void mtd_load(const char *name);
+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 bool attached = false;
static bool started = false;
static struct mtd_dev_s *mtd_dev;
-static char *_mtdname = "/dev/mtd_params";
-static char *_wpname = "/dev/mtd_waypoints";
+
+/* note, these will be equally sized */
+static char *partition_names_default[] = {"/fs/mtd_params", "/fs/mtd_waypoints"};
+static const int n_partitions_default = sizeof(partition_names_default) / sizeof(partition_names_default[0]);
int mtd_main(int argc, char *argv[])
{
if (argc >= 2) {
- if (!strcmp(argv[1], "start"))
- mtd_start();
+ if (!strcmp(argv[1], "start")) {
+
+ /* start mapping according to user request */
+ if (argc > 3) {
+ mtd_start(argv + 2, argc - 2);
+
+ } else {
+ mtd_start(partition_names_default, n_partitions_default);
+ }
+ }
if (!strcmp(argv[1], "test"))
mtd_test();
+
+ if (!strcmp(argv[1], "erase")) {
+ if (argc < 3) {
+ errx(1, "usage: mtd erase <PARTITION_PATH..>");
+ }
+ mtd_erase(argv + 2, argc - 2);
+ }
}
- errx(1, "expected a command, try 'start' or 'test'");
+ errx(1, "expected a command, try 'start', 'erase' or 'test'");
}
struct mtd_dev_s *ramtron_initialize(FAR struct spi_dev_s *dev);
-
+struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd,
+ off_t firstblock, off_t nblocks);
static void
mtd_attach(void)
@@ -140,7 +155,7 @@ mtd_attach(void)
}
static void
-mtd_start(void)
+mtd_start(char *partition_names[], unsigned n_partitions)
{
int ret;
@@ -151,65 +166,113 @@ mtd_start(void)
mtd_attach();
if (!mtd_dev) {
- warnx("ERROR: Failed to create RAMTRON FRAM MTD instance\n");
+ warnx("ERROR: Failed to create RAMTRON FRAM MTD instance");
exit(1);
}
- /* Initialize to provide an FTL block driver on the MTD FLASH interface.
- *
- * NOTE: We could just skip all of this FTL and BCH stuff. We could
- * instead just use the MTD drivers bwrite and bread to perform this
- * test. Creating the character drivers, however, makes this test more
- * interesting.
- */
- ret = ftl_initialize(0, mtd_dev);
+ /* Get the geometry of the FLASH device */
- if (ret < 0) {
- warnx("Creating /dev/mtdblock0 failed: %d\n", ret);
- exit(2);
- }
+ FAR struct mtd_geometry_s geo;
- /* Now create a character device on the block device */
-
- ret = bchdev_register("/dev/mtdblock0", _mtdname, false);
+ ret = mtd_dev->ioctl(mtd_dev, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&geo));
if (ret < 0) {
- warnx("ERROR: bchdev_register %s failed: %d\n", _mtdname, ret);
+ warnx("ERROR: mtd->ioctl failed: %d", ret);
exit(3);
}
- /* mount the mtd */
- ret = mount(NULL, "/mtd", "nxffs", 0, NULL);
+ warnx("Flash Geometry:");
+ warnx(" blocksize: %lu", (unsigned long)geo.blocksize);
+ warnx(" erasesize: %lu", (unsigned long)geo.erasesize);
+ warnx(" neraseblocks: %lu", (unsigned long)geo.neraseblocks);
- if (ret < 0)
- errx(1, "failed to mount /mtd - erase mtd to reformat");
+ /* Determine the size of each partition. Make each partition an even
+ * multiple of the erase block size (perhaps not using some space at the
+ * end of the FLASH).
+ */
- started = true;
- warnx("mounted mtd at /mtd");
- exit(0);
-}
+ unsigned blkpererase = geo.erasesize / geo.blocksize;
+ unsigned nblocks = (geo.neraseblocks / n_partitions) * blkpererase;
+ unsigned partsize = nblocks * geo.blocksize;
-static void
-mtd_ioctl(unsigned operation)
-{
- int fd;
+ warnx(" No. partitions: %u", n_partitions);
+ warnx(" Partition size: %lu Blocks (%lu bytes)", (unsigned long)nblocks, (unsigned long)partsize);
+
+ /* Now create MTD FLASH partitions */
+
+ warnx("Creating partitions");
+ FAR struct mtd_dev_s *part[n_partitions];
+ char blockname[32];
+
+ unsigned offset;
+ unsigned i;
- fd = open("/mtd/.", 0);
+ for (offset = 0, i = 0; i < n_partitions; offset += nblocks, i++) {
- if (fd < 0)
- err(1, "open /mtd");
+ warnx(" Partition %d. Block offset=%lu, size=%lu",
+ i, (unsigned long)offset, (unsigned long)nblocks);
- if (ioctl(fd, operation, 0) < 0)
- err(1, "ioctl");
+ /* Create the partition */
+ part[i] = mtd_partition(mtd_dev, offset, nblocks);
+
+ if (!part[i]) {
+ warnx("ERROR: mtd_partition failed. offset=%lu nblocks=%lu",
+ (unsigned long)offset, (unsigned long)nblocks);
+ exit(4);
+ }
+
+ /* Initialize to provide an FTL block driver on the MTD FLASH interface */
+
+ snprintf(blockname, sizeof(blockname), "/dev/mtdblock%d", i);
+
+ ret = ftl_initialize(i, part[i]);
+
+ if (ret < 0) {
+ warnx("ERROR: ftl_initialize %s failed: %d", blockname, ret);
+ exit(5);
+ }
+
+ /* Now create a character device on the block device */
+
+ ret = bchdev_register(blockname, partition_names[i], false);
+
+ if (ret < 0) {
+ warnx("ERROR: bchdev_register %s failed: %d", partition_names[i], ret);
+ exit(6);
+ }
+ }
+
+ started = true;
exit(0);
}
static void
mtd_test(void)
{
-// at24c_test();
+ warnx("This test routine does not test anything yet!");
+ exit(1);
+}
+
+static void
+mtd_erase(char *partition_names[], unsigned n_partitions)
+{
+ uint8_t v[64];
+ memset(v, 0xFF, sizeof(v));
+ for (uint8_t i = 0; i < n_partitions; i++) {
+ uint32_t count = 0;
+ printf("Erasing %s\n", partition_names[i]);
+ int fd = open(partition_names[i], O_WRONLY);
+ if (fd == -1) {
+ errx(1, "Failed to open partition");
+ }
+ while (write(fd, &v, sizeof(v)) == sizeof(v)) {
+ count += sizeof(v);
+ }
+ printf("Erased %lu bytes\n", (unsigned long)count);
+ close(fd);
+ }
exit(0);
}