STM32F7과 STM32H7 의 L1 캐시에 대해

Cortex®-M7 프로세서의 MPU(메모리 보호 장치)를 사용하면 영역별로 Level 1(L1) 캐시 속성(Attributes)을 수정할 수 있습니다. 캐시는 캐시 제어 레지스터에 의해 전역적으로 제어되지만 MPU는 캐시 모드와 영역에 대한 액세스를 캐시할 수 있는지 여부를 지정할 수 있습니다.

경우에 따라 캐시된 시스템은 공유 데이터를 처리할 때 코어와 주 메모리 간의 데이터 일관성을 보장해야 합니다. 이 애플리케이션 노트는 레벨 1 캐시 동작을 설명하고 L1 캐시를 사용할 때 STM32F7 시리즈 및 STM32H7 시리즈에서 데이터 일관성을 보장하는 방법을 보여주는 예를 제공합니다.

MPU 및 메모리 유형 및 캐시 정책에 따라 메모리 속성을 설정하는 방법에 대한 자세한 내용은 http://www.st.com에서 제공되는 다음 문서를 참조할 수 있습니다.

• STM32F7 시리즈 및 STM32H7 시리즈 Cortex®-M7 프로세서 프로그래밍 매뉴얼(PM0253).

• STM32 MCU(AN4838)에서 메모리 보호 장치(MPU) 관리.

Cache control

STM32F7 시리즈 및 STM32H7 시리즈는 명령어와 데이터 모두에 대해 최대 16KB의 L1 캐시를 포함합니다. L1 캐시는 CPU 근처에 일련의 데이터 또는 명령을 저장하므로 CPU는 작은 루프와 같이 반복적으로 사용되는 경우 동일한 데이터를 계속 가져올 필요가 없습니다.

그림 1. STM32F7 시리즈 시스템 아키텍처는 STM32F7 시리즈 시스템 아키텍처의 예를 보여줍니다.

하위 시스템(Subsystem)에 대한 메모리 액세스는 여러 주기가 걸릴 수 있으며(특히 여러 대기 상태가 있는 외부 메모리 인터페이스에서) 이러한 이유로 캐시는 메모리에 대한 읽기/쓰기 작업의 속도를 높이기 위한 것입니다.

데이터가 로컬에서(액세스하는 데 한 주기만 걸리는 영역에서) 사용할 수 있는 경우 두 작업을 모두 최적화할 수 있다는 아이디어입니다. 실행하는 데 두 개 이상의 CPU 주기가 필요한 하위 시스템(Subsystem) 메모리에 대한 버스 액세스는 CPU 파이프라인 명령 스트림 실행과 다릅니다. 이를 통해 성능이 크게 향상됩니다.

캐시는 일반적으로 라인이 메모리의 짧은 세그먼트인 라인 세트를 사용하여 구현됩니다. 집합의 줄 수를 x-way 연관이라고 합니다. 이 속성은 하드웨어 디자인에서 설정됩니다. 읽기는 위치에 처음 액세스할 때만 메모리에서 위치를 가져옵니다. 쓰기는 메모리를 통해 값을 푸시하거나(write-through 모드) 나중에 쓰기를 위해 캐시에 저장합니다(write-back 모드). 각 모드에는 응용 프로그램에 따라 가중치를 적용해야 하는 성능과 관련하여 장단점이 있습니다.

메모리가 다시 쓰기인 경우 캐시 라인은 Dirty로 표시되고 쓰기는 라인이 제거될 때 AXIM 인터페이스에서만 수행됩니다. Dirty 캐시 라인이 제거되면 데이터는 AXIM 인터페이스의 쓰기 버퍼로 전달되어 외부 메모리 시스템에 기록됩니다.

모든 Cortex®-M7의 L1 캐시는 32바이트 행으로 나뉩니다. 각 줄에는 주소가 태그로 지정됩니다. 데이터 캐시는 4-way 집합 연관(세트당 4줄)이고 명령 캐시는 2-way 집합 연관입니다. 이것은 주소로 각 행에 태그를 지정하지 않아도 되는 하드웨어 절충안입니다.

캐시 적중(cache hit)은 주소가 주어진 라인 세트 내 임의의 위치에 있을 때입니다. 따라서 하드웨어는 해당 주소가 캐시되었는지 확인하기 위해 더 적은 수의 주소를 수행해야 합니다. 적중이 있으면 캐시 값이 읽기에 사용되거나 값이 쓰기에 저장됩니다. 누락(miss)이 있는 경우 새 행이 할당되고 태그가 지정되며 읽기 또는 쓰기 액세스에서 캐시가 채워집니다. 모든 라인이 할당되면 캐시 컨트롤러는 라인 제거 프로세스를 실행합니다. 여기서 라인이 선택되고(교체 알고리즘에 따라) 정리/무효화 및 재할당됩니다.

데이터 캐시와 명령어 캐시는 의사 랜덤 교체 알고리즘을 구현합니다. L1 캐시는 AXI 버스의 메모리 인터페이스와 함께 사용할 때 성능을 높일 수 있습니다. 이것은 캐시할 수 없는 TCM(Tightly Couple Memory) 인터페이스의 메모리와 혼동되어서는 안 됩니다. 위에서 설명한 대로 모든 일반 메모리 영역을 캐시할 수 있지만 가장 큰 이득은 내부 플래시 메모리, 내부 SRAM 및 FMC 또는 Quad-SPI 컨트롤러에 연결된 외부 메모리와 같이 AXI 버스에서 액세스하는 메모리에서 볼 수 있습니다.

네 가지 기본 캐시 작업(활성화, 비활성화, 정리 및 무효화)이 있습니다. 이러한 작업을 위한 전용 API를 STM32F7 및 STM32H7 Cube 펌웨어 패키지에서 사용할 수 있으므로 개발 시간이 단축됩니다.

Accessing the Cortex®-M7 cache maintenance operations using CMSIS

core_cm7.h에 정의된 CMSIS 캐시 기능은 표 1에 나와 있습니다.

• Cache clean: 작업이 더티 캐시 라인을 메모리에 다시 씁니다(때때로 플러시라고 하는 작업).

• Invatlidate cache: 작업이 내용을 유효하지 않은 것으로 표시합니다(기본적으로 삭제 작업).

Cache operation

캐시 사용은 가장 기본적인 수준으로 간단합니다. 사용자는 MPU에서 영역을 설정하고 위에 나열된 CMSIS 기능을 통해 캐시를 활성화하기만 하면 됩니다. 예를 들어 사용자는 후기입 또는 연속 기입을 사용하여 항목을 설정할 수 있습니다.

• Write-back(후기입): 캐시는 정리 작업이 완료될 때까지 캐시 내용을 메모리에 쓰지 않습니다.

• Write-through(연속 기입): 캐시 라인의 내용이 기록되는 즉시 메모리에 대한 쓰기를 트리거합니다. 이것은 데이터 일관성을 위해 더 안전하지만 더 많은 버스 액세스가 필요합니다. 실제로 메모리에 대한 쓰기는 백그라운드에서 수행되며 동일한 캐시 세트가 반복적으로 매우 빠르게 액세스되지 않는 한 약간의 효과가 있습니다. 항상 절충되어야 할 요소입니다.

STM32F7 and STM32H7 default settings

기본적으로 MPU는 비활성화 상태이며 이 경우 캐시 설정은 기본 Address map으로 되어 있습니다.

Example for cache maintenance and data coherency

이 예제의 목적은 ARM® Cortex®-M7 데이터 캐시 일관성에 익숙해지는 것입니다.

처음에 CPU는 플래시 메모리 "aSRC_Const_Buffer"에서 SRAM1 임시 버퍼 "pBuffer"로 128바이트 상수 패턴을 복사합니다. 그런 다음 CPU는 DMA가 메모리 대 메모리 전송을 수행하여 SRAM1 "pBuffer" 에서 DTCM RAM에 정의된 대상 버퍼 "aDST_Buffer"로 복사하도록 구성하고 활성화합니다.

마지막으로 CPU는 DMA aDST_Buffer가 읽은 데이터를 플래시 메모리(aSRC_Const_Buffer)의 상수 패턴과 비교합니다.

그림 2. 데이터 전송 경로는 데이터 전송 경로를 보여줍니다.

그 목적은 다시 쓰기 속성이 설정된 캐시 가능 메모리 영역에 액세스할 때 CPU와 DMA 간의 데이터 일관성에 미치는 영향을 보여주는 것입니다.

기본적으로 Reset 후에는 데이터 및 명령 캐시가 비활성화됩니다. 데이터 캐시가 비활성화되면 SRAM1과 DTCM RAM 간의 데이터 전송이 위에서 설명한 시나리오에서 성공적으로 수행됩니다.

만약 설명된 전송 시나리오를 실행하기 전에 데이터 캐시를 활성화하면 "aDST_Buffer"(DTCM의 DMA 대상 버퍼)와 "aSRC_Const_Buffer"(플래시 메모리의 CPU 데이터 소스 버퍼)에 있는 데이터 간에 데이터 불일치가 감지됩니다.

L1 캐시를 사용할 때 항상 캐시 일관성이라고 하는 지속적인 문제가 있습니다. 이 문제는 여러 마스터(CPU, DMA...)가 메모리를 공유할 때 발생합니다. CPU가 Write-back 캐시 속성이 있는 영역(예: SRAM1)에 무언가를 쓰는 경우 액세스가 버퍼링될 때 처럼 쓰기 결과가 SRAM에 표시되지 않고 DMA가 데이터를 수행하기 위해 동일한 메모리 영역을 읽는 경우 전송 시 읽은 값이 의도한 데이터와 일치하지 않습니다.

Solution 1: CMSIS 함수 SCB_CleanDCache()를 통해 소프트웨어에 의해 D-캐시 정리 작업을 강제하여 캐시 가능한 메모리 영역에 데이터를 쓴 후 캐시 유지 관리 작업을 수행합니다(모든 Dirty 라인은 SRAM1에 Write-back).

Solution 2: 캐시 일관성을 보장하기 위해 사용자는 다시 쓰기(기본값)에서 연속 쓰기 정책으로 SRAM1의 MPU 속성을 수정해야 합니다.

Solution 3: 공유 속성을 사용하여 SRAM1의 MPU 속성을 수정합니다. 이것은 기본적으로 SRAM1이 D-캐시에 캐시되는 것을 방지합니다.

Solution 4: 모든 쓰기에 대해 연속 기록 정책을 적용하여 캐시 유지 관리 작업을 수행합니다. 이것은 CACR 제어 레지스터의 D-캐시 비트에서 강제 기록을 설정하여 활성화할 수 있습니다.

코어와 DMA 간의 데이터 일관성은 다음을 통해 보장됩니다.

1. SRAM1 버퍼를 캐시할 수 없도록 만들기

2. 또는 소프트웨어에 의해 보장된 일관성과 함께 Write-back(후기입) 정책으로 SRAM1 버퍼 캐시를 활성화합니다

(D-캐시 정리 또는 무효화).

3. 또는 MPU 속성의 SRAM1 영역을 공유 영역(Shared region)으로 수정합니다.

4. 또는 Write-through(연속 기입) 정책으로 SRAM1 버퍼 캐시를 활성화합니다.

또 다른 경우는 DMA가 SRAM1에 쓰고 CPU가 SRAM1에서 데이터를 읽을 때입니다. 캐시와 SRAM1 간의 데이터 일관성을 보장하기 위해 소프트웨어는 SRAM1에서 업데이트된 데이터를 읽기 전에 캐시 무효화를 수행해야 합니다.

캐시 유지 관리 작업에 대한 자세한 내용은 STM32F7 시리즈 및 STM32H7 시리즈 Cortex®-M7 프로세서 프로그래밍 매뉴얼(PM0253)의 캐시 유지 관리 작업 섹션을 참조하세요.

Mistakes to avoid and tips

• Reset 후 사용자는 활성화하기 전에 각 캐시를 무효화해야 합니다. 그렇지 않으면 예측할 수 없는 동작이 발생할 수 있습니다.

• 데이터 캐시를 비활성화할 때 사용자는 모든 Dirty 데이터가 외부 메모리로 플러시되도록 전체 캐시를 Clean해야 합니다.

• 데이터 캐시를 활성화하기 전에 캐시가 비활성화된 이후 외부 메모리가 변경되었을 수 있는 경우 사용자는 전체 데이터 캐시를 무효화해야 합니다.

• 명령 캐시를 활성화하기 전에 캐시가 비활성화된 이후 외부 메모리가 변경되었을 수 있는 경우 사용자는 전체 명령어 캐시를 무효화해야 합니다.

• 소프트웨어가 DMA 소스/또는 대상 버퍼에 대해 캐시 가능한 메모리 영역을 사용하는 경우. 소프트웨어는 모든 데이터가 하위 시스템 메모리에 커밋되도록 DMA 작업을 시작하기 전에 캐시 정리를 트리거해야 합니다. DMA 전송이 완료된 후 주변 장치에서 데이터를 읽을 때 소프트웨어는 DMA 업데이트된 메모리 영역을 읽기 전에 캐시 무효화를 수행해야 합니다.

• DMA 버퍼에 대해 캐시할 수 없는(Non-cacheable) 영역을 사용하는 것이 항상 더 좋습니다. 소프트웨어는 MPU를 사용하여 캐시할 수 없는 메모리 블록을 설정하여 CPU와 DMA 간의 공유 메모리로 사용할 수 있습니다.

• DMA 작업에 광범위하게 사용되는 메모리에 대해 캐시를 활성화하지 마십시오.

• ART accelerator를 사용할 때 CPU는 내부 플래시 메모리(예: 0-wait 상태)로 부터 단 1클록안에서 명령을 읽을 수 있습니다. 따라서 내부 플래시 메모리에는 I-캐시를 사용할 수 없습니다.

• NOR 플래시를 사용할 때 삭제 및 쓰기 명령이 이 외부 플래시 메모리로 전송되지 않기 때문에 Write-back이 문제를 일으킵니다.

• 연결된 장치가 일반 메모리인 경우 D-캐시 읽기가 유용합니다. 그러나 외부 장치가 ASIC 및/또는 FIFO인 경우 사용자는 읽기를 위해 D-캐시를 비활성화해야 합니다.