diff --git a/os/hal/include/hal_efl.h b/os/hal/include/hal_efl.h index d68266cc7..4a07853f1 100644 --- a/os/hal/include/hal_efl.h +++ b/os/hal/include/hal_efl.h @@ -133,8 +133,6 @@ extern "C" { void eflObjectInit(EFlashDriver *eflp); msg_t eflStart(EFlashDriver *eflp, const EFlashConfig *config); void eflStop(EFlashDriver *eflp); - void eflAcquireBus(EFlashDriver *eflp); - void eflReleaseBus(EFlashDriver *eflp); #ifdef __cplusplus } #endif diff --git a/os/hal/include/hal_flash.h b/os/hal/include/hal_flash.h index ba90a765e..a667f9f49 100644 --- a/os/hal/include/hal_flash.h +++ b/os/hal/include/hal_flash.h @@ -189,7 +189,11 @@ typedef struct { flash_sector_t sector); \ flash_error_t (*query_erase)(void *instance, uint32_t *wait_time); \ /* Verify erase single sector.*/ \ - flash_error_t (*verify_erase)(void *instance, flash_sector_t sector); + flash_error_t (*verify_erase)(void *instance, flash_sector_t sector); \ + /* Acquire exclusive use of flash.*/ \ + flash_error_t (*acquire_exclusive)(void *instance); \ + /* Release exclusive use of flash.*/ \ + flash_error_t (*release_exclusive)(void *instance); /** * @brief @p BaseFlash specific methods with inherited ones. @@ -348,6 +352,30 @@ typedef struct { */ #define flashVerifyErase(ip, sector) \ (ip)->vmt->verify_erase(ip, sector) + +/** + * @brief Acquires exclusive access to flash. + * + * @param[in] ip pointer to a @p BaseFlash or derived class + * @return An error code. + * @retval FLASH_NO_ERROR if the access is obtained. + * @retval FLASH_ERROR_UNIMPLEMENTED if exclusive access not enabled + * @api + */ +#define flashAcquireExclusive(ip) \ + (ip)->vmt->acquire_exclusive(ip) + +/** + * @brief Releases exclusive access to flash. + * + * @param[in] ip pointer to a @p BaseFlash or derived class + * @return An error code. + * @retval FLASH_NO_ERROR if the access is released. + * @retval FLASH_ERROR_UNIMPLEMENTED if exclusive access not enabled + * @api + */ +#define flashReleaseExclusive(ip) \ + (ip)->vmt->release_exclusive(ip) /** @} */ /*===========================================================================*/ @@ -357,9 +385,12 @@ typedef struct { #ifdef __cplusplus extern "C" { #endif - flash_error_t flashWaitErase(BaseFlash *devp); + flash_error_t flashWaitErase(BaseFlash *devp); flash_offset_t flashGetSectorOffset(BaseFlash *devp, flash_sector_t sector); - uint32_t flashGetSectorSize(BaseFlash *devp, flash_sector_t sector); + uint32_t flashGetSectorSize(BaseFlash *devp, flash_sector_t sector); + void * flashGetOffsetAddress(BaseFlash *devp, flash_offset_t offset); + flash_offset_t flashGetAddressOffset(BaseFlash *devp, void * addr); + flash_sector_t flashGetOffsetSector(BaseFlash *devp, flash_offset_t offset); #ifdef __cplusplus } #endif diff --git a/os/hal/lib/complex/serial_nor/hal_serial_nor.c b/os/hal/lib/complex/serial_nor/hal_serial_nor.c index 82d90835e..20f380d21 100644 --- a/os/hal/lib/complex/serial_nor/hal_serial_nor.c +++ b/os/hal/lib/complex/serial_nor/hal_serial_nor.c @@ -48,6 +48,8 @@ static flash_error_t snor_start_erase_sector(void *instance, static flash_error_t snor_verify_erase(void *instance, flash_sector_t sector); static flash_error_t snor_query_erase(void *instance, uint32_t *msec); +static flash_error_t snor_acquire_exclusive(void *instance); +static flash_error_t snor_release_exclusive(void *instance); static flash_error_t snor_read_sfdp(void *instance, flash_offset_t offset, size_t n, uint8_t *rp); @@ -58,8 +60,8 @@ static const struct SNORDriverVMT snor_vmt = { (size_t)0, snor_get_descriptor, snor_read, snor_program, snor_start_erase_all, snor_start_erase_sector, - snor_query_erase, snor_verify_erase, - snor_read_sfdp + snor_query_erase, snor_verify_erase, snor_acquire_exclusive, + snor_release_exclusive, snor_read_sfdp, }; /*===========================================================================*/ @@ -301,6 +303,32 @@ static flash_error_t snor_read_sfdp(void *instance, flash_offset_t offset, return err; } +static flash_error_t snor_acquire_exclusive(void *instance) { +#if (SNOR_USE_MUTUAL_EXCLUSION == TRUE) + SNORDriver *devp = (SNORDriver *)instance; + + osalMutexLock(&devp->mutex); + return FLASH_NO_ERROR; +#else + (void)instance; + osalDbgAssert(false, "mutual exclusion not enabled"); + return FLASH_ERROR_UNIMPLEMENTED; +#endif +} + +static flash_error_t snor_release_exclusive(void *instance) { +#if (SNOR_USE_MUTUAL_EXCLUSION == TRUE) + SNORDriver *devp = (SNORDriver *)instance; + + osalMutexUnlock(&devp->mutex); + return FLASH_NO_ERROR; +#else + (void)instance; + osalDbgAssert(false, "mutual exclusion not enabled"); + return FLASH_ERROR_UNIMPLEMENTED; +#endif +} + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -647,6 +675,9 @@ void snorObjectInit(SNORDriver *devp) { devp->vmt = &snor_vmt; devp->state = FLASH_STOP; devp->config = NULL; +#if SNOR_USE_MUTUAL_EXCLUSION == TRUE + osalMutexObjectInit(&devp->mutex); +#endif } /** diff --git a/os/hal/lib/complex/serial_nor/hal_serial_nor.h b/os/hal/lib/complex/serial_nor/hal_serial_nor.h index 7e5afaa57..f8411b8ed 100644 --- a/os/hal/lib/complex/serial_nor/hal_serial_nor.h +++ b/os/hal/lib/complex/serial_nor/hal_serial_nor.h @@ -65,6 +65,14 @@ #if !defined(SNOR_SHARED_BUS) || defined(__DOXYGEN__) #define SNOR_SHARED_BUS TRUE #endif + +/** + * @brief Exclusive access control. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SNOR_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SNOR_USE_MUTUAL_EXCLUSION TRUE +#endif /** @} */ /*===========================================================================*/ @@ -138,6 +146,12 @@ typedef struct { * @brief Device ID and unique ID. */ uint8_t device_id[20]; +#if (SNOR_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__) + /** + * @brief Mutex protecting SNOR. + */ + mutex_t mutex; +#endif /* EFL_USE_MUTUAL_EXCLUSION == TRUE */ } SNORDriver; /*===========================================================================*/ diff --git a/os/hal/src/hal_efl.c b/os/hal/src/hal_efl.c index 34e078c90..7681c3c50 100644 --- a/os/hal/src/hal_efl.c +++ b/os/hal/src/hal_efl.c @@ -35,11 +35,37 @@ /*===========================================================================*/ /*===========================================================================*/ -/* Driver local variables and types. */ +/* Driver local functions. */ /*===========================================================================*/ +static flash_error_t efl_acquire_exclusive(void *instance) { +#if (EFL_USE_MUTUAL_EXCLUSION == TRUE) + EFlashDriver *devp = (EFlashDriver *)instance; + + osalMutexLock(&devp->mutex); + return FLASH_NO_ERROR; +#else + (void)instance; + osalDbgAssert(false, "mutual exclusion not enabled"); + return FLASH_ERROR_UNIMPLEMENTED; +#endif +} + +static flash_error_t efl_release_exclusive(void *instance) { +#if (EFL_USE_MUTUAL_EXCLUSION == TRUE) + EFlashDriver *devp = (EFlashDriver *)instance; + + osalMutexUnlock(&devp->mutex); + return FLASH_NO_ERROR; +#else + (void)instance; + osalDbgAssert(false, "mutual exclusion not enabled"); + return FLASH_ERROR_UNIMPLEMENTED; +#endif +} + /*===========================================================================*/ -/* Driver local functions. */ +/* Driver local variables and types. */ /*===========================================================================*/ static const struct EFlashDriverVMT vmt = { @@ -50,7 +76,9 @@ static const struct EFlashDriverVMT vmt = { efl_lld_start_erase_all, efl_lld_start_erase_sector, efl_lld_query_erase, - efl_lld_verify_erase + efl_lld_verify_erase, + efl_acquire_exclusive, + efl_release_exclusive }; /*===========================================================================*/ @@ -148,42 +176,6 @@ void eflStop(EFlashDriver *eflp) { osalSysUnlock(); } -#if (EFL_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__) -/** - * @brief Gains exclusive access to EFL. - * @details This function tries to gain ownership of EFL. If EFL - * is already being used then the invoking thread is queued. - * @pre In order to use this function the option @p EFL_USE_MUTUAL_EXCLUSION - * must be enabled. - * - * @param[in] eflp pointer to the @p EFlashDriver object - * - * @api - */ -void eflAcquireBus(EFlashDriver *eflp) { - - osalDbgCheck(eflp != NULL); - - osalMutexLock(&eflp->mutex); -} - -/** - * @brief Releases exclusive access to EFL. - * @pre In order to use this function the option @p EFL_USE_MUTUAL_EXCLUSION - * must be enabled. - * - * @param[in] eflp pointer to the @p EFlashDriver object - * - * @api - */ -void eflReleaseBus(EFlashDriver *eflp) { - - osalDbgCheck(eflp != NULL); - - osalMutexUnlock(&eflp->mutex); -} -#endif /* EFL_USE_MUTUAL_EXCLUSION == TRUE */ - #endif /* HAL_USE_EFL == TRUE */ /** @} */ diff --git a/os/hal/src/hal_flash.c b/os/hal/src/hal_flash.c index f3e7a35bc..115fcf2ca 100644 --- a/os/hal/src/hal_flash.c +++ b/os/hal/src/hal_flash.c @@ -1,5 +1,5 @@ /* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2006..2021 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. @@ -122,4 +122,81 @@ uint32_t flashGetSectorSize(BaseFlash *devp, return size; } + +/** + * @brief Get absolute address from offset + * + * @param[in] ip pointer to a @p BaseFlash or derived class + * @param[in] offset offset + * @return A pointer to the offset + * + * @api + */ +void * flashGetOffsetAddress(BaseFlash *devp, flash_offset_t offset) { + osalDbgCheck(devp != NULL); + + const flash_descriptor_t *descriptor = flashGetDescriptor(devp); + osalDbgAssert(offset < descriptor->size, "invalid offset"); + + return (void *)((flash_offset_t)descriptor->address + offset); +} + +/** + * @brief Get offset from absolute address + * + * @param[in] ip pointer to a @p BaseFlash or derived class + * @param[in] addr pointer + * @return offset + * + * @api + */ +flash_offset_t flashGetAddressOffset(BaseFlash *devp, void * addr) { + osalDbgCheck(devp != NULL); + + const flash_descriptor_t *descriptor = flashGetDescriptor(devp); + osalDbgAssert(((flash_offset_t)addr >= + (flash_offset_t)descriptor->address) + && ((flash_offset_t)addr <= (flash_offset_t)descriptor->address + + descriptor->size), + "invalid address"); + + return (flash_offset_t)addr - (flash_offset_t)descriptor->address; +} + +/** + * @brief Returns the sector of an offset. + * + * @param[in] devp pointer to a @p BaseFlash object + * @param[in] offset flash offset + * + * @return the sector of the offset + */ +flash_sector_t flashGetOffsetSector(BaseFlash *devp, + flash_offset_t offset) { + flash_sector_t sector; + const flash_descriptor_t *descriptor = flashGetDescriptor(devp); + + osalDbgAssert(offset < descriptor->size, "invalid offset"); + + if (descriptor->sectors != NULL) { + flash_offset_t sector_start; + flash_offset_t sector_end; + for (flash_sector_t i = 0; i < descriptor->sectors_count; i++) { + sector_start = descriptor->sectors[i].offset; + sector_end = sector_start + descriptor->sectors[i].size - 1U; + if ((offset >= sector_start) && (offset <= sector_end)) { + sector = i; + return sector; + } + } + } + else { + sector = offset/descriptor->sectors_size; + return sector; + } + + osalDbgAssert(FALSE, "invalid offset"); + + return 0; +} /** @} */ diff --git a/os/readme.txt b/os/readme.txt deleted file mode 100644 index 237a592b8..000000000 --- a/os/readme.txt +++ /dev/null @@ -1,39 +0,0 @@ -***************************************************************************** -*** ChibiOS products directory organization *** -***************************************************************************** - ---{root} - Distribution directory. - +--os/ - ChibiOS products, this directory. - | +--rt/ - ChibiOS/RT product. - | | +--include/ - RT kernel headers. - | | +--src/ - RT kernel sources. - | | +--templates/ - RT kernel port template files. - | | +--ports/ - RT kernel port files. - | | +--osal/ - RT kernel OSAL module for HAL interface. - | +--nil/ - ChibiOS/NIL product. - | | +--include/ - Nil kernel headers. - | | +--src/ - Nil kernel sources. - | | +--templates/ - Nil kernel port template files. - | | +--ports/ - Nil kernel port files. - | | +--osal/ - Nil kernel OSAL module for HAL interface. - | +--oslib/ - ChibiOS/LIB product. - | | +--include/ - OSLIB headers. - | | +--src/ - OSLIB sources. - | +--sb/ - ChibiOS/SB product. - | +--ex/ - ChibiOS/EX product. - | +--hal/ - ChibiOS/HAL product. - | | +--include/ - HAL high level headers. - | | +--src/ - HAL high level sources. - | | +--templates/ - HAL port template files. - | | +--ports/ - HAL port files (low level drivers implementations). - | | +--boards/ - HAL board files. - | +--common/ - Files used by multiple ChibiOS products. - | | +--abstractions/- Emulation of other API. - | | +--ext/ - Vendor files used by ChibiOS products. - | | +--portability/ - Compilers abstraction support files. - | | +--ports - RT/NIL port files for various architectures and - | | compilers. - | | +--startup/ - Startup, linker and make support for various - | | architectures and compilers. - | +--various/ - Various portable support files. - \ No newline at end of file diff --git a/readme.txt b/readme.txt index fe3632aca..e8d1ea0a2 100644 --- a/readme.txt +++ b/readme.txt @@ -74,6 +74,8 @@ ***************************************************************************** *** Next *** +- NEW: Improved HAL flash interface with mutual exclusion methods, improved + EFL and SNOR drivers to use it. - NEW: Added a centralized errors handler under /os/common/utils. It will replace those in HAL and SB and will be shared among multiple subsystems. - NEW: Added a new OOP model under /os/common/utils. It will replace the