HAL ICACHE Overview

Introducing ICACHE

group ICACHE_Introduction

The Instruction Cache (ICACHE) hardware abstraction layer provides a set of APIs to interface with the instruction cache peripheral on STM32 microcontrollers. It improves performance by reducing wait states when fetching instructions and data from internal and external memories.

It simplifies the configuration, initialization, and management of the ICACHE by supporting features such as cache associativity modes, memory address remapping, performance monitoring and error detection with interrupt capabilities.

This abstraction layer guarantees portability and ease of use across different STM32 series. The HAL ICACHE driver covers the instruction cache peripheral with support for multiple cache configurations and maintenance operations.

Module and files

The following diagram illustrates the ICACHE module and its associated files.

Module and files diagram

Component diagram

The following diagram illustrates the software components involved in the ICACHE module. It shows the interactions between the user application, HAL drivers, low-level drivers, and the hardware components.


@startuml

' The Driver name to be customized according to the driver
' Example CRC, I2C, NVM, FLASH, ....
!$ppp = "ICACHE"

' The HAL driver use a core driver - default value 0
!$use_ppp_core = 0

' When using a core driver : the core driver name
!$core = "XXX" + "_CORE"

' enable/disable LL RCC interfaces depandencies - default value 0
!$use_ll_rcc = 0

' the driver provide an LL layer : default value 1
' Set to 0 if core is set to 1
!if ($use_ppp_core == 1)
!$use_ppp_ll = 0
!else
!$use_ppp_ll = 1
!endif
' the driver provide a HAL Layer : default value 1
!$use_ppp_hal = 1

' the HAL driver use HAL services : default value 1
!$use_hal_service = 1

' the HAL driver use HAL RCC services : default value 1
!$use_hal_rcc = 0

' the HAL driver use HAL DMA services : default value 1
!$use_hal_dma = 0

' The driver use HAL_RCC_PPP_GetClockFreq()
!$use_kernel_clock = 1

' HAL driver use depandencies with generic instead of interfaces
!$use_hal_generic_dep = 0

' The driver use interrupts : default value 1
' Example CCB --> no interrupts
!$use_ppp_isr = 1

' The driver use an extented file : default value 0
' Example of Usage NVM, FLASH
!$use_hal_ppp_extend = 0

' The HAL Driver extension name
!$ppp_extend = "EXT"

' The HAL Driver interface
!$hal_api_itf = "HAL " + $ppp + " API"

' The HAL Driver extended interface
!$hal_api_ext_itf = "HAL " + $ppp + " " + $ppp_extend + " API"

' The Use Application Interface
!$appli_itf = $ppp+ " User Callback"
!$appli_ext_itf = "\n" + $ppp+ " " + $ppp_extend + " User Callback"

' The HAL PPP name
!$ppp_name = "HAL_" + $ppp
!$ppp_ext_name = "HAL_" + $ppp+ "_" + $ppp_extend

' The PPP isr
!$ppp_ISR = $ppp + " ISR"
!$ppp_ext_ISR = $ppp+ " " + $ppp_extend + " ISR"

' The LL Driver name
!$ll_ppp = "LL_" + $ppp

!$hal_dma_itf = "HAL_DMA_StartDirectXfer_IT_Opt()\nHAL_DMA_Abort_IT"
!if ($use_kernel_clock == 1)
!$hal_rcc_itf = "\t\t\tHAL_RCC_"+$ppp+"_GetClockFreq()\n\t\t\tHAL_RCC_"+$ppp+"_EnableClock()"
!else
!$hal_rcc_itf = "\t\t\tHAL_RCC_"+$ppp+"_EnableClock()"
!endif

!$hal_ppp_itf = "Half transfer complete\nTransfer complete\nError callback\nAbort callback"

' HAL Generic interface for the PPP driver
!$hal_generic_itf = "HAL_GetTick()"

!$ll_ppp_itf = "LL " + $ppp +" API"

' HW
!$ppp_xIRQ = $ppp+"x_IRQ"

<style>
componentDiagram {
arrow {
FontSize 8
}
interface {
FontSize 8
}
}
</style>

title $ppp Software Component Diagram

Package "Application Layer" {

component [Appli]
!if ($use_ppp_isr == 1)
interface "$appli_itf" as APPLI_Interface
[Appli] -r- APPLI_Interface
!if ($use_hal_ppp_extend == 1)
interface "$appli_ext_itf" as APPLI_EXT_Interface
[Appli] -l- APPLI_EXT_Interface
!endif
!endif
}

package "HAL" {
!if ($use_hal_ppp_extend == 1)
component [$ppp_name]
component [$ppp_ext_name]
!else
component [$ppp_name]
!endif
!if ($use_hal_dma == 1)
interface "$hal_ppp_itf" as HAL_PPP_Interface
[$ppp_name] -d- HAL_PPP_Interface
!endif
interface "$hal_api_itf" as HAL_PPP_APPLI_Interface
!if ($use_hal_ppp_extend == 1)
interface "$hal_api_ext_itf" as HAL_PPP_APPLI_EXT_Interface
[$ppp_name] -u- HAL_PPP_APPLI_Interface
[$ppp_ext_name] -u- HAL_PPP_APPLI_EXT_Interface
'[$ppp_ext_name] -u-(
[$ppp_name] ..> [$ppp_ext_name] : <<include>>
!else
[$ppp_name] -u- HAL_PPP_APPLI_Interface
!endif
!if ($use_hal_generic_dep == 0)
!if ($use_hal_service == 1)
component [HAL_SERVICE]
interface "$hal_generic_itf" as HAL_Service_Interface
[HAL_SERVICE] -r- HAL_Service_Interface
[$ppp_name] -l-( HAL_Service_Interface
!if ($use_hal_ppp_extend == 1)
[$ppp_ext_name] -r-( HAL_Service_Interface
!endif
!endif
!else
[HAL_SERVICE]
[$ppp_name] ..> [HAL_SERVICE]
!endif
!if ($use_hal_dma == 1)
component [HAL_DMA]
interface "$hal_dma_itf" as HAL_DMA_Interface
[HAL_DMA] -u- HAL_DMA_Interface
[HAL_DMA] -u-( HAL_PPP_Interface
[$ppp_name] --( HAL_DMA_Interface
!endif
!if ($use_hal_rcc == 1)
component [HAL_RCC]
interface "$hal_rcc_itf" as HAL_RCC_Interface
[HAL_RCC] -l- HAL_RCC_Interface
[$ppp_name] -r-( HAL_RCC_Interface
!endif

}

[Appli] -d-( HAL_PPP_APPLI_Interface
!if ($use_hal_ppp_extend == 1)
[Appli] -d-( HAL_PPP_APPLI_EXT_Interface
!endif
!if ($use_ppp_isr == 1)
[$ppp_name] -u-( APPLI_Interface
!if ($use_hal_ppp_extend == 1)
[$ppp_ext_name] -u-( APPLI_EXT_Interface
!endif
!endif
!if ($use_ppp_core ==1)
Package "Core Layer" #Lavender{
component [$core]
interface "core API" as Core_api_itf
[$core] -u- Core_api_itf
}
[$ppp_name] -d-( Core_api_itf
!endif
package "Low Layer" {
component "CMSIS-Devices"
!if ($use_ppp_ll == 1)
component [$ll_ppp]
interface "$ll_ppp_itf" as LL_PPP_Interface
[$ll_ppp] -u- LL_PPP_Interface
!endif

!if ($use_ppp_isr == 1)
interface "$ppp_ISR" as PPP_ISR
[$ppp_ISR] -u- PPP_ISR
component [$ppp_ISR]
!if ($use_hal_ppp_extend == 1)
  interface "$ppp_ext_ISR" as PPP_EXT_ISR
  [$ppp_ISR] -u- PPP_EXT_ISR
  [$ppp_ext_name] -d-( PPP_EXT_ISR
!endif
!endif


!if ($use_ll_rcc == 1)
  component [LL_RCC]
  interface "LL RCC API" as LL_RCC_API
  [LL_RCC] -u- LL_RCC_API
  [HAL_RCC] -d-(LL_RCC_API
!endif

!if ($use_hal_dma == 1)
  component [DMA ISR]
  interface "DMA ISR" as DMA_ISR
  [DMA ISR] -u- DMA_ISR
!endif
}

package "HW" {
component [STM32_HW]
!if ($use_ppp_isr == 1)
interface "$ppp_xIRQ" as PPPx_IRQ
[STM32_HW] -u- PPPx_IRQ
!endif
!if ($use_hal_dma == 1)
interface "DMAx_IRQ_Ch" as DMA_IRQ_CH
[STM32_HW] -u- DMA_IRQ_CH
[DMA ISR] -d-( DMA_IRQ_CH
[HAL_DMA] --( DMA_ISR
!endif
}
!if ($use_ppp_ll == 1)
!if ($use_hal_ppp_extend == 1)
[$ppp_ext_name] -d-( LL_PPP_Interface
!else
[$ppp_name] -d-( LL_PPP_Interface
!endif
[$ll_ppp] .r.> [CMSIS-Devices]: $ppp register def
[STM32_HW] <.u. [$ll_ppp] : $ppp registers R/W
!else
!if ($use_ppp_core == 1)
[$core] .l.> [CMSIS-Devices]: $ppp register def
[STM32_HW] <.u. [$core] : $ppp registers R/W
!else
[$ppp_name] .d.> [CMSIS-Devices]: $ppp register def
[STM32_HW] <.l. [$ppp_name] : $ppp registers R/W
!endif
!endif
!if ($use_ppp_isr == 1)
[$ppp_ISR] -d-( PPPx_IRQ
[$ppp_name] -d-( PPP_ISR
!endif
!if ($use_ll_rcc == 1)
[STM32_HW] <.u. [LL_RCC] : RCC registers R/W
!endif

@enduml

Configuration table

The following table lists the configuration defines for the HAL ICACHE module, specifying their locations, default values, and descriptions:

group ICACHE_Configuration_Table

Configuration inside the ICACHE driver :

Config defines

Description

Default value

Note

USE_HAL_ICACHE_MODULE

From hal_conf.h

1

Allows the use of the HAL ICACHE module.

USE_HAL_ICACHE_REGISTER_CALLBACKS

From hal_conf.h

0

Allows the use of the register callbacks.

USE_HAL_CHECK_PARAM

From hal_conf.h

0

Allows the use of run-time check parameters.

USE_ASSERT_DBG_PARAM

From IDE

None

Allows the use of assert check parameters.

USE_ASSERT_DBG_STATE

From IDE

None

Allows the use of assert check states.

USE_HAL_ICACHE_GET_LAST_ERRORS

From hal_conf.h

0

Allows the use of the error code mechanism.

USE_HAL_ICACHE_USER_DATA

From hal_conf.h

0

Allows the use of user data.