forked from Archive/PX4-Autopilot
mtd: added "mtd readtest" and "mtd rwtest"
this allows for verification of MTD operation on startup
This commit is contained in:
parent
ff59aa9a0f
commit
e5ad3c31e0
|
@ -89,6 +89,8 @@ static void at24xxx_attach(void);
|
||||||
static void mtd_start(char *partition_names[], unsigned n_partitions);
|
static void mtd_start(char *partition_names[], unsigned n_partitions);
|
||||||
static void mtd_test(void);
|
static void mtd_test(void);
|
||||||
static void mtd_erase(char *partition_names[], unsigned n_partitions);
|
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 void mtd_print_info();
|
||||||
static int mtd_get_geometry(unsigned long *blocksize, unsigned long *erasesize, unsigned long *neraseblocks,
|
static int mtd_get_geometry(unsigned long *blocksize, unsigned long *erasesize, unsigned long *neraseblocks,
|
||||||
unsigned *blkpererase, unsigned *nblocks, unsigned *partsize, unsigned n_partitions);
|
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"))
|
if (!strcmp(argv[1], "test"))
|
||||||
mtd_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"))
|
if (!strcmp(argv[1], "status"))
|
||||||
mtd_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);
|
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;
|
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()
|
void mtd_print_info()
|
||||||
{
|
{
|
||||||
if (!attached)
|
if (!attached)
|
||||||
|
@ -370,7 +403,7 @@ mtd_erase(char *partition_names[], unsigned n_partitions)
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
errx(1, "Failed to open partition");
|
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);
|
count += sizeof(v);
|
||||||
}
|
}
|
||||||
printf("Erased %lu bytes\n", (unsigned long)count);
|
printf("Erased %lu bytes\n", (unsigned long)count);
|
||||||
|
@ -379,4 +412,82 @@ mtd_erase(char *partition_names[], unsigned n_partitions)
|
||||||
exit(0);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue