From 121211f09647c64c8992248ea569750f659f6d22 Mon Sep 17 00:00:00 2001 From: Michael Jung Date: Tue, 1 May 2018 06:23:52 -0600 Subject: [PATCH] progmem interface: Discern r/w and erase page sizes. Introduce new up_progmem_erasesize architecture API to be able to communicate the read/write page size independently from erase page size. Implement up_progmem_erasesize for all architectures that already support progmem, assuming that for those architectures the sizes of both read/write and erase pages are identical. --- arch/arm/src/efm32/efm32_flash.c | 5 +++++ arch/arm/src/samv7/sam_progmem.c | 13 +++++++++++++ arch/arm/src/stm32/stm32_flash.c | 5 +++++ arch/arm/src/stm32l4/stm32l4_flash.c | 5 +++++ drivers/mtd/mtd_progmem.c | 19 ++++++++++++++++--- include/nuttx/progmem.h | 26 ++++++++++++++++++-------- 6 files changed, 62 insertions(+), 11 deletions(-) diff --git a/arch/arm/src/efm32/efm32_flash.c b/arch/arm/src/efm32/efm32_flash.c index d02f9d2fa53..9d2de108b68 100644 --- a/arch/arm/src/efm32/efm32_flash.c +++ b/arch/arm/src/efm32/efm32_flash.c @@ -577,6 +577,11 @@ size_t up_progmem_pagesize(size_t page) return 0; } +size_t up_progmem_erasesize(size_t page) +{ + return up_progmem_pagesize(page); +} + ssize_t up_progmem_getpage(size_t addr) { #if (EFM32_FLASH_BASE != 0) diff --git a/arch/arm/src/samv7/sam_progmem.c b/arch/arm/src/samv7/sam_progmem.c index 552c1ed609e..20fc0102543 100644 --- a/arch/arm/src/samv7/sam_progmem.c +++ b/arch/arm/src/samv7/sam_progmem.c @@ -409,6 +409,19 @@ size_t up_progmem_pagesize(size_t cluster) return SAMV7_CLUSTER_SIZE; } +/**************************************************************************** + * Name: up_progmem_erasesize + * + * Description: + * Return cluster size + * + ****************************************************************************/ + +size_t up_progmem_erasesize(size_t cluster) +{ + return SAMV7_CLUSTER_SIZE; +} + /**************************************************************************** * Name: up_progmem_getpage * diff --git a/arch/arm/src/stm32/stm32_flash.c b/arch/arm/src/stm32/stm32_flash.c index 6b90e6e53f7..67942672299 100644 --- a/arch/arm/src/stm32/stm32_flash.c +++ b/arch/arm/src/stm32/stm32_flash.c @@ -512,6 +512,11 @@ size_t up_progmem_pagesize(size_t page) return STM32_FLASH_PAGESIZE; } +size_t up_progmem_erasesize(size_t page) +{ + return STM32_FLASH_PAGESIZE; +} + ssize_t up_progmem_getpage(size_t addr) { if (addr >= STM32_FLASH_BASE) diff --git a/arch/arm/src/stm32l4/stm32l4_flash.c b/arch/arm/src/stm32l4/stm32l4_flash.c index c706b50d93d..487b4d50353 100644 --- a/arch/arm/src/stm32l4/stm32l4_flash.c +++ b/arch/arm/src/stm32l4/stm32l4_flash.c @@ -276,6 +276,11 @@ size_t up_progmem_pagesize(size_t page) return STM32L4_FLASH_PAGESIZE; } +size_t up_progmem_erasesize(size_t page) +{ + return STM32L4_FLASH_PAGESIZE; +} + ssize_t up_progmem_getpage(size_t addr) { if (addr >= STM32L4_FLASH_BASE) diff --git a/drivers/mtd/mtd_progmem.c b/drivers/mtd/mtd_progmem.c index d46bed5ac5b..da6958adcc2 100644 --- a/drivers/mtd/mtd_progmem.c +++ b/drivers/mtd/mtd_progmem.c @@ -69,7 +69,8 @@ struct progmem_dev_s /* Fields unique to the progmem MTD driver */ bool initialized; /* True: Already initialized */ - uint8_t blkshift; /* Log2 of the flash block size */ + uint8_t blkshift; /* Log2 of the flash read/write block size */ + uint8_t ersshift; /* Log2 of the flash erase block size */ }; /**************************************************************************** @@ -314,7 +315,7 @@ static int progmem_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) */ geo->blocksize = (1 << priv->blkshift); /* Size of one read/write block */ - geo->erasesize = (1 << priv->blkshift); /* Size of one erase block */ + geo->erasesize = (1 << priv->ersshift); /* Size of one erase block */ geo->neraseblocks = up_progmem_npages(); /* Number of erase blocks */ ret = OK; } @@ -374,6 +375,7 @@ FAR struct mtd_dev_s *progmem_initialize(void) { FAR struct progmem_dev_s *priv = (FAR struct progmem_dev_s *)&g_progmem; int32_t blkshift; + int32_t ersshift; /* Perform initialization if necessary */ @@ -386,7 +388,7 @@ FAR struct mtd_dev_s *progmem_initialize(void) size_t blocksize = up_progmem_pagesize(0); - /* Calculate Log2 of the flash block size */ + /* Calculate Log2 of the flash read/write block size */ blkshift = progmem_log2(blocksize); if (blkshift < 0) @@ -394,9 +396,20 @@ FAR struct mtd_dev_s *progmem_initialize(void) return NULL; } + /* Calculate Log2 of the flash erase block size */ + + blocksize = up_progmem_erasesize(0); + + ersshift = progmem_log2(blocksize); + if (ersshift < 0) + { + return NULL; + } + /* Save the configuration data */ g_progmem.blkshift = blkshift; + g_progmem.ersshift = ersshift; g_progmem.initialized = true; #ifdef CONFIG_MTD_REGISTRATION diff --git a/include/nuttx/progmem.h b/include/nuttx/progmem.h index 367f66af8ce..627567a7105 100644 --- a/include/nuttx/progmem.h +++ b/include/nuttx/progmem.h @@ -68,7 +68,7 @@ extern "C" * Name: up_progmem_npages * * Description: - * Return number of pages + * Return number of erase pages * ****************************************************************************/ @@ -78,7 +78,7 @@ size_t up_progmem_npages(void); * Name: up_progmem_isuniform * * Description: - * Is program memory uniform or page size differs? + * Is program memory uniform or erase page and read/write page size differs? * ****************************************************************************/ @@ -88,17 +88,27 @@ bool up_progmem_isuniform(void); * Name: up_progmem_pagesize * * Description: - * Return page size + * Return read/write page size * ****************************************************************************/ size_t up_progmem_pagesize(size_t page); +/**************************************************************************** + * Name: up_progmem_erasesize + * + * Description: + * Return erase page size. Must be a multiple of the read/write page size. + * + ****************************************************************************/ + +size_t up_progmem_erasesize(size_t page); + /**************************************************************************** * Name: up_progmem_getpage * * Description: - * Address to page conversion + * Address to read/write page conversion * * Input Parameters: * addr - Address with or without flash offset (absolute or aligned to page0) @@ -117,7 +127,7 @@ ssize_t up_progmem_getpage(size_t addr); * Name: up_progmem_getaddress * * Description: - * Page to address conversion + * Read/write page to address conversion * * Input Parameters: * page - page index @@ -133,10 +143,10 @@ size_t up_progmem_getaddress(size_t page); * Name: up_progmem_erasepage * * Description: - * Erase selected page. + * Erase selected erase page. * * Input Parameters: - * page - The page index to be erased. + * page - The erase page index to be erased. * * Returned Value: * Page size or negative value on error. The following errors are reported @@ -157,7 +167,7 @@ ssize_t up_progmem_erasepage(size_t page); * Name: up_progmem_ispageerased * * Description: - * Checks whether page is erased + * Checks whether erase page is erased * * Input Parameters: * page - The page index to be checked.