Add support for the byte write method to MTD partition logic; Beef up the MTD partition test -- and fix resulting bugs detected

This commit is contained in:
Gregory Nutt 2013-05-02 08:07:42 -06:00
parent f2139ef029
commit 1190bd7d50
3 changed files with 155 additions and 10 deletions

View File

@ -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).

View File

@ -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)

View File

@ -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");