Page 3 of 5

Re: [NEWS] Introducing MFS

Posted: Thu Mar 07, 2019 5:11 pm
by Giovanni
Hi,

Small update about MFS, I added a "transactional mode".

Basically it allows to encapsulate multiple operations (write, erase, read) in a transaction then commit all of those atomically or roll-back everything.

If there is a power loss the whole transaction is undone on the next boot.

Now we need more flash drivers.

Giovanni

Re: [NEWS] Introducing MFS

Posted: Sun Apr 14, 2019 11:43 pm
by 0x3333
Is there a reference implementation of the flash driver? I'm working on the F1 driver, would be nice to have a reference to look. Thanks.

Re: [NEWS] Introducing MFS

Posted: Mon Apr 15, 2019 8:05 am
by Giovanni
There is a driver for L4 in trunk, see the other topic, you can use it as a template.

Giovanni

Re: [NEWS] Introducing MFS

Posted: Mon Apr 15, 2019 4:21 pm
by 0x3333
What is the expected behavior in function

Code: Select all

flash_error_t efl_lld_start_erase_all(void *instance)
when the device has only one bank?

There is a note in the function;

Code: Select all

This function only erases bank 2 if it is present. Bank 1 is not
touched because it is where the program is running on.\
Pages on bank 1 can be individually erased.


Should I just return FLASH_NO_ERROR and do nothing?

Re: [NEWS] Introducing MFS

Posted: Mon Apr 15, 2019 5:14 pm
by Giovanni
Better return an error, FLASH_NO_ERROR means that an erase is in progress and polling should be started.

Giovanni

Re: [NEWS] Introducing MFS

Posted: Mon Apr 15, 2019 5:54 pm
by 0x3333
Right, will return FLASH_ERROR_HW_FAILURE, as the doc says:

Code: Select all

@retval FLASH_ERROR_HW_FAILURE   if access to the memory failed.


Kind of...

Thanks.

Re: [NEWS] Introducing MFS

Posted: Mon Apr 15, 2019 6:32 pm
by Giovanni
I will add a specific error code "unimplemented" later.

Giovanni

Re: [NEWS] Introducing MFS

Posted: Mon Apr 15, 2019 8:19 pm
by 0x3333
Here is an initial implementation for F1XX. I'll test it tonight and let you guys know.

Small changes from L4 driver:

  • Removed unused defines, FLASH_PDKEY1, FLASH_PDKEY2, FLASH_OPTKEY1, FLASH_OPTKEY1
  • Removed already defined defines FLASH_KEY1 and FLASH_KEY2, defined on os/common/ext/ST/STM32F1xx/stm32f1xxxx.h
  • Use of FLASH_BASE instead 0x08000000U hardcoded
  • Created the function stm32_flash_is_busy, to read FLASH_SR_BSY flag
  • Removed osalDbgAssert on stm32_flash_check_errors, F1 has no such flags
  • efl_lld_start_erase_all does nothing, return FLASH_ERROR_HW_FAILURE, will wait for the unimplemented error
  • Changed in efl_lld_query_erase parameter msec to wait_time, as it is defined in the header

I'm unable to upload an attachment, "Invalid file extension: driver_f1.diff".

Code: Select all

diff --git a/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.c b/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.c
new file mode 100644
index 000000000..399777d31
--- /dev/null
+++ b/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.c
@@ -0,0 +1,491 @@
+/*
+    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+
+/**
+ * @file    hal_efl_lld.c
+ * @brief   STM32L4xx Embedded Flash subsystem low level driver source.
+ *
+ * @addtogroup HAL_EFL
+ * @{
+ */
+
+#include <string.h>
+
+#include "hal.h"
+
+#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions.                                                 */
+/*===========================================================================*/
+
+#define STM32_FLASH_SECTOR_SIZE             1024U
+#define STM32_FLASH_LINE_SIZE               2U
+#define STM32_FLASH_LINE_MASK               (STM32_FLASH_LINE_SIZE - 1U)
+
+/*===========================================================================*/
+/* Driver exported variables.                                                */
+/*===========================================================================*/
+
+/**
+ * @brief   EFL1 driver identifier.
+ */
+EFlashDriver EFLD1;
+
+/*===========================================================================*/
+/* Driver local variables and types.                                         */
+/*===========================================================================*/
+
+static const flash_descriptor_t efl_lld_descriptor = {
+ .attributes        = FLASH_ATTR_ERASED_IS_ONE |
+                      FLASH_ATTR_MEMORY_MAPPED,
+ .page_size         = STM32_FLASH_LINE_SIZE,
+ .sectors_count     = STM32_FLASH_NUMBER_OF_BANKS *
+                      STM32_FLASH_SECTORS_PER_BANK,
+ .sectors           = NULL,
+ .sectors_size      = STM32_FLASH_SECTOR_SIZE,
+ .address           = (uint8_t *)FLASH_BASE,
+ .size              = STM32_FLASH_NUMBER_OF_BANKS *
+                      STM32_FLASH_SECTORS_PER_BANK *
+                      STM32_FLASH_SECTOR_SIZE
+};
+
+/*===========================================================================*/
+/* Driver local functions.                                                   */
+/*===========================================================================*/
+
+
+static inline void stm32_flash_lock(EFlashDriver *eflp) {
+
+  eflp->flash->CR |= FLASH_CR_LOCK;
+}
+
+static inline void stm32_flash_unlock(EFlashDriver *eflp) {
+
+  eflp->flash->KEYR |= FLASH_KEY1;
+  eflp->flash->KEYR |= FLASH_KEY2;
+}
+
+static inline void stm32_flash_enable_pgm(EFlashDriver *eflp) {
+
+  eflp->flash->CR |= FLASH_CR_PG;
+}
+
+static inline void stm32_flash_disable_pgm(EFlashDriver *eflp) {
+
+  eflp->flash->CR &= ~FLASH_CR_PG;
+}
+
+static inline void stm32_flash_clear_status(EFlashDriver *eflp) {
+
+  eflp->flash->SR = 0x0000001FU;
+}
+
+static inline uint32_t stm32_flash_is_busy(EFlashDriver *eflp) {
+
+  return (eflp->flash->SR & FLASH_SR_BSY);
+}
+
+static inline void stm32_flash_wait_busy(EFlashDriver *eflp) {
+
+  /* Wait for busy bit clear.*/
+  while (stm32_flash_is_busy(eflp) != 0U) {
+  }
+}
+
+static inline flash_error_t stm32_flash_check_errors(EFlashDriver *eflp) {
+  uint32_t sr = eflp->flash->SR;
+
+  /* Clearing error conditions.*/
+  eflp->flash->SR = sr & 0x0000001FU;
+
+  /* Decoding relevant errors.*/
+  if ((sr & FLASH_SR_WRPRTERR) != 0U) {
+    return FLASH_ERROR_HW_FAILURE;
+  }
+
+  if ((sr & FLASH_SR_PGERR) != 0U) {
+    return FLASH_ERROR_PROGRAM; /* There is no error on erase.*/
+  }
+
+  return FLASH_NO_ERROR;
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers.                                                */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions.                                                */
+/*===========================================================================*/
+
+/**
+ * @brief   Low level Embedded Flash driver initialization.
+ *
+ * @notapi
+ */
+void efl_lld_init(void) {
+
+  /* Driver initialization.*/
+  eflObjectInit(&EFLD1);
+  EFLD1.flash = FLASH;
+}
+
+/**
+ * @brief   Configures and activates the Embedded Flash peripheral.
+ *
+ * @param[in] eflp      pointer to a @p EFlashDriver structure
+ *
+ * @notapi
+ */
+void efl_lld_start(EFlashDriver *eflp) {
+
+  stm32_flash_unlock(eflp);
+  FLASH->CR = 0x00000000U;
+}
+
+/**
+ * @brief   Deactivates the Embedded Flash peripheral.
+ *
+ * @param[in] eflp      pointer to a @p EFlashDriver structure
+ *
+ * @notapi
+ */
+void efl_lld_stop(EFlashDriver *eflp) {
+
+  stm32_flash_lock(eflp);
+}
+
+/**
+ * @brief   Gets the flash descriptor structure.
+ *
+ * @param[in] ip                    pointer to a @p EFlashDriver instance
+ * @return                          A flash device descriptor.
+ *
+ * @notapi
+ */
+const flash_descriptor_t *efl_lld_get_descriptor(void *instance) {
+
+  (void)instance;
+
+  return &efl_lld_descriptor;
+}
+
+/**
+ * @brief   Read operation.
+ *
+ * @param[in] ip                    pointer to a @p EFlashDriver instance
+ * @param[in] offset                flash offset
+ * @param[in] n                     number of bytes to be read
+ * @param[out] rp                   pointer to the data buffer
+ * @return                          An error code.
+ * @retval FLASH_NO_ERROR           if there is no erase operation in progress.
+ * @retval FLASH_BUSY_ERASING       if there is an erase operation in progress.
+ * @retval FLASH_ERROR_READ         if the read operation failed.
+ * @retval FLASH_ERROR_HW_FAILURE   if access to the memory failed.
+ *
+ * @notapi
+ */
+flash_error_t efl_lld_read(void *instance, flash_offset_t offset,
+                           size_t n, uint8_t *rp) {
+  EFlashDriver *devp = (EFlashDriver *)instance;
+  flash_error_t err = FLASH_NO_ERROR;
+
+  osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U));
+  osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size);
+  osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
+                "invalid state");
+
+  /* No reading while erasing.*/
+  if (devp->state == FLASH_ERASE) {
+    return FLASH_BUSY_ERASING;
+  }
+
+  /* FLASH_READY state while the operation is performed.*/
+  devp->state = FLASH_READ;
+
+  /* Clearing error status bits.*/
+  stm32_flash_clear_status(devp);
+
+  /* Actual read implementation.*/
+  memcpy((void *)rp, (const void *)efl_lld_descriptor.address + offset, n);
+
+  /* Ready state again.*/
+  devp->state = FLASH_READY;
+
+  return err;
+}
+
+/**
+ * @brief   Program operation.
+ * @note    It is only possible to write erased pages once except
+ *          when writing all zeroes.
+ *
+ * @param[in] ip                    pointer to a @p EFlashDriver instance
+ * @param[in] offset                flash offset
+ * @param[in] n                     number of bytes to be programmed
+ * @param[in] pp                    pointer to the data buffer
+ * @return                          An error code.
+ * @retval FLASH_NO_ERROR           if there is no erase operation in progress.
+ * @retval FLASH_BUSY_ERASING       if there is an erase operation in progress.
+ * @retval FLASH_ERROR_PROGRAM      if the program operation failed.
+ * @retval FLASH_ERROR_HW_FAILURE   if access to the memory failed.
+ *
+ * @notapi
+ */
+flash_error_t efl_lld_program(void *instance, flash_offset_t offset,
+                              size_t n, const uint8_t *pp) {
+  EFlashDriver *devp = (EFlashDriver *)instance;
+  flash_error_t err = FLASH_NO_ERROR;
+
+  osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U));
+  osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size);
+
+  osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
+                "invalid state");
+
+  /* No programming while erasing.*/
+  if (devp->state == FLASH_ERASE) {
+    return FLASH_BUSY_ERASING;
+  }
+
+  /* FLASH_PGM state while the operation is performed.*/
+  devp->state = FLASH_PGM;
+
+  /* Clearing error status bits.*/
+  stm32_flash_clear_status(devp);
+
+  /* Enabling PGM mode in the controller.*/
+  stm32_flash_enable_pgm(devp);
+
+  /* Actual program implementation.*/
+  while (n > 0U) {
+    volatile uint32_t *address;
+
+    union {
+      uint16_t  hw[STM32_FLASH_LINE_SIZE / sizeof (uint16_t)];
+      uint8_t   b[STM32_FLASH_LINE_SIZE / sizeof (uint8_t)];
+    } line;
+
+    /* Unwritten bytes are initialized to all ones.*/
+    line.hw[0] = 0xFFFFU;
+
+    /* Programming address aligned to flash lines.*/
+    address = (volatile uint32_t *)(efl_lld_descriptor.address +
+                                    (offset & ~STM32_FLASH_LINE_MASK));
+
+    /* Copying data inside the prepared line.*/
+    do {
+      line.b[offset & STM32_FLASH_LINE_MASK] = *pp;
+      offset++;
+      n--;
+      pp++;
+    }
+    while ((n > 0U) & ((offset & STM32_FLASH_LINE_MASK) != 0U));
+
+    /* Programming line.*/
+    address[0] = line.hw[0];
+    stm32_flash_wait_busy(devp);
+
+    err = stm32_flash_check_errors(devp);
+    if (err != FLASH_NO_ERROR) {
+      break;
+    }
+    /* Check for flash error.*/
+    if(address[0] != line.hw[0])
+    {
+      err = FLASH_ERROR_PROGRAM;
+      break;
+    }
+  }
+
+  /* Disabling PGM mode in the controller.*/
+  stm32_flash_disable_pgm(devp);
+
+  /* Ready state again.*/
+  devp->state = FLASH_READY;
+
+  return err;
+}
+
+/**
+ * @brief   Starts a whole-device erase operation.
+ * @note    This function does nothing, as STM32F1 has only one bank
+ *          and it is where the program is running on.
+ *
+ * @param[in] ip                    pointer to a @p EFlashDriver instance
+ * @return                          An error code.
+ * @retval FLASH_NO_ERROR           if there is no erase operation in progress.
+ * @retval FLASH_BUSY_ERASING       if there is an erase operation in progress.
+ * @retval FLASH_ERROR_HW_FAILURE   if access to the memory failed.
+ *
+ * @notapi
+ */
+flash_error_t efl_lld_start_erase_all(void *instance) {
+  (void) instance;
+
+  return FLASH_ERROR_HW_FAILURE;
+}
+
+/**
+ * @brief   Starts an sector erase operation.
+ *
+ * @param[in] ip                    pointer to a @p EFlashDriver instance
+ * @param[in] sector                sector to be erased
+ * @return                          An error code.
+ * @retval FLASH_NO_ERROR           if there is no erase operation in progress.
+ * @retval FLASH_BUSY_ERASING       if there is an erase operation in progress.
+ * @retval FLASH_ERROR_HW_FAILURE   if access to the memory failed.
+ *
+ * @notapi
+ */
+flash_error_t efl_lld_start_erase_sector(void *instance,
+                                         flash_sector_t sector) {
+  EFlashDriver *devp = (EFlashDriver *)instance;
+
+  osalDbgCheck(instance != NULL);
+  osalDbgCheck(sector < efl_lld_descriptor.sectors_count);
+  osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
+                "invalid state");
+
+  /* No erasing while erasing.*/
+  if (devp->state == FLASH_ERASE) {
+    return FLASH_BUSY_ERASING;
+  }
+
+  /* FLASH_PGM state while the operation is performed.*/
+  devp->state = FLASH_ERASE;
+
+  /* Clearing error status bits.*/
+  stm32_flash_clear_status(devp);
+
+  /* Enable page erase.*/
+  devp->flash->CR |= FLASH_CR_PER;
+
+  /* Set the page.*/
+  devp->flash->AR = sector;
+
+  /* Start the erase.*/
+  devp->flash->CR |= FLASH_CR_STRT;
+
+  return FLASH_NO_ERROR;
+}
+
+/**
+ * @brief   Queries the driver for erase operation progress.
+ *
+ * @param[in] ip                    pointer to a @p EFlashDriver instance
+ * @param[out] wait_time            recommended time, in milliseconds, that
+ *                                  should be spent before calling this
+ *                                  function again, can be @p NULL
+ * @return                          An error code.
+ * @retval FLASH_NO_ERROR           if there is no erase operation in progress.
+ * @retval FLASH_BUSY_ERASING       if there is an erase operation in progress.
+ * @retval FLASH_ERROR_ERASE        if the erase operation failed.
+ * @retval FLASH_ERROR_HW_FAILURE   if access to the memory failed.
+ *
+ * @api
+ */
+flash_error_t efl_lld_query_erase(void *instance, uint32_t *wait_time){
+  EFlashDriver *devp = (EFlashDriver *)instance;
+  flash_error_t err;
+
+  /* If there is an erase in progress then the device must be checked.*/
+  if (devp->state == FLASH_ERASE) {
+
+    /* Checking for operation in progress.*/
+    if (stm32_flash_is_busy(devp) == 0U) {
+
+      /* Disabling the various erase control bits.*/
+      devp->flash->CR &= ~(FLASH_CR_OPTER | FLASH_CR_OPTPG |
+                           FLASH_CR_MER | FLASH_CR_PER);
+
+      /* Back to ready state.*/
+      devp->state = FLASH_READY;
+
+      err = FLASH_NO_ERROR;
+    }
+    else {
+      /* Recommended time before polling again, this is a simplified
+         implementation.*/
+      if (wait_time != NULL) {
+        *wait_time = (uint32_t)STM32_FLASH_WAIT_TIME_MS;
+      }
+
+      err = FLASH_BUSY_ERASING;
+    }
+  }
+  else {
+    err = FLASH_NO_ERROR;
+  }
+
+  return err;
+}
+
+/**
+ * @brief   Returns the erase state of a sector.
+ *
+ * @param[in] ip                    pointer to a @p EFlashDriver instance
+ * @param[in] sector                sector to be verified
+ * @return                          An error code.
+ * @retval FLASH_NO_ERROR           if the sector is erased.
+ * @retval FLASH_BUSY_ERASING       if there is an erase operation in progress.
+ * @retval FLASH_ERROR_VERIFY       if the verify operation failed.
+ * @retval FLASH_ERROR_HW_FAILURE   if access to the memory failed.
+ *
+ * @notapi
+ */
+flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector) {
+  EFlashDriver *devp = (EFlashDriver *)instance;
+  uint32_t *address;
+  flash_error_t err = FLASH_NO_ERROR;
+  unsigned i;
+
+  osalDbgCheck(instance != NULL);
+  osalDbgCheck(sector < efl_lld_descriptor.sectors_count);
+  osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
+                "invalid state");
+
+  /* No verifying while erasing.*/
+  if (devp->state == FLASH_ERASE) {
+    return FLASH_BUSY_ERASING;
+  }
+
+  /* Address of the sector.*/
+  address = (uint32_t *)(efl_lld_descriptor.address +
+                         flashGetSectorOffset(getBaseFlash(devp), sector));
+
+  /* FLASH_READY state while the operation is performed.*/
+  devp->state = FLASH_READ;
+
+  /* Scanning the sector space.*/
+  for (i = 0U; i < STM32_FLASH_SECTOR_SIZE / sizeof(uint32_t); i++) {
+    if (*address != 0xFFFFFFFFU) {
+      err = FLASH_ERROR_VERIFY;
+      break;
+    }
+    address++;
+  }
+
+  /* Ready state again.*/
+  devp->state = FLASH_READY;
+
+  return err;
+}
+
+#endif /* HAL_USE_EFL == TRUE */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.h b/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.h
new file mode 100644
index 000000000..c2dfb1bac
--- /dev/null
+++ b/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.h
@@ -0,0 +1,116 @@
+/*
+    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+
+/**
+ * @file    hal_efl_lld.h
+ * @brief   STM32F1xx Embedded Flash subsystem low level driver header.
+ *
+ * @addtogroup HAL_EFL
+ * @{
+ */
+
+#ifndef HAL_EFL_LLD_H
+#define HAL_EFL_LLD_H
+
+#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants.                                                         */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings.                                         */
+/*===========================================================================*/
+
+/**
+ * @name    STM32F1xx configuration options
+ * @{
+ */
+/**
+ * @brief   Suggested wait time during erase operations polling.
+ */
+#if !defined(STM32_FLASH_WAIT_TIME_MS) || defined(__DOXYGEN__)
+#define STM32_FLASH_WAIT_TIME_MS            1
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks.                                       */
+/*===========================================================================*/
+
+#if !defined(STM32_FLASH_NUMBER_OF_BANKS)
+#error "STM32_FLASH_NUMBER_OF_BANKS not defined in registry"
+#endif
+
+#if !defined(STM32_FLASH_SECTORS_PER_BANK)
+#error "STM32_FLASH_SECTORS_PER_BANK not defined in registry"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types.                                         */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros.                                                            */
+/*===========================================================================*/
+
+/**
+ * @brief   Low level fields of the embedded flash driver structure.
+ */
+#define efl_lld_driver_fields                                               \
+  /* Flash registers.*/                                                     \
+  FLASH_TypeDef             *flash
+
+/**
+ * @brief   Low level fields of the embedded flash configuration structure.
+ */
+#define efl_lld_config_fields                                               \
+  /* Dummy configuration, it is not needed.*/                               \
+  uint32_t                  dummy
+
+/*===========================================================================*/
+/* External declarations.                                                    */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern EFlashDriver EFLD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void efl_lld_init(void);
+  void efl_lld_start(EFlashDriver *eflp);
+  void efl_lld_stop(EFlashDriver *eflp);
+  const flash_descriptor_t *efl_lld_get_descriptor(void *instance);
+  flash_error_t efl_lld_read(void *instance, flash_offset_t offset,
+                             size_t n, uint8_t *rp);
+  flash_error_t efl_lld_program(void *instance, flash_offset_t offset,
+                                size_t n, const uint8_t *pp);
+  flash_error_t efl_lld_start_erase_all(void *instance);
+  flash_error_t efl_lld_start_erase_sector(void *instance,
+                                           flash_sector_t sector);
+  flash_error_t efl_lld_query_erase(void *instance, uint32_t *wait_time);
+  flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_EFL == TRUE */
+
+#endif /* HAL_EFL_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F1xx/platform.mk b/os/hal/ports/STM32/STM32F1xx/platform.mk
index 4179fa910..8ff4f5331 100644
--- a/os/hal/ports/STM32/STM32F1xx/platform.mk
+++ b/os/hal/ports/STM32/STM32F1xx/platform.mk
@@ -1,7 +1,8 @@
 # Required platform files.
 PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
                $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/stm32_isr.c \
-               $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_lld.c
+               $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_lld.c \
+               $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.c
 
 # Required include directories.
 PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
diff --git a/os/hal/ports/STM32/STM32F1xx/stm32_registry.h b/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
index dc9dd13e7..f643b9bad 100644
--- a/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
@@ -115,6 +115,12 @@
 #define STM32_EXTI_NUM_LINES                19
 #define STM32_EXTI_IMR_MASK                 0x00000000U
 
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS         1
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK        32 /* Maximum, can be redefined.*/
+#endif
+
 /* GPIO attributes.*/
 #define STM32_HAS_GPIOA                     TRUE
 #define STM32_HAS_GPIOB                     TRUE
@@ -321,6 +327,12 @@
 #define STM32_EXTI_NUM_LINES                19
 #define STM32_EXTI_IMR_MASK                 0x00000000U
 
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS         1
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK        32 /* Maximum, can be redefined.*/
+#endif
+
 /* GPIO attributes.*/
 #define STM32_HAS_GPIOA                     TRUE
 #define STM32_HAS_GPIOB                     TRUE
@@ -499,6 +511,12 @@
 #define STM32_EXTI_NUM_LINES                19
 #define STM32_EXTI_IMR_MASK                 0x00000000U
 
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS         1
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK        128 /* Maximum, can be redefined.*/
+#endif
+
 /* GPIO attributes.*/
 #define STM32_HAS_GPIOA                     TRUE
 #define STM32_HAS_GPIOB                     TRUE
@@ -710,6 +728,12 @@
 #define STM32_EXTI_NUM_LINES                19
 #define STM32_EXTI_IMR_MASK                 0x00000000U
 
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS         1
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK        256 /* Maximum, can be redefined.*/
+#endif
+
 /* GPIO attributes.*/
 #define STM32_HAS_GPIOA                     TRUE
 #define STM32_HAS_GPIOB                     TRUE
@@ -943,6 +967,12 @@
 #define STM32_EXTI_NUM_LINES                19
 #define STM32_EXTI_IMR_MASK                 0x00000000U
 
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS         2
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK        256 /* Maximum, can be redefined.*/
+#endif
+
 /* GPIO attributes.*/
 #define STM32_HAS_GPIOA                     TRUE
 #define STM32_HAS_GPIOB                     TRUE
@@ -1196,6 +1226,12 @@
 #define STM32_EXTI_NUM_LINES                20
 #define STM32_EXTI_IMR_MASK                 0x00000000U
 
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS         1
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK        128 /* Maximum, can be redefined.*/
+#endif
+
 /* GPIO attributes.*/
 #define STM32_HAS_GPIOA                     TRUE
 #define STM32_HAS_GPIOB                     TRUE


Re: [NEWS] Introducing MFS

Posted: Mon Apr 15, 2019 8:31 pm
by Giovanni
Hi,

It looks very similar except for the program lines of just 2 bytes. You may also post the files zipped, the forum only accepts .zip and .7z.

Giovanni

Re: [NEWS] Introducing MFS

Posted: Mon Apr 15, 2019 9:12 pm
by 0x3333
Exactly, I used L4 as base. I'll validate everything in some hours and post the patch.