From bb95a53a6ae12defb44b61ddff8b55011f983196 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 2 May 2013 08:07:42 -0600 Subject: Add support for the byte write method to MTD partition logic; Beef up the MTD partition test -- and fix resulting bugs detected --- apps/ChangeLog.txt | 2 + apps/examples/Makefile | 8 +- apps/examples/mtdpart/mtdpart_main.c | 155 +++++++++++++++++++++++++++++++++-- 3 files changed, 155 insertions(+), 10 deletions(-) (limited to 'apps') diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt index 57abd2e6b..753bdc5cc 100644 --- a/apps/ChangeLog.txt +++ b/apps/ChangeLog.txt @@ -544,3 +544,5 @@ flash_eraseall NSH command (Ken Pettit, 2013-5-1). * apps/examples/flash_test and apps/examples/smart_test: Add tests of the SMART block driver and file system (Ken Pettit, 2013-5-1). + * apps/examples/mtdpart: Extended to the test. The original test + coverage was superficial (2013-5-3). diff --git a/apps/examples/Makefile b/apps/examples/Makefile index 72a554ed0..41593b8f9 100644 --- a/apps/examples/Makefile +++ b/apps/examples/Makefile @@ -39,8 +39,8 @@ SUBDIRS = adc buttons can cdcacm composite cxxtest dhcpd discover elf SUBDIRS += flash_test ftpc ftpd hello helloxx hidkbd igmp json keypadtest -SUBDIRS += lcdrw mm modbus mount nettest nsh null nx nxconsole nxffs nxflat -SUBDIRS += nxhello nximage nxlines nxtext ostest pashello pipe poll +SUBDIRS += lcdrw mm modbus mount mtdpart nettest nsh null nx nxconsole nxffs +SUBDIRS += nxflat nxhello nximage nxlines nxtext ostest pashello pipe poll SUBDIRS += posix_spawn pwm qencoder relays rgmp romfs sendmail serloop SUBDIRS += smart_test telnetd thttpd tiff touchscreen udp uip usbserial SUBDIRS += usbstorage usbterm watchdog wget wgetjson xmlrpc @@ -59,8 +59,8 @@ CNTXTDIRS = pwm ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) CNTXTDIRS += adc can cdcacm composite cxxtest dhcpd discover flash_test ftpd -CNTXTDIRS += hello json keypadtestmodbus nettest nxlines relays qencoder -CNTXTDIRS += smart_test telnetd watchdog wgetjson +CNTXTDIRS += hello json keypadtestmodbus mtdpart nettest nxlines relays +CNTXTDIRS += qencoder smart_test telnetd watchdog wgetjson endif ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y) diff --git a/apps/examples/mtdpart/mtdpart_main.c b/apps/examples/mtdpart/mtdpart_main.c index 9c44826dd..9fcd2a76d 100644 --- a/apps/examples/mtdpart/mtdpart_main.c +++ b/apps/examples/mtdpart/mtdpart_main.c @@ -161,6 +161,8 @@ int mtdpart_main(int argc, char *argv[]) off_t nblocks; off_t offset; off_t check; + off_t sectoff; + off_t seekpos; unsigned int blkpererase; int fd; int i; @@ -182,6 +184,14 @@ int mtdpart_main(int argc, char *argv[]) exit(1); } + /* Perform the IOCTL to erase the entire FLASH part */ + + ret = master->ioctl(master, MTDIOC_BULKERASE, 0); + if (ret < 0) + { + message("ERROR: MTDIOC_BULKERASE ioctl failed: %d\n", ret); + } + /* 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 @@ -345,7 +355,7 @@ int mtdpart_main(int argc, char *argv[]) /* Open the master MTD partition character driver for writing */ snprintf(charname, 32, "/dev/mtd%d", i); - fd = open(charname, O_RDONLY); + fd = open(charname, O_RDWR); if (fd < 0) { message("ERROR: open %s failed: %d\n", charname, errno); @@ -356,11 +366,23 @@ int mtdpart_main(int argc, char *argv[]) /* Now verify the offset in every block */ check = offset; + sectoff = 0; + for (j = 0; j < nblocks; j++) { #if 0 /* Too much */ message(" block=%u offset=%lu\n", j, (unsigned long) check); #endif + /* Seek to the next read position */ + + seekpos = lseek(fd, sectoff, SEEK_SET); + if (seekpos != sectoff) + { + message("ERROR: lseek to offset %ld failed: %d\n", + (unsigned long)sectoff, errno); + msgflush(); + exit(11); + } /* Read the next block into memory */ @@ -369,7 +391,20 @@ int mtdpart_main(int argc, char *argv[]) { message("ERROR: read from %s failed: %d\n", charname, errno); msgflush(); - exit(11); + exit(12); + } + else if (nbytes == 0) + { + message("ERROR: Unexpected end-of file in %s\n", charname); + msgflush(); + exit(13); + } + else if (nbytes != geo.blocksize) + { + message("ERROR: Unexpected read size from %s: %ld\n", + charname, (unsigned long)nbytes); + msgflush(); + exit(14); } /* Since we forced the size of the partition to be an even number @@ -381,7 +416,7 @@ int mtdpart_main(int argc, char *argv[]) { message("ERROR: Unexpected end of file on %s\n", charname); msgflush(); - exit(11); + exit(15); } /* This is not expected at all */ @@ -391,7 +426,7 @@ int mtdpart_main(int argc, char *argv[]) message("ERROR: Short read from %s failed: %lu\n", charname, (unsigned long)nbytes); msgflush(); - exit(11); + exit(16); } /* Verfy the offsets in the block */ @@ -403,16 +438,124 @@ int mtdpart_main(int argc, char *argv[]) message("ERROR: Bad offset %lu, expected %lu\n", (long)buffer[k], (long)check); msgflush(); - exit(12); + exit(17); } - check += 4; + /* Invert the value to indicate that we have verified + * this value. + */ + + buffer[k] = ~check; + check += sizeof(uint32_t); + } + + /* Seek to the next write position */ + + seekpos = lseek(fd, sectoff, SEEK_SET); + if (seekpos != sectoff) + { + message("ERROR: lseek to offset %ld failed: %d\n", + (unsigned long)sectoff, errno); + msgflush(); + exit(18); + } + + /* Now write the block back to FLASH with the modified value */ + + nbytes = write(fd, buffer, geo.blocksize); + if (nbytes < 0) + { + message("ERROR: write to %s failed: %d\n", charname, errno); + msgflush(); + exit(19); + } + else if (nbytes != geo.blocksize) + { + message("ERROR: Unexpected write size to %s: %ld\n", + charname, (unsigned long)nbytes); + msgflush(); + exit(20); } + + /* Get the offset to the next block */ + + sectoff += geo.blocksize; + } + + /* Try reading one more time. We should get the end of file */ + + nbytes = read(fd, buffer, geo.blocksize); + if (nbytes != 0) + { + message("ERROR: Expected end-of-file from %s failed: %d %d\n", + charname, nbytes, errno); + msgflush(); + exit(22); } close(fd); } + /* Now verify that all of the verifed blocks appear where we thing they + * should on the device. + */ + + message("Verfying media:\n"); + + fd = open("/dev/mtd0", O_RDONLY); + if (fd < 0) + { + message("ERROR: open /dev/mtd0 failed: %d\n", errno); + msgflush(); + exit(23); + } + + offset = 0; + check = 0; + + for (i = 0; i < nblocks * CONFIG_EXAMPLES_MTDPART_NPARTITIONS; i++) + { + /* Read the next block into memory */ + + nbytes = read(fd, buffer, geo.blocksize); + if (nbytes < 0) + { + message("ERROR: read from %s failed: %d\n", charname, errno); + msgflush(); + exit(24); + } + else if (nbytes == 0) + { + message("ERROR: Unexpected end-of file in %s\n", charname); + msgflush(); + exit(25); + } + else if (nbytes != geo.blocksize) + { + message("ERROR: Unexpected read size from %s: %ld\n", + charname, (unsigned long)nbytes); + msgflush(); + exit(26); + } + + /* Verfy the values in the block */ + + for (k = 0; k < geo.blocksize / sizeof(uint32_t); k++) + { + if (buffer[k] != ~check) + { + message("ERROR: Bad value %lu, expected %lu\n", + (long)buffer[k], (long)(~check)); + msgflush(); + exit(27); + } + + check += sizeof(uint32_t); + } + } + + close(fd); + /* And exit without bothering to clean up */ message("PASS: Everything looks good\n"); -- cgit v1.2.3