Improved HAL flash interface with mutual exclusion methods, improved EFL and SNOR drivers to use it.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15286 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-12-30 06:40:05 +00:00
parent 8f71c3e6b5
commit e9c826005e
8 changed files with 192 additions and 86 deletions

View File

@ -133,8 +133,6 @@ extern "C" {
void eflObjectInit(EFlashDriver *eflp); void eflObjectInit(EFlashDriver *eflp);
msg_t eflStart(EFlashDriver *eflp, const EFlashConfig *config); msg_t eflStart(EFlashDriver *eflp, const EFlashConfig *config);
void eflStop(EFlashDriver *eflp); void eflStop(EFlashDriver *eflp);
void eflAcquireBus(EFlashDriver *eflp);
void eflReleaseBus(EFlashDriver *eflp);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -189,7 +189,11 @@ typedef struct {
flash_sector_t sector); \ flash_sector_t sector); \
flash_error_t (*query_erase)(void *instance, uint32_t *wait_time); \ flash_error_t (*query_erase)(void *instance, uint32_t *wait_time); \
/* Verify erase single sector.*/ \ /* 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. * @brief @p BaseFlash specific methods with inherited ones.
@ -348,6 +352,30 @@ typedef struct {
*/ */
#define flashVerifyErase(ip, sector) \ #define flashVerifyErase(ip, sector) \
(ip)->vmt->verify_erase(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)
/** @} */ /** @} */
/*===========================================================================*/ /*===========================================================================*/
@ -360,6 +388,9 @@ extern "C" {
flash_error_t flashWaitErase(BaseFlash *devp); flash_error_t flashWaitErase(BaseFlash *devp);
flash_offset_t flashGetSectorOffset(BaseFlash *devp, flash_sector_t sector); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -48,6 +48,8 @@ static flash_error_t snor_start_erase_sector(void *instance,
static flash_error_t snor_verify_erase(void *instance, static flash_error_t snor_verify_erase(void *instance,
flash_sector_t sector); flash_sector_t sector);
static flash_error_t snor_query_erase(void *instance, uint32_t *msec); 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, static flash_error_t snor_read_sfdp(void *instance, flash_offset_t offset,
size_t n, uint8_t *rp); size_t n, uint8_t *rp);
@ -58,8 +60,8 @@ static const struct SNORDriverVMT snor_vmt = {
(size_t)0, (size_t)0,
snor_get_descriptor, snor_read, snor_program, snor_get_descriptor, snor_read, snor_program,
snor_start_erase_all, snor_start_erase_sector, snor_start_erase_all, snor_start_erase_sector,
snor_query_erase, snor_verify_erase, snor_query_erase, snor_verify_erase, snor_acquire_exclusive,
snor_read_sfdp 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; 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. */ /* Driver exported functions. */
/*===========================================================================*/ /*===========================================================================*/
@ -647,6 +675,9 @@ void snorObjectInit(SNORDriver *devp) {
devp->vmt = &snor_vmt; devp->vmt = &snor_vmt;
devp->state = FLASH_STOP; devp->state = FLASH_STOP;
devp->config = NULL; devp->config = NULL;
#if SNOR_USE_MUTUAL_EXCLUSION == TRUE
osalMutexObjectInit(&devp->mutex);
#endif
} }
/** /**

View File

@ -65,6 +65,14 @@
#if !defined(SNOR_SHARED_BUS) || defined(__DOXYGEN__) #if !defined(SNOR_SHARED_BUS) || defined(__DOXYGEN__)
#define SNOR_SHARED_BUS TRUE #define SNOR_SHARED_BUS TRUE
#endif #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. * @brief Device ID and unique ID.
*/ */
uint8_t device_id[20]; 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; } SNORDriver;
/*===========================================================================*/ /*===========================================================================*/

View File

@ -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 = { static const struct EFlashDriverVMT vmt = {
@ -50,7 +76,9 @@ static const struct EFlashDriverVMT vmt = {
efl_lld_start_erase_all, efl_lld_start_erase_all,
efl_lld_start_erase_sector, efl_lld_start_erase_sector,
efl_lld_query_erase, 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(); 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 */ #endif /* HAL_USE_EFL == TRUE */
/** @} */ /** @} */

View File

@ -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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with 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; 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;
}
/** @} */ /** @} */

View File

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

View File

@ -74,6 +74,8 @@
***************************************************************************** *****************************************************************************
*** Next *** *** 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 - 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. 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 - NEW: Added a new OOP model under /os/common/utils. It will replace the