This section describes the programming interfaces of the CACHE controller.
More...
This section describes the programming interfaces of the CACHE controller.
The CACHE controller is a unified CACHE (I-CACHE and D-CACHE use the same CACHE) that allows the user to set the CACHE size, configure the cacheable region(s), enable or disable the CACHE and to perform CACHE maintenance operations, such as invalidate and flush. These maintenance operations may be performed on the entire CACHE or based on the given address and length.
When a memory is set as cacheable, the CPU exchanges data with the CACHE memory during the CACHE hit instead of an external memory, so it can accelerate the access performance. But a data coherency issue is possible when the memory is shared between the Central Processing Unit (CPU) and hardware co-processors, such as Direct Memory Access (DMA). Peripherals (Inter-Integrated Circuit (I2C), Universal Asynchronous Receiver/Transmitter (UART), Serial Peripheral Interface (SPI)) or hardware modules (Graphics 2D (G2D), CAMERA) that operate in DMA mode also face the same issue.
These peripherals or hardware modules must work with non-cacheable memory.
Terms and acronyms
The following provides descriptions to the terms commonly used in the CACHE controller and how to use its various functions.
Terms | Details |
AHB | Advanced High-performance Bus (AHB) is a bus protocol introduced in the Advanced Microcontroller Bus Architecture version 2 published by ARM Ltd. |
CACHE | A collection of data duplicating original values stored in external memory, to accelerate the data access and enhance the MCU performance. |
CACHE line | The smallest unit of memory that can be transferred between the main memory and the CACHE. Unless otherwise indicated, the CACHE line size is 8 words (64 bytes). |
TCM | Tightly Coupled Memory (TCM), memory which resides directly in the processor. |
flush | Data in invalid CACHE line with dirty bit set is evicted to write-back buffer, then dirty bits are cleared. If the entry is invalid or the dirty flag is not set, leave as it is. The action does not clear the valid bit(s). |
invalidate | Unconditionally clear valid and dirty bits of the corresponding CACHE line(s). |
Supported features
Features supported by this module are listed below:
- Configure the overall CACHE size.
To reach the optimum system performance, the CACHE size can be set with flexibility. If the CACHE size is not set to the maximum (32kB), the memory of the unused CACHE is reused by the TCM. Users can call the function hal_cache_set_size(), to set the CACHE size. The input parameter of this function can be any value of type hal_cache_size_t. Apply different parameters for the function hal_cache_set_size() to set the cache size to one of the following four configurations:
- Using CACHE region to set a cacheable attribute for a memory block.
The CACHE controller has 16 regions for cacheable attribute settings. Note that each region can be continuous or non-continuous to each other. For those address ranges not covered by any region in the CACHE, the cacheable settings are automatically set as uncacheable. There is one restriction: different regions must not overlap. Call the function hal_cache_region_config(), to set the cacheable memory blocks for each region. The parameter should be of type hal_cache_region_config_t and the field in the hal_cache_region_config_t includes the cache_region_address (must be 4kB aligned) and the cache_region_size (must be 4kB aligned).
- CACHE flush or invalidate operation.
The CACHE maintenance operation includes flush and invalidate. The two operations may be performed on the entire CACHE or on a given address-length. The CACHE driver API names distinguish one from the other by the word "all". For example, to invalidate all CACHE lines, call the API hal_cache_invalidate_all_cache_lines(). To invalidate the CACHE lines for a particular memory block, simply call hal_cache_invalidate_multiple_cache_lines(). Note that the parameters "address" and "length" must be supplied to specify the physical address range to perform the CACHE maintenance operation on. The usage of flush operation is the same as the invalidate operation.
How to use this driver
- Use CACHE driver to enable or disable CACHE.
- Use CACHE driver to set a cacheable region.
- Step 1. Call hal_cache_set_size() to set the total CACHE size.
- Step 2. Call hal_cache_region_config() to set a CACHE region with specified address and length (should call more than once if there are multiple regions to be configured as cacheable).
- Step 3. Call hal_cache_region_enable() to enable the CACHE function of the corresponding region configured in step 2.
- Step 4. Call hal_cache_enable() to enable the CACHE controller.
- Sample code:
- Use CACHE driver to flush or invalidate a cacheable region.
- Use CACHE driver to flush or invalidate all cacheable regions.
This function deinitializes the CACHE, returning the CACHE module to its default state.
- Returns
- HAL_CACHE_STATUS_OK, the CACHE is successfully deinitialized.
This function flushes the whole CACHE.
- Returns
- HAL_CACHE_STATUS_OK, the CACHE is successfully flushed.
- Note
- Flush all CACHE lines.
hal_cache_status_t hal_cache_flush_multiple_cache_lines |
( |
uint32_t |
address, |
|
|
uint32_t |
length |
|
) |
| |
This function flushes the CACHE lines by address and length.
- Parameters
-
[in] | address | is the start address of the memory to flush. |
[in] | length | is the length of the memory to be flushed. The unit of the memory length is in bytes and both address and length must be CACHE line size aligned when the API is called. |
- Returns
- HAL_CACHE_STATUS_OK, the CACHE is successfully flushed.
HAL_CACHE_STATUS_INVALID_PARAMETER, either address or length is not CACHE line size aligned. The alignment requires that the address and the length of a CACHE line must be a multiple of HAL_CACHE_LINE_SIZE.
This function flushes one CACHE line by address.
- Parameters
-
[in] | address | is the start address of the memory that is flushed. |
- Returns
- HAL_CACHE_STATUS_OK, the CACHE is successfully flushed.
HAL_CACHE_STATUS_INVALID_PARAMETER, address is not CACHE line size aligned. The alignment requires that the address of a CACHE line must be a multiple of HAL_CACHE_LINE_SIZE.
This function invalidates the whole CACHE.
- Returns
- HAL_CACHE_STATUS_OK, the CACHE is successfully invalidated.
hal_cache_status_t hal_cache_invalidate_multiple_cache_lines |
( |
uint32_t |
address, |
|
|
uint32_t |
length |
|
) |
| |
This function invalidates the CACHE lines by address and length.
- Parameters
-
[in] | address | is the start address of the memory that is invalidated. |
[in] | length | is the length of memory that to be invalidated.The unit of the memory length is in bytes and both address and length must be CACHE line size aligned when the API is called. |
- Returns
- HAL_CACHE_STATUS_OK, the CACHE is successfully invalidated.
HAL_CACHE_STATUS_INVALID_PARAMETER, either address or length is not CACHE line size aligned. The alignment requires that the address and the length of a CACHE line must be a multiple of HAL_CACHE_LINE_SIZE.
This function invalidates a CACHE line at a given address.
- Parameters
-
[in] | address | is the start address of the memory that is invalidated. |
- Returns
- HAL_CACHE_STATUS_OK, the CACHE is successfully invalidated.
HAL_CACHE_STATUS_INVALID_PARAMETER, address is not CACHE line size aligned. The alignment requires that the address of a CACHE line must be a multiple of HAL_CACHE_LINE_SIZE.
bool hal_cache_is_cacheable |
( |
uint32_t |
address | ) |
|
This function checks whether the memory is cacheable.
- Parameters
-
[in] | address | is the memory address to check. |
- Returns
- return true, the memory is cacheable.
return false, the memory is non-cacheable.