Rearchitecting of some MTD, partition, SMART interfaces, and FLASH drivers to: Better use the byte write capbility when available and to use smaller erase sectors for the erase sector size when available).

This commit is contained in:
Gregory Nutt
2013-05-03 12:52:33 -06:00
parent b934926bd2
commit 72179b7773
17 changed files with 643 additions and 452 deletions
+7 -1
View File
@@ -4651,7 +4651,7 @@
* configs/sim/mtdpart: A new configuration to test MTD * configs/sim/mtdpart: A new configuration to test MTD
partitions (2013-4-30). partitions (2013-4-30).
* configs/sim/mkroe-stm32f4: Support for the MikroElektronika * configs/sim/mkroe-stm32f4: Support for the MikroElektronika
Mikromedia for STM32F4 development board (from Ken Petit, 2013-4-30). Mikromedia for STM32F4 development board (from Ken Pettit, 2013-4-30).
* fs/smartfs: Add Ken Pettits SMART FS (2013-4-30). * fs/smartfs: Add Ken Pettits SMART FS (2013-4-30).
* include/nuttx/mtd.h and most MTD drivers: Add support for * include/nuttx/mtd.h and most MTD drivers: Add support for
(optional) method to perform byte oriented writes if so configured (optional) method to perform byte oriented writes if so configured
@@ -4663,3 +4663,9 @@
(option) byte write method (2013-5-3). (option) byte write method (2013-5-3).
* arch/arm/src/kl: Repartitioning of definitions in headef files * arch/arm/src/kl: Repartitioning of definitions in headef files
from Alan Carvalho de Assis (2013-5-3). from Alan Carvalho de Assis (2013-5-3).
* drivers/mtd/smart.c, fs/smart, and other files: SMART file system
now makes use of the MTD byte write capabilities when present (from
Ken Pettit, 2013-5-3).
* drivers/mtd/m25px.c: Some rearchitecting to use the byte write
capability (when possible) and to use 4KB sectors for the erase block
size when the part supports it (Ken Pettit, 2013-5-3).
+45
View File
@@ -2552,6 +2552,19 @@ nsh>
<p> <p>
<b>STMicro STM32F4-Discovery (STM32 F4 family)</b>. <b>STMicro STM32F4-Discovery (STM32 F4 family)</b>.
This port uses the STMicro STM32F4-Discovery board featuring the STM32F407VGT6 MCU. This port uses the STMicro STM32F4-Discovery board featuring the STM32F407VGT6 MCU.
The STM32F407VGT6 is a 168MHz Cortex-M4 operation with 1Mbit Flash memory and 128kbytes.
The board features:
</p>
<ul>
<li>On-board ST-LINK/V2 for programming and debugging,</li>
<li>LIS302DL, ST MEMS motion sensor, 3-axis digital output accelerometer,</li>
<li>MP45DT02, ST MEMS audio sensor, omni-directional digital microphone,</li>
<li>CS43L22, audio DAC with integrated class D speaker driver,</li>
<li>Eight LEDs and two push-buttons,</li>
<li>USB OTG FS with micro-AB connector, and</li>
<li>Easy access to most MCU pins.</li>
</ul>
<p>
Refer to the <a href="http://www.st.com/internet/evalboard/product/252419.jsp">STMicro web site</a> for further information about this board. Refer to the <a href="http://www.st.com/internet/evalboard/product/252419.jsp">STMicro web site</a> for further information about this board.
</p> </p>
<ul> <ul>
@@ -2567,6 +2580,38 @@ nsh>
<td><br></td> <td><br></td>
<td><hr></td> <td><hr></td>
</tr> </tr>
<tr>
<td><br></td>
<td>
<p>
<b>MikroElektronika Mikromedia for STM32F4</b>.
This is another board supported by NuttX that uses the same STM32F407VGT6 MCU as does the STM32F4-Discovery board.
This board, however, has very different on-board peripherals than does the STM32F4-Discovery:
</p>
<ul>
<li>TFT display with touch panel,</li>
<li>VS1053 stereo audio codec with headphone jack,</li>
<li>SD card slot,</li>
<li>Serial FLASH memory,</li>
<li>USB OTG FS with micro-AB connector, and</li>
<li>Battery connect and batter charger circuit.</li>
</ul>
<p>
See the <a href="http://www.mikroe.com/mikromedia/stm32-m4/">Mikroelektronika website<a> for more information about this board.
</p>
<ul>
<p>
<b>STATUS:</b>
The basic port for the Mikromedia STM32 M4 was contributed by Ken Petit and was first released in NuttX-6.128.
All drivers for the STM32 F4 family may be used with this board as well.
</p>
</ul>
</td>
</tr>
<tr>
<td><br></td>
<td><hr></td>
</tr>
<tr> <tr>
<td><br></td> <td><br></td>
<td> <td>
+55 -14
View File
@@ -5,53 +5,94 @@
if ARCH_BOARD_MIKROE_STM32F4 if ARCH_BOARD_MIKROE_STM32F4
config PM_BUTTONS config MIKROE_FLASH
bool "PM Button support" bool "MTD driver for onboard 1M FLASH"
default n default n
depends on PM && ARCH_IRQBUTTONS select MTD
select MTD_M25P
select MTD_SMART
select FS_SMARTFS
select STM32_SPI3
select MTD_BYTE_WRITE
---help--- ---help---
Enable PM button EXTI interrupts to support PM testing Configures an MTD device for use with the onboard flash
config PM_BUTTON_ACTIVITY config MIKROE_FLASH_MINOR
int "Button PM activity weight" int "Minor number for the FLASH /dev/smart entry"
default 10 default 0
depends on PM_BUTTONS depends on MIKROE_FLASH
---help--- ---help---
The activity weight to report to the power management subsystem when a button is pressed. Sets the minor number for the FLASH MTD /dev entry
config MIKROE_FLASH_PART
bool "Enable partition support on FLASH"
default n
depends on MIKROE_FLASH
---help---
Enables creation of partitions on the FLASH
config MIKROE_FLASH_PART_LIST
string "Flash partition size list"
default "256,768"
depends on MIKROE_FLASH_PART
---help---
Comma separated list of partition sizes in KB
config MIKROE_RAMMTD
bool "MTD driver for SMARTFS RAM disk"
default n
select MTD
select RAMMTD
---help---
Configures an MTD based RAM device for use with SMARTFS.
config MIKROE_RAMMTD_MINOR
int "Minor number for RAM /dev/smart entry"
default 1
depends on MIKROE_RAMMTD
---help---
Sets the minor number for the RAM MTD /dev entry
config MIKROE_RAMMTD_SIZE
int "Size in KB of the RAM device to create"
default 32
depends on MIKROE_RAMMTD
---help---
Sets the size of static RAM allocation for the SMART RAM device
config PM_ALARM_SEC config PM_ALARM_SEC
int "PM_STANDBY delay (seconds)" int "PM_STANDBY delay (seconds)"
default 15 default 15
depends on PM && RTC_ALARM depends on PM && RTC_ALARM
--help--- ---help---
Number of seconds to wait in PM_STANDBY before going to PM_STANDBY mode. Number of seconds to wait in PM_STANDBY before going to PM_STANDBY mode.
config PM_ALARM_NSEC config PM_ALARM_NSEC
int "PM_STANDBY delay (nanoseconds)" int "PM_STANDBY delay (nanoseconds)"
default 0 default 0
depends on PM && RTC_ALARM depends on PM && RTC_ALARM
--help--- ---help---
Number of additional nanoseconds to wait in PM_STANDBY before going to PM_STANDBY mode. Number of additional nanoseconds to wait in PM_STANDBY before going to PM_STANDBY mode.
config PM_SLEEP_WAKEUP config PM_SLEEP_WAKEUP
bool "PM_SLEEP wake-up alarm" bool "PM_SLEEP wake-up alarm"
default n default n
depends on PM && RTC_ALARM depends on PM && RTC_ALARM
--help--- ---help---
Wake-up of PM_SLEEP mode after a delay and resume normal operation. Wake-up of PM_SLEEP mode after a delay and resume normal operation.
config PM_SLEEP_WAKEUP_SEC config PM_SLEEP_WAKEUP_SEC
int "PM_SLEEP delay (seconds)" int "PM_SLEEP delay (seconds)"
default 10 default 10
depends on PM && RTC_ALARM depends on PM && RTC_ALARM
--help--- ---help---
Number of seconds to wait in PM_SLEEP before going to PM_STANDBY mode. Number of seconds to wait in PM_SLEEP before going to PM_STANDBY mode.
config PM_SLEEP_WAKEUP_NSEC config PM_SLEEP_WAKEUP_NSEC
int "PM_SLEEP delay (nanoseconds)" int "PM_SLEEP delay (nanoseconds)"
default 0 default 0
depends on PM && RTC_ALARM depends on PM && RTC_ALARM
--help--- ---help---
Number of additional nanoseconds to wait in PM_SLEEP before going to PM_STANDBY mode. Number of additional nanoseconds to wait in PM_SLEEP before going to PM_STANDBY mode.
endif endif
+14 -1
View File
@@ -2,7 +2,20 @@ README
====== ======
This README discusses issues unique to NuttX configurations for the This README discusses issues unique to NuttX configurations for the
MikroElektronika Mikromedia for STM32F4 development board. MikroElektronika Mikromedia for STM32F4 development board. This is
another board support by NuttX that uses the same STM32F407VGT6 MCU
as does the STM32F4-Discovery board. This board, however, has very
different on-board peripherals than does the STM32F4-Discovery:
- TFT display with touch panel,
- VS1053 stereo audio codec with headphone jack,
- SD card slot,
- Serial FLASH memory,
- USB OTG FS with micro-AB connector, and
- Battery connect and batter charger circuit.
See the http://www.mikroe.com/mikromedia/stm32-m4/ for more information
about this board.
Contents Contents
======== ========
+66 -16
View File
@@ -128,9 +128,14 @@
# define CONFIG_EXAMPLES_SMART_NEBLOCKS (22) # define CONFIG_EXAMPLES_SMART_NEBLOCKS (22)
# endif # endif
# undef CONFIG_EXAMPLES_SMART_BUFSIZE #ifdef CONFIG_MIKROE_RAMMTD
# define CONFIG_EXAMPLES_SMART_BUFSIZE \ # ifndef CONFIG_MIKROE_RAMMTD_MINOR
(CONFIG_RAMMTD_ERASESIZE * CONFIG_EXAMPLES_SMART_NEBLOCKS) # define CONFIG_MIKROE_RAMMTD_MINOR 1
# endif
# ifndef CONFIG_MIKROE_RAMMTD_SIZE
# define CONFIG_MIKROE_RAMMTD_SIZE 32
# endif
#endif
/* Debug ********************************************************************/ /* Debug ********************************************************************/
@@ -151,11 +156,6 @@
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
/* Pre-allocated simulated flash */
#ifdef CONFIG_RAMMTD
//static uint8_t g_simflash[CONFIG_EXAMPLES_SMART_BUFSIZE];
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
@@ -197,7 +197,7 @@ int nsh_archinitialize(void)
/* Now bind the SPI interface to the M25P8 SPI FLASH driver */ /* Now bind the SPI interface to the M25P8 SPI FLASH driver */
#ifdef CONFIG_MTD #if defined(CONFIG_MTD) && defined(CONFIG_MIKROE_FLASH)
message("nsh_archinitialize: Bind SPI to the SPI flash driver\n"); message("nsh_archinitialize: Bind SPI to the SPI flash driver\n");
mtd = m25p_initialize(spi); mtd = m25p_initialize(spi);
if (!mtd) if (!mtd)
@@ -208,28 +208,78 @@ int nsh_archinitialize(void)
{ {
message("nsh_archinitialize: Successfully bound SPI port 3 to the SPI FLASH driver\n"); message("nsh_archinitialize: Successfully bound SPI port 3 to the SPI FLASH driver\n");
/* Now initialize a SMART Flash block device and bind it to the MTD device */ #ifdef CONFIG_MIKROE_FLASH_PART
{
int partno;
int partsize;
int partoffset;
const char *partstring = CONFIG_MIKROE_FLASH_PART_LIST;
const char *ptr;
FAR struct mtd_dev_s *mtd_part;
char partname[4];
/* Now create a partition on the FLASH device */
partno = 0;
ptr = partstring;
partoffset = 0;
while (*ptr != '\0')
{
/* Get the partition size */
partsize = atoi(ptr);
mtd_part = mtd_partition(mtd, partoffset, (partsize>>2)*16);
partoffset += (partsize >> 2) * 16;
/* Now initialize a SMART Flash block device and bind it to the MTD device */
#if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS) #if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS)
smart_initialize(0, mtd); sprintf(partname, "p%d", partno);
smart_initialize(CONFIG_MIKROE_FLASH_MINOR, mtd_part, partname);
#endif #endif
/* Update the pointer to point to the next size in the list */
while ((*ptr >= '0') && (*ptr <= '9'))
{
ptr++;
}
if (*ptr == ',')
{
ptr++;
}
/* Increment the part number */
partno++;
}
}
#else /* CONFIG_MIKROE_FLASH_PART */
/* Configure the device with no partition support */
smart_initialize(CONFIG_MIKROE_FLASH_MINOR, mtd, NULL);
#endif /* CONFIG_MIKROE_FLASH_PART */
} }
/* Create a RAM MTD device if configured */ /* Create a RAM MTD device if configured */
#ifdef CONFIG_RAMMTD #if defined(CONFIG_RAMMTD) && defined(CONFIG_MIKROE_RAMMTD)
{ {
uint8_t *start = (uint8_t *) kmalloc(CONFIG_EXAMPLES_SMART_BUFSIZE); uint8_t *start = (uint8_t *) kmalloc(CONFIG_MIKROE_RAMMTD_SIZE * 1024);
mtd = rammtd_initialize(start, CONFIG_EXAMPLES_SMART_BUFSIZE); mtd = rammtd_initialize(start, CONFIG_MIKROE_RAMMTD_SIZE * 1024);
mtd->ioctl(mtd, MTDIOC_BULKERASE, 0); mtd->ioctl(mtd, MTDIOC_BULKERASE, 0);
/* Now initialize a SMART Flash block device and bind it to the MTD device */ /* Now initialize a SMART Flash block device and bind it to the MTD device */
#if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS) #if defined(CONFIG_MTD_SMART) && defined(CONFIG_FS_SMARTFS)
smart_initialize(1, mtd); smart_initialize(CONFIG_MIKROE_RAMMTD_MINOR, mtd, NULL);
#endif #endif
} }
#endif /* CONFIG_RAMMTD */ #endif /* CONFIG_RAMMTD && CONFIG_MIKROE_RAMMTD */
#endif /* CONFIG_MTD */ #endif /* CONFIG_MTD */
#endif /* CONFIG_STM32_SPI3 */ #endif /* CONFIG_STM32_SPI3 */
+25 -42
View File
@@ -16,7 +16,7 @@ CONFIG_HOST_LINUX=y
# #
# Build Configuration # Build Configuration
# #
# CONFIG_APPS_DIR="../apps" CONFIG_APPS_DIR="../apps"
# CONFIG_BUILD_2PASS is not set # CONFIG_BUILD_2PASS is not set
# #
@@ -38,27 +38,8 @@ CONFIG_RAW_BINARY=y
# #
# Debug Options # Debug Options
# #
CONFIG_DEBUG=y # CONFIG_DEBUG is not set
# CONFIG_DEBUG_VERBOSE is not set # CONFIG_DEBUG_SYMBOLS is not set
#
# Subsystem Debug Options
#
# CONFIG_DEBUG_MM is not set
# CONFIG_DEBUG_SCHED is not set
# CONFIG_DEBUG_USB is not set
CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_LIB is not set
# CONFIG_DEBUG_BINFMT is not set
# CONFIG_DEBUG_GRAPHICS is not set
#
# Driver Debug Options
#
# CONFIG_DEBUG_ANALOG is not set
# CONFIG_DEBUG_SPI is not set
# CONFIG_DEBUG_GPIO is not set
CONFIG_DEBUG_SYMBOLS=y
# #
# System Type # System Type
@@ -104,7 +85,6 @@ CONFIG_ARCH_HAVE_CMNVECTOR=y
# CONFIG_ARCH_FPU is not set # CONFIG_ARCH_FPU is not set
CONFIG_ARCH_HAVE_MPU=y CONFIG_ARCH_HAVE_MPU=y
# CONFIG_ARMV7M_MPU is not set # CONFIG_ARMV7M_MPU is not set
# CONFIG_DEBUG_HARDFAULT is not set
# #
# ARMV7M Configuration Options # ARMV7M Configuration Options
@@ -310,6 +290,13 @@ CONFIG_NSH_MMCSDSPIPORTNO=0
# #
# Board-Specific Options # Board-Specific Options
# #
CONFIG_MIKROE_FLASH=y
CONFIG_MIKROE_FLASH_MINOR=0
CONFIG_MIKROE_FLASH_PART=y
CONFIG_MIKROE_FLASH_PART_LIST="256,768"
CONFIG_MIKROE_RAMMTD=y
CONFIG_MIKROE_RAMMTD_MINOR=1
CONFIG_MIKROE_RAMMTD_SIZE=32
# #
# RTOS Features # RTOS Features
@@ -408,21 +395,27 @@ CONFIG_MMCSD_SPI=y
CONFIG_MMCSD_SPICLOCK=20000000 CONFIG_MMCSD_SPICLOCK=20000000
# CONFIG_MMCSD_SDIO is not set # CONFIG_MMCSD_SDIO is not set
CONFIG_MTD=y CONFIG_MTD=y
# CONFIG_MTD_PARTITION is not set
#
# MTD Configuration
#
CONFIG_MTD_PARTITION=y
CONFIG_MTD_BYTE_WRITE=y
#
# MTD Device Drivers
#
CONFIG_RAMMTD=y CONFIG_RAMMTD=y
CONFIG_RAMMTD_BLOCKSIZE=512 CONFIG_RAMMTD_BLOCKSIZE=512
CONFIG_RAMMTD_ERASESIZE=4096 CONFIG_RAMMTD_ERASESIZE=4096
CONFIG_RAMMTD_ERASESTATE=0xff CONFIG_RAMMTD_ERASESTATE=0xff
# CONFIG_RAMMTD_FLASHSIM is not set # CONFIG_RAMMTD_FLASHSIM is not set
CONFIG_RAMMTD_SMART=y
# CONFIG_MTD_AT24XX is not set # CONFIG_MTD_AT24XX is not set
# CONFIG_MTD_AT45DB is not set # CONFIG_MTD_AT45DB is not set
CONFIG_MTD_M25P=y CONFIG_MTD_M25P=y
CONFIG_M25P_SPIMODE=0 CONFIG_M25P_SPIMODE=0
CONFIG_M25P_MANUFACTURER=0x1C CONFIG_M25P_MANUFACTURER=0x1C
CONFIG_M25P_MEMORY_TYPE=0x31 CONFIG_M25P_MEMORY_TYPE=0x31
CONFIG_M25P_SUBSECTOR_ERASE=y
CONFIG_M25P_BYTEWRITE=y
CONFIG_MTD_SMART=y CONFIG_MTD_SMART=y
CONFIG_MTD_SMART_SECTOR_SIZE=512 CONFIG_MTD_SMART_SECTOR_SIZE=512
# CONFIG_MTD_RAMTRON is not set # CONFIG_MTD_RAMTRON is not set
@@ -441,7 +434,6 @@ CONFIG_SERIAL_REMOVABLE=y
CONFIG_ARCH_HAVE_USART2=y CONFIG_ARCH_HAVE_USART2=y
CONFIG_MCU_SERIAL=y CONFIG_MCU_SERIAL=y
CONFIG_STANDARD_SERIAL=y CONFIG_STANDARD_SERIAL=y
# CONFIG_SERIAL_TIOCSERGSTRUCT is not set
# CONFIG_USART2_SERIAL_CONSOLE is not set # CONFIG_USART2_SERIAL_CONSOLE is not set
CONFIG_NO_SERIAL_CONSOLE=y CONFIG_NO_SERIAL_CONSOLE=y
@@ -529,7 +521,7 @@ CONFIG_FS_ROMFS=y
CONFIG_FS_SMARTFS=y CONFIG_FS_SMARTFS=y
CONFIG_SMARTFS_ERASEDSTATE=0xff CONFIG_SMARTFS_ERASEDSTATE=0xff
CONFIG_SMARTFS_MAXNAMLEN=16 CONFIG_SMARTFS_MAXNAMLEN=16
CONFIG_SMARTFS_MULTI_ROOT_DIRS=y # CONFIG_SMARTFS_MULTI_ROOT_DIRS is not set
# CONFIG_FS_BINFS is not set # CONFIG_FS_BINFS is not set
# #
@@ -650,6 +642,7 @@ CONFIG_EXAMPLES_NSH=y
# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NX is not set
# CONFIG_EXAMPLES_NXCONSOLE is not set # CONFIG_EXAMPLES_NXCONSOLE is not set
# CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXFFS is not set
# CONFIG_EXAMPLES_SMART is not set
# CONFIG_EXAMPLES_NXFLAT is not set # CONFIG_EXAMPLES_NXFLAT is not set
# CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXHELLO is not set
# CONFIG_EXAMPLES_NXIMAGE is not set # CONFIG_EXAMPLES_NXIMAGE is not set
@@ -664,8 +657,8 @@ CONFIG_EXAMPLES_NSH=y
# CONFIG_EXAMPLES_ROMFS is not set # CONFIG_EXAMPLES_ROMFS is not set
# CONFIG_EXAMPLES_SENDMAIL is not set # CONFIG_EXAMPLES_SENDMAIL is not set
# CONFIG_EXAMPLES_SERLOOP is not set # CONFIG_EXAMPLES_SERLOOP is not set
CONFIG_EXAMPLES_FLASH_TEST=y # CONFIG_EXAMPLES_FLASH_TEST is not set
CONFIG_EXAMPLES_SMART_TEST=y # CONFIG_EXAMPLES_SMART_TEST is not set
# CONFIG_EXAMPLES_TELNETD is not set # CONFIG_EXAMPLES_TELNETD is not set
# CONFIG_EXAMPLES_THTTPD is not set # CONFIG_EXAMPLES_THTTPD is not set
# CONFIG_EXAMPLES_TIFF is not set # CONFIG_EXAMPLES_TIFF is not set
@@ -774,23 +767,13 @@ CONFIG_NSH_LINELEN=64
CONFIG_NSH_NESTDEPTH=3 CONFIG_NSH_NESTDEPTH=3
# CONFIG_NSH_DISABLESCRIPT is not set # CONFIG_NSH_DISABLESCRIPT is not set
# CONFIG_NSH_DISABLEBG is not set # CONFIG_NSH_DISABLEBG is not set
CONFIG_NSH_ROMFSETC=y # CONFIG_NSH_ROMFSETC is not set
# CONFIG_NSH_ROMFSRC is not set
CONFIG_NSH_ROMFSMOUNTPT="/etc"
CONFIG_NSH_INITSCRIPT="init.d/rcS"
CONFIG_NSH_ROMFSDEVNO=0
CONFIG_NSH_ROMFSSECTSIZE=64
CONFIG_NSH_FATDEVNO=0
CONFIG_NSH_FATSECTSIZE=512
CONFIG_NSH_FATNSECTORS=1024
CONFIG_NSH_FATMOUNTPT="/tmp"
CONFIG_NSH_CONSOLE=y CONFIG_NSH_CONSOLE=y
# CONFIG_NSH_USBCONSOLE is not set # CONFIG_NSH_USBCONSOLE is not set
# #
# USB Trace Support # USB Trace Support
# #
# CONFIG_NSH_USBDEV_TRACE is not set
# CONFIG_NSH_CONDEV is not set # CONFIG_NSH_CONDEV is not set
CONFIG_NSH_ARCHINIT=y CONFIG_NSH_ARCHINIT=y
+14 -1
View File
@@ -2,7 +2,20 @@ README
====== ======
This README discusses issues unique to NuttX configurations for the This README discusses issues unique to NuttX configurations for the
STMicro STM32F4Discovery development board. STMicro STM32F4Discovery development board featuring the STM32F407VGT6
MCU. The STM32F407VGT6 is a 168MHz Cortex-M4 operation with 1Mbit Flash
memory and 128kbytes. The board features:
- On-board ST-LINK/V2 for programming and debugging,
- LIS302DL, ST MEMS motion sensor, 3-axis digital output accelerometer,
- MP45DT02, ST MEMS audio sensor, omni-directional digital microphone,
- CS43L22, audio DAC with integrated class D speaker driver,
- Eight LEDs and two push-buttons,
- USB OTG FS with micro-AB connector, and
- Easy access to most MCU pins.
Refer to http://www.st.com/internet/evalboard/product/252419.jsp for
further information about this board.
Contents Contents
======== ========
+2 -25
View File
@@ -64,13 +64,6 @@ config RAMMTD_FLASHSIM
RAMMTD_FLASHSIM will add some extra logic to improve the level of RAMMTD_FLASHSIM will add some extra logic to improve the level of
FLASH simulation. FLASH simulation.
config RAMMTD_SMART
bool "SMART block driver support in the RAM MTD driver"
default n
---help---
Builds in additional ioctl and interface code to support the
SMART block driver / filesystem.
endif endif
config MTD_AT24XX config MTD_AT24XX
@@ -139,30 +132,14 @@ config M25P_MEMORY_TYPE
---help--- ---help---
The memory type for M25 "P" series is 0x20, but the driver also supports "F" series The memory type for M25 "P" series is 0x20, but the driver also supports "F" series
devices, such as the EON EN25F80 part which adds a 4K sector erase capability. The devices, such as the EON EN25F80 part which adds a 4K sector erase capability. The
ID for "F" series parts from EON is 0x31. memory type for "F" series parts from EON is 0x31. The 4K sector erase size will
automatically be enabled when filessytems that can use it are enabled, such as SMART.
config M25P_SUBSECTOR_ERASE
bool "Sub-Sector Erase"
default n
---help---
Some devices (such as the EON EN25F80) support a smaller erase block
size (4K vs 64K). This option enables support for sub-sector erase.
The SMART file system can take advantage of this option if it is enabled.
config M25P_BYTEWRITE
bool "Enable ByteWrite ioctl support"
default n
---help---
The M25P series of devices allow writing to a page with less than a full-page
size of data. In this case, only the written bytes are updated without affecting
the other bytes in the page. The SMART FS requires this option for proper operation.
endif endif
config MTD_SMART config MTD_SMART
bool "Sector Mapped Allocation for Really Tiny (SMART) Flash support" bool "Sector Mapped Allocation for Really Tiny (SMART) Flash support"
default y default y
select M25P_BYTEWRITE
---help--- ---help---
The MP25x series of Flash devices are typically very small and have a very large The MP25x series of Flash devices are typically very small and have a very large
erase block size. This causes issues with the standard Flash Translation Layer erase block size. This causes issues with the standard Flash Translation Layer
+167 -165
View File
@@ -3,7 +3,7 @@
* Driver for SPI-based M25P1 (128Kbit), M25P64 (32Mbit), M25P64 (64Mbit), and * Driver for SPI-based M25P1 (128Kbit), M25P64 (32Mbit), M25P64 (64Mbit), and
* M25P128 (128Mbit) FLASH (and compatible). * M25P128 (128Mbit) FLASH (and compatible).
* *
* Copyright (C) 2009-2011 Gregory Nutt. All rights reserved. * Copyright (C) 2009-2011, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -114,6 +114,7 @@
#define M25P_EN25F80_PAGE_SHIFT 8 /* Page size 1 << 8 = 256 */ #define M25P_EN25F80_PAGE_SHIFT 8 /* Page size 1 << 8 = 256 */
#define M25P_EN25F80_NPAGES 4096 #define M25P_EN25F80_NPAGES 4096
#define M25P_EN25F80_SUBSECT_SHIFT 12 /* Sub-Sector size 1 << 12 = 4,096 */ #define M25P_EN25F80_SUBSECT_SHIFT 12 /* Sub-Sector size 1 << 12 = 4,096 */
#define M25P_EN25F80_NSUBSECTORS 256
/* M25P32 capacity is 4,194,304 bytes: /* M25P32 capacity is 4,194,304 bytes:
* (64 sectors) * (65,536 bytes per sector) * (64 sectors) * (65,536 bytes per sector)
@@ -203,7 +204,7 @@ struct m25p_dev_s
uint8_t pageshift; /* 8 */ uint8_t pageshift; /* 8 */
uint16_t nsectors; /* 128 or 64 */ uint16_t nsectors; /* 128 or 64 */
uint32_t npages; /* 32,768 or 65,536 */ uint32_t npages; /* 32,768 or 65,536 */
#ifdef CONFIG_M25P_SUBSECTOR_ERASE #ifdef CONFIG_MTD_SMART
uint8_t subsectorshift; /* 0, 12 or 13 (4K or 8K) */ uint8_t subsectorshift; /* 0, 12 or 13 (4K or 8K) */
#endif #endif
}; };
@@ -219,13 +220,10 @@ static inline void m25p_unlock(FAR struct spi_dev_s *dev);
static inline int m25p_readid(struct m25p_dev_s *priv); static inline int m25p_readid(struct m25p_dev_s *priv);
static void m25p_waitwritecomplete(struct m25p_dev_s *priv); static void m25p_waitwritecomplete(struct m25p_dev_s *priv);
static void m25p_writeenable(struct m25p_dev_s *priv); static void m25p_writeenable(struct m25p_dev_s *priv);
static inline void m25p_sectorerase(struct m25p_dev_s *priv, off_t offset); static inline void m25p_sectorerase(struct m25p_dev_s *priv, off_t offset, uint8_t type);
static inline int m25p_bulkerase(struct m25p_dev_s *priv); static inline int m25p_bulkerase(struct m25p_dev_s *priv);
static inline void m25p_pagewrite(struct m25p_dev_s *priv, FAR const uint8_t *buffer, static inline void m25p_pagewrite(struct m25p_dev_s *priv, FAR const uint8_t *buffer,
off_t offset); off_t offset);
#ifdef CONFIG_M25P_SUBSECTOR_ERASE
static inline void m25p_subsectorerase(struct m25p_dev_s *priv, off_t offset);
#endif
/* MTD driver methods */ /* MTD driver methods */
@@ -236,6 +234,10 @@ static ssize_t m25p_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, FAR const uint8_t *buf); size_t nblocks, FAR const uint8_t *buf);
static ssize_t m25p_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t m25p_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
FAR uint8_t *buffer); FAR uint8_t *buffer);
#ifdef CONFIG_MTD_BYTE_WRITE
static ssize_t m25p_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
FAR const uint8_t *buffer);
#endif
static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
/************************************************************************************ /************************************************************************************
@@ -320,7 +322,7 @@ static inline int m25p_readid(struct m25p_dev_s *priv)
{ {
/* Okay.. is it a FLASH capacity that we understand? */ /* Okay.. is it a FLASH capacity that we understand? */
#ifdef CONFIG_M25P_SUBSECTOR_ERASE #ifdef CONFIG_MTD_SMART
priv->subsectorshift = 0; priv->subsectorshift = 0;
#endif #endif
@@ -338,11 +340,11 @@ static inline int m25p_readid(struct m25p_dev_s *priv)
{ {
/* Save the FLASH geometry */ /* Save the FLASH geometry */
priv->sectorshift = M25P_EN25F80_SECTOR_SHIFT;
priv->nsectors = M25P_EN25F80_NSECTORS;
priv->pageshift = M25P_EN25F80_PAGE_SHIFT; priv->pageshift = M25P_EN25F80_PAGE_SHIFT;
priv->npages = M25P_EN25F80_NPAGES; priv->npages = M25P_EN25F80_NPAGES;
#ifdef CONFIG_M25P_SUBSECTOR_ERASE priv->sectorshift = M25P_EN25F80_SECTOR_SHIFT;
priv->nsectors = M25P_EN25F80_NSECTORS;
#ifdef CONFIG_MTD_SMART
priv->subsectorshift = M25P_EN25F80_SUBSECT_SHIFT; priv->subsectorshift = M25P_EN25F80_SUBSECT_SHIFT;
#endif #endif
return OK; return OK;
@@ -480,9 +482,20 @@ static void m25p_writeenable(struct m25p_dev_s *priv)
* Name: m25p_sectorerase * Name: m25p_sectorerase
************************************************************************************/ ************************************************************************************/
static inline void m25p_sectorerase(struct m25p_dev_s *priv, off_t sector) static void m25p_sectorerase(struct m25p_dev_s *priv, off_t sector, uint8_t type)
{ {
off_t offset = sector << priv->sectorshift; off_t offset;
#ifdef CONFIG_MTD_SMART
if (priv->subsectorshift > 0)
{
offset = sector << priv->subsectorshift;
}
else
#endif
{
offset = sector << priv->sectorshift;
}
fvdbg("sector: %08lx\n", (long)sector); fvdbg("sector: %08lx\n", (long)sector);
@@ -502,9 +515,11 @@ static inline void m25p_sectorerase(struct m25p_dev_s *priv, off_t sector)
SPI_SELECT(priv->dev, SPIDEV_FLASH, true); SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
/* Send the "Sector Erase (SE)" instruction */ /* Send the "Sector Erase (SE)" or Sub-Sector Erase (SSE) instruction
* that was passed in as the erase type.
*/
(void)SPI_SEND(priv->dev, M25P_SE); (void)SPI_SEND(priv->dev, type);
/* Send the sector offset high byte first. For all of the supported /* Send the sector offset high byte first. For all of the supported
* parts, the sector number is completely contained in the first byte * parts, the sector number is completely contained in the first byte
@@ -521,53 +536,6 @@ static inline void m25p_sectorerase(struct m25p_dev_s *priv, off_t sector)
fvdbg("Erased\n"); fvdbg("Erased\n");
} }
/************************************************************************************
* Name: m25p_subsectorerase
************************************************************************************/
#ifdef CONFIG_M25P_SUBSECTOR_ERASE
static inline void m25p_subsectorerase(struct m25p_dev_s *priv, off_t subsector)
{
off_t offset = subsector << priv->subsectorshift;
fvdbg("subsector: %9lx\n", (long)subsector);
/* Wait for any preceding write to complete. We could simplify things by
* perform this wait at the end of each write operation (rather than at
* the beginning of ALL operations), but have the wait first will slightly
* improve performance.
*/
m25p_waitwritecomplete(priv);
/* Send write enable instruction */
m25p_writeenable(priv);
/* Select this FLASH part */
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
/* Send the "Sub-Sector Erase (SSE)" instruction */
(void)SPI_SEND(priv->dev, M25P_SSE);
/* Send the sector offset high byte first. For all of the supported
* parts, the sector number is completely contained in the first byte
* and the values used in the following two bytes don't really matter.
*/
(void)SPI_SEND(priv->dev, (offset >> 16) & 0xff);
(void)SPI_SEND(priv->dev, (offset >> 8) & 0xff);
(void)SPI_SEND(priv->dev, offset & 0xff);
/* Deselect the FLASH */
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
fvdbg("Erased\n");
}
#endif
/************************************************************************************ /************************************************************************************
* Name: m25p_bulkerase * Name: m25p_bulkerase
************************************************************************************/ ************************************************************************************/
@@ -654,7 +622,7 @@ static inline void m25p_pagewrite(struct m25p_dev_s *priv, FAR const uint8_t *bu
* Name: m25p_bytewrite * Name: m25p_bytewrite
************************************************************************************/ ************************************************************************************/
#ifdef CONFIG_M25P_BYTEWRITE #ifdef CONFIG_MTD_BYTE_WRITE
static inline void m25p_bytewrite(struct m25p_dev_s *priv, FAR const uint8_t *buffer, static inline void m25p_bytewrite(struct m25p_dev_s *priv, FAR const uint8_t *buffer,
off_t offset, uint16_t count) off_t offset, uint16_t count)
{ {
@@ -711,13 +679,55 @@ static int m25p_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblock
/* Lock access to the SPI bus until we complete the erase */ /* Lock access to the SPI bus until we complete the erase */
m25p_lock(priv->dev); m25p_lock(priv->dev);
while (blocksleft-- > 0) while (blocksleft > 0)
{ {
/* Erase each sector */ #ifdef CONFIG_MTD_SMART
size_t sectorboundry;
size_t blkper;
m25p_sectorerase(priv, startblock); /* If we have a smaller erase size, then we will find as many full
* sector erase blocks as possible to speed up the process instead of
* erasing everything in smaller chunks.
*/
if (priv->subsectorshift > 0)
{
blkper = 1 << (priv->sectorshift - priv->subsectorshift);
sectorboundry = (startblock + blkper - 1) / blkper;
sectorboundry *= blkper;
/* If we are on a sector boundry and have at least a full sector
* of blocks left to erase, then we can do a full sector erase.
*/
if (startblock == sectorboundry && blocksleft >= blkper)
{
/* Do a full sector erase */
m25p_sectorerase(priv, startblock / blkper, M25P_SE);
startblock += blkper;
blocksleft -= blkper;
continue;
}
else
{
/* Just do a sub-sector erase */
m25p_sectorerase(priv, startblock, M25P_SSE);
startblock++;
blocksleft--;
continue;
}
}
#endif
/* Not using sub-sector erase. Erase each full sector */
m25p_sectorerase(priv, startblock, M25P_SE);
startblock++; startblock++;
blocksleft--;
} }
m25p_unlock(priv->dev); m25p_unlock(priv->dev);
return (int)nblocks; return (int)nblocks;
} }
@@ -741,6 +751,7 @@ static ssize_t m25p_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nb
{ {
return nbytes >> priv->pageshift; return nbytes >> priv->pageshift;
} }
return (int)nbytes; return (int)nbytes;
} }
@@ -766,8 +777,8 @@ static ssize_t m25p_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t n
buffer += pagesize; buffer += pagesize;
startblock++; startblock++;
} }
m25p_unlock(priv->dev);
m25p_unlock(priv->dev);
return nblocks; return nblocks;
} }
@@ -817,6 +828,78 @@ static ssize_t m25p_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
return nbytes; return nbytes;
} }
/************************************************************************************
* Name: m25p_write
************************************************************************************/
#ifdef CONFIG_MTD_BYTE_WRITE
static ssize_t m25p_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
FAR const uint8_t *buffer)
{
FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev;
int startpage;
int endpage;
int count;
int index;
int pagesize;
int bytestowrite;
fvdbg("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
/* We must test if the offset + count crosses one or more pages
* and perform individual writes. The devices can only write in
* page increments.
*/
startpage = offset / (1 << priv->pageshift);
endpage = (offset + nbytes) / (1 << priv->pageshift);
if (startpage == endpage)
{
/* All bytes within one programmable page. Just do the write. */
m25p_bytewrite(priv, buffer, offset, nbytes);
}
else
{
/* Write the 1st partial-page */
count = nbytes;
pagesize = (1 << priv->pageshift);
bytestowrite = pagesize - (offset & (pagesize-1));
m25p_bytewrite(priv, buffer, offset, bytestowrite);
/* Update offset and count */
offset += bytestowrite;
count -= bytestowrite;
index = bytestowrite;
/* Write full pages */
while (count >= pagesize)
{
m25p_bytewrite(priv, &buffer[index], offset, pagesize);
/* Update offset and count */
offset += pagesize;
count -= pagesize;
index += pagesize;
}
/* Now write any partial page at the end */
if (count > 0)
{
m25p_bytewrite(priv, &buffer[index], offset, count);
}
}
return nbytes;
}
#endif /* CONFIG_MTD_BYTE_WRITE */
/************************************************************************************ /************************************************************************************
* Name: m25p_ioctl * Name: m25p_ioctl
************************************************************************************/ ************************************************************************************/
@@ -844,15 +927,22 @@ static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
* appear so. * appear so.
*/ */
geo->blocksize = (1 << priv->pageshift); geo->blocksize = (1 << priv->pageshift);
geo->erasesize = (1 << priv->sectorshift); #ifdef CONFIG_MTD_SMART
geo->neraseblocks = priv->nsectors; if (priv->subsectorshift > 0)
#ifdef CONFIG_M25P_SUBSECTOR_ERASE {
geo->subsectorsize = (1 << priv->subsectorshift); geo->erasesize = (1 << priv->subsectorshift);
geo->nsubsectors = priv->nsectors * (1 << (priv->sectorshift - geo->neraseblocks = priv->nsectors * (1 << (priv->sectorshift -
priv->subsectorshift)); priv->subsectorshift));
}
else
#endif #endif
ret = OK; {
geo->erasesize = (1 << priv->sectorshift);
geo->neraseblocks = priv->nsectors;
}
ret = OK;
fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n", fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n",
geo->blocksize, geo->erasesize, geo->neraseblocks); geo->blocksize, geo->erasesize, geo->neraseblocks);
@@ -870,97 +960,6 @@ static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
} }
break; break;
#ifdef CONFIG_FS_SMARTFS
case MTDIOC_GETCAPS:
{
ret = 0;
#ifdef CONFIG_M25P_BYTEWRITE
ret |= MTDIOC_CAPS_BYTEWRITE;
#endif
#ifdef CONFIG_M25P_SUBSECTOR_ERASE
ret |= MTDIOC_CAPS_SECTERASE;
#endif
break;
}
#endif /* CONFIG_FS_SMARTFS */
#ifdef CONFIG_M25P_SUBSECTOR_ERASE
case MTDIOC_SECTERASE:
{
m25p_subsectorerase(priv, (off_t) arg);
ret = OK;
break;
}
#endif
#ifdef CONFIG_M25P_BYTEWRITE
case MTDIOC_BYTEWRITE:
{
struct mtd_byte_write_s *bytewrite = (struct mtd_byte_write_s *) arg;
int startpage;
int endpage;
int count;
int index;
int pagesize;
int bytestowrite;
size_t offset;
/* We must test if the offset + count crosses one or more pages
* and perform individual writes. The devices can only write in
* page increments.
*/
startpage = bytewrite->offset / (1 << priv->pageshift);
endpage = (bytewrite->offset + bytewrite->count) / (1 << priv->pageshift);
if (startpage == endpage)
{
m25p_bytewrite(priv, bytewrite->buffer, bytewrite->offset,
bytewrite->count);
}
else
{
/* Write the 1st partial-page */
count = bytewrite->count;
pagesize = (1 << priv->pageshift);
offset = bytewrite->offset;
bytestowrite = pagesize - (bytewrite->offset & (pagesize-1));
m25p_bytewrite(priv, bytewrite->buffer, offset, bytestowrite);
/* Update offset and count */
offset += bytestowrite;
count -= bytestowrite;
index = bytestowrite;
/* Write full pages */
while (count >= pagesize)
{
m25p_bytewrite(priv, &bytewrite->buffer[index], offset, pagesize);
/* Update offset and count */
offset += pagesize;
count -= pagesize;
index += pagesize;
}
/* Now write any partial page at the end */
if (count > 0)
{
m25p_bytewrite(priv, &bytewrite->buffer[index], offset, count);
}
}
ret = OK;
break;
}
#endif
case MTDIOC_XIPBASE: case MTDIOC_XIPBASE:
default: default:
ret = -ENOTTY; /* Bad command */ ret = -ENOTTY; /* Bad command */
@@ -1010,6 +1009,9 @@ FAR struct mtd_dev_s *m25p_initialize(FAR struct spi_dev_s *dev)
priv->mtd.bread = m25p_bread; priv->mtd.bread = m25p_bread;
priv->mtd.bwrite = m25p_bwrite; priv->mtd.bwrite = m25p_bwrite;
priv->mtd.read = m25p_read; priv->mtd.read = m25p_read;
#ifdef CONFIG_MTD_BYTE_WRITE
priv->mtd.write = m25p_write;
#endif
priv->mtd.ioctl = m25p_ioctl; priv->mtd.ioctl = m25p_ioctl;
priv->dev = dev; priv->dev = dev;
+10 -1
View File
@@ -137,7 +137,7 @@ static bool part_bytecheck(FAR struct mtd_partition_s *priv, off_t byoff)
erasesize = priv->blocksize * priv->blkpererase; erasesize = priv->blocksize * priv->blkpererase;
readend = (byoff + erasesize - 1) / erasesize; readend = (byoff + erasesize - 1) / erasesize;
return readend < priv->neraseblocks; return readend <= priv->neraseblocks;
} }
/**************************************************************************** /****************************************************************************
@@ -410,6 +410,12 @@ static int part_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
* sector count (where the size of a sector is provided the by parent MTD * sector count (where the size of a sector is provided the by parent MTD
* driver). * driver).
* *
* NOTE: Since there may be a number of MTD partition drivers operating on
* the same, underlying FLASH driver, that FLASH driver must be capable
* of enforcing mutually exclusive access to the FLASH device. Without
* partitions, that mutual exclusion would be provided by the file system
* above the FLASH driver.
*
****************************************************************************/ ****************************************************************************/
FAR struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd, off_t firstblock, FAR struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd, off_t firstblock,
@@ -483,6 +489,9 @@ FAR struct mtd_dev_s *mtd_partition(FAR struct mtd_dev_s *mtd, off_t firstblock,
part->child.bwrite = part_bwrite; part->child.bwrite = part_bwrite;
part->child.read = mtd->read ? part_read : NULL; part->child.read = mtd->read ? part_read : NULL;
part->child.ioctl = part_ioctl; part->child.ioctl = part_ioctl;
#ifdef CONFIG_MTD_BYTE_WRITE
part->child.write = mtd->write ? part_write : NULL;
#endif
part->parent = mtd; part->parent = mtd;
part->firstblock = erasestart * blkpererase; part->firstblock = erasestart * blkpererase;
+35 -20
View File
@@ -228,7 +228,7 @@ static int ram_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks
* Name: ram_readbytes * Name: ram_readbytes
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_RAMMTD_SMART #ifdef CONFIG_MTD_SMART
static ssize_t ram_read_bytes(FAR struct mtd_dev_s *dev, off_t offset, static ssize_t ram_read_bytes(FAR struct mtd_dev_s *dev, off_t offset,
size_t nbytes, FAR uint8_t *buf) size_t nbytes, FAR uint8_t *buf)
{ {
@@ -328,6 +328,34 @@ static ssize_t ram_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
return nblocks; return nblocks;
} }
/****************************************************************************
* Name: ram_bytewrite
****************************************************************************/
#ifdef CONFIG_MTD_BYTE_WRITE
static ssize_t ram_bytewrite(FAR struct mtd_dev_s *dev, off_t offset,
size_t nbytes, FAR const uint8_t *buf)
{
FAR struct ram_dev_s *priv = (FAR struct ram_dev_s *)dev;
off_t maxaddr;
DEBUGASSERT(dev && buf);
/* Don't let the write exceed the size of the ram buffer */
maxaddr = priv->nblocks * CONFIG_RAMMTD_ERASESIZE;
if (offset + nbytes > maxaddr)
{
return 0;
}
/* Then write the data to RAM */
ram_write(&priv->start[offset], buf, nbytes);
return nbytes;
}
#endif
/**************************************************************************** /****************************************************************************
* Name: ram_ioctl * Name: ram_ioctl
****************************************************************************/ ****************************************************************************/
@@ -380,24 +408,6 @@ static int ram_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
} }
break; break;
#ifdef CONFIG_RAMMTD_SMART
case MTDIOC_GETCAPS:
{
ret = MTDIOC_CAPS_BYTEWRITE;
break;
}
case MTDIOC_BYTEWRITE:
{
struct mtd_byte_write_s *bytewrite = (struct mtd_byte_write_s *) arg;
ram_write(&priv->start[bytewrite->offset], bytewrite->buffer,
bytewrite->count);
ret = OK;
break;
}
#endif
default: default:
ret = -ENOTTY; /* Bad command */ ret = -ENOTTY; /* Bad command */
break; break;
@@ -454,9 +464,14 @@ FAR struct mtd_dev_s *rammtd_initialize(FAR uint8_t *start, size_t size)
priv->mtd.bwrite = ram_bwrite; priv->mtd.bwrite = ram_bwrite;
priv->mtd.ioctl = ram_ioctl; priv->mtd.ioctl = ram_ioctl;
priv->mtd.erase = ram_erase; priv->mtd.erase = ram_erase;
#ifdef CONFIG_MTD_BYTE_WRITE
priv->mtd.write = ram_bytewrite;
#endif
#ifdef CONFIG_RAMMTD_SMART #ifdef CONFIG_MTD_SMART
priv->mtd.read = ram_read_bytes; priv->mtd.read = ram_read_bytes;
#else
priv->mtd.read = NULL;
#endif #endif
priv->start = start; priv->start = start;
+178 -135
View File
File diff suppressed because it is too large Load Diff
+4 -5
View File
@@ -389,6 +389,7 @@ static int smartfs_close(FAR struct file *filep)
/* Remove ourselves from the linked list */ /* Remove ourselves from the linked list */
nextfile = fs->fs_head; nextfile = fs->fs_head;
prevfile = nextfile;
while ((nextfile != sf) && (nextfile != NULL)) while ((nextfile != sf) && (nextfile != NULL))
{ {
/* Save the previous file pointer too */ /* Save the previous file pointer too */
@@ -577,7 +578,7 @@ static int smartfs_sync_internal(struct smartfs_mountpt_s *fs,
if (sf->byteswritten > 0) if (sf->byteswritten > 0)
{ {
fdbg("Syncing sector %d\n", sf->currsector); fvdbg("Syncing sector %d\n", sf->currsector);
/* Read the existing sector used bytes value */ /* Read the existing sector used bytes value */
@@ -880,6 +881,7 @@ static off_t smartfs_seek_internal(struct smartfs_mountpt_s *fs,
switch (whence) switch (whence)
{ {
case SEEK_SET: case SEEK_SET:
default:
newpos = offset; newpos = offset;
break; break;
@@ -1034,7 +1036,7 @@ static int smartfs_sync(FAR struct file *filep)
struct inode *inode; struct inode *inode;
struct smartfs_mountpt_s *fs; struct smartfs_mountpt_s *fs;
struct smartfs_ofile_s *sf; struct smartfs_ofile_s *sf;
int ret = OK; int ret;
/* Sanity checks */ /* Sanity checks */
@@ -1067,7 +1069,6 @@ static int smartfs_sync(FAR struct file *filep)
static int smartfs_dup(FAR const struct file *oldp, FAR struct file *newp) static int smartfs_dup(FAR const struct file *oldp, FAR struct file *newp)
{ {
FAR struct smart_mountpt_s *fs;
struct smartfs_ofile_s *sf; struct smartfs_ofile_s *sf;
fvdbg("Dup %p->%p\n", oldp, newp); fvdbg("Dup %p->%p\n", oldp, newp);
@@ -1080,10 +1081,8 @@ static int smartfs_dup(FAR const struct file *oldp, FAR struct file *newp)
/* Recover our private data from the struct file instance */ /* Recover our private data from the struct file instance */
fs = (struct smart_mountpt_s *)oldp->f_inode->i_private;
sf = oldp->f_priv; sf = oldp->f_priv;
DEBUGASSERT(fs != NULL);
DEBUGASSERT(sf != NULL); DEBUGASSERT(sf != NULL);
/* Just increment the reference count on the ofile */ /* Just increment the reference count on the ofile */
+13 -9
View File
@@ -502,6 +502,8 @@ int smartfs_finddirentry(struct smartfs_mountpt_s *fs,
/* Read the directory */ /* Read the directory */
offset = 0xFFFF;
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF #if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
while (dirsector != 0xFFFF) while (dirsector != 0xFFFF)
#else #else
@@ -549,7 +551,8 @@ int smartfs_finddirentry(struct smartfs_mountpt_s *fs,
/* Test if the name matches */ /* Test if the name matches */
if (strcmp(entry->name, fs->fs_workbuffer) == 0) if (strncmp(entry->name, fs->fs_workbuffer,
fs->fs_llformat.namesize) == 0)
{ {
/* We found it! If this is the last segment entry, /* We found it! If this is the last segment entry,
* then report the entry. If it isn't the last * then report the entry. If it isn't the last
@@ -571,10 +574,11 @@ int smartfs_finddirentry(struct smartfs_mountpt_s *fs,
direntry->dfirst = dirstack[depth]; direntry->dfirst = dirstack[depth];
if (direntry->name == NULL) if (direntry->name == NULL)
{ {
direntry->name = (char *) kmalloc(fs->fs_llformat.namesize); direntry->name = (char *) kmalloc(fs->fs_llformat.namesize+1);
} }
strcpy(direntry->name, entry->name); memset(direntry->name, 0, fs->fs_llformat.namesize + 1);
strncpy(direntry->name, entry->name, fs->fs_llformat.namesize);
direntry->datlen = 0; direntry->datlen = 0;
/* Scan the file's sectors to calculate the length and perform /* Scan the file's sectors to calculate the length and perform
@@ -734,7 +738,7 @@ int smartfs_createentry(struct smartfs_mountpt_s *fs,
/* Validate the name isn't too long */ /* Validate the name isn't too long */
if (strlen(filename) + 1 > fs->fs_llformat.namesize) if (strlen(filename) > fs->fs_llformat.namesize)
{ {
return -ENAMETOOLONG; return -ENAMETOOLONG;
} }
@@ -887,13 +891,13 @@ int smartfs_createentry(struct smartfs_mountpt_s *fs,
entry->firstsector = nextsector; entry->firstsector = nextsector;
entry->utc = 0; entry->utc = 0;
memset(entry->name, 0, fs->fs_llformat.namesize); memset(entry->name, 0, fs->fs_llformat.namesize);
strncpy(entry->name, filename, fs->fs_llformat.namesize-1); strncpy(entry->name, filename, fs->fs_llformat.namesize);
/* Now write the new entry to the parent directory sector */ /* Now write the new entry to the parent directory sector */
readwrite.logsector = psector; readwrite.logsector = psector;
readwrite.offset = offset; readwrite.offset = offset;
readwrite.count = sizeof(struct smartfs_entry_header_s) + fs->fs_llformat.namesize; readwrite.count = entrysize;
readwrite.buffer = (uint8_t *) &fs->fs_rwbuffer[offset]; readwrite.buffer = (uint8_t *) &fs->fs_rwbuffer[offset];
ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &readwrite); ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &readwrite);
if (ret < 0) if (ret < 0)
@@ -911,11 +915,11 @@ int smartfs_createentry(struct smartfs_mountpt_s *fs,
direntry->datlen = 0; direntry->datlen = 0;
if (direntry->name == NULL) if (direntry->name == NULL)
{ {
direntry->name = (FAR char *) kmalloc(fs->fs_llformat.namesize); direntry->name = (FAR char *) kmalloc(fs->fs_llformat.namesize+1);
} }
memset(direntry->name, 0, fs->fs_llformat.namesize); memset(direntry->name, 0, fs->fs_llformat.namesize+1);
strncpy(direntry->name, filename, fs->fs_llformat.namesize-1); strncpy(direntry->name, filename, fs->fs_llformat.namesize);
ret = OK; ret = OK;
-9
View File
@@ -193,15 +193,6 @@
* of device memory */ * of device memory */
#define MTDIOC_BULKERASE _MTDIOC(0x0003) /* IN: None #define MTDIOC_BULKERASE _MTDIOC(0x0003) /* IN: None
* OUT: None */ * OUT: None */
#define MTDIOC_GETCAPS _MTDIOC(0x0004) /* IN: None
* OUT: Capabilities flags */
#define MTDIOC_SECTERASE _MTDIOC(0x0005) /* IN: Sector number to erase
* OUT: None */
#define MTDIOC_BYTEWRITE _MTDIOC(0x0006) /* IN: Pointer to bytewrite structure
* OUT: None */
#define MTDIOC_CAPS_SECTERASE 0x01
#define MTDIOC_CAPS_BYTEWRITE 0x02
/* NuttX ARP driver ioctl definitions (see netinet/arp.h) *******************/ /* NuttX ARP driver ioctl definitions (see netinet/arp.h) *******************/
+6 -7
View File
@@ -83,10 +83,6 @@ struct mtd_geometry_s
uint16_t erasesize; /* Size of one erase blocks -- must be a multiple uint16_t erasesize; /* Size of one erase blocks -- must be a multiple
* of blocksize. */ * of blocksize. */
size_t neraseblocks; /* Number of erase blocks */ size_t neraseblocks; /* Number of erase blocks */
#ifdef CONFIG_MTD_SUBSECTOR_ERASE
uint16_t subsectorsize; /* Size of the sub-sector erase block */
uint16_t nsubsectors; /* Number of sub-sector erase blocks */
#endif
}; };
/* The following defines the information for writing bytes to a sector /* The following defines the information for writing bytes to a sector
@@ -179,8 +175,8 @@ extern "C"
* NOTE: Since there may be a number of MTD partition drivers operating on * NOTE: Since there may be a number of MTD partition drivers operating on
* the same, underlying FLASH driver, that FLASH driver must be capable * the same, underlying FLASH driver, that FLASH driver must be capable
* of enforcing mutually exclusive access to the FLASH device. Without * of enforcing mutually exclusive access to the FLASH device. Without
* paritions, that mutual exclusing would be provided by the file system * partitions, that mutual exclusion would be provided by the file system
* abover the FLASH driver. * above the FLASH driver.
* *
****************************************************************************/ ****************************************************************************/
@@ -213,10 +209,13 @@ int ftl_initialize(int minor, FAR struct mtd_dev_s *mtd);
* minor - The minor device number. The MTD block device will be * minor - The minor device number. The MTD block device will be
* registered as as /dev/mtdsmartN where N is the minor number. * registered as as /dev/mtdsmartN where N is the minor number.
* mtd - The MTD device that supports the FLASH interface. * mtd - The MTD device that supports the FLASH interface.
* partname - Optional partition name to append to dev entry, NULL if
* not supplied.
* *
****************************************************************************/ ****************************************************************************/
int smart_initialize(int minor, FAR struct mtd_dev_s *mtd); int smart_initialize(int minor, FAR struct mtd_dev_s *mtd,
FAR const char *partname);
/**************************************************************************** /****************************************************************************
* Name: flash_eraseall * Name: flash_eraseall
+2 -1
View File
@@ -2368,7 +2368,8 @@ static char *parse_kconfigfile(FILE *stream, const char *kconfigdir)
{ {
/* Set token to NULL to skip to the next line */ /* Set token to NULL to skip to the next line */
error("Unhandled token: %s\n", token); error("File %s/Kconfig Unhandled token: %s\n",
kconfigdir, token);
token = NULL; token = NULL;
} }
break; break;