آموزش STM32H7 | قسمت چهارم: مثال عملی I-Cache و D-Cache در STM32H745
مقدمه
پردازندهی STM32H745 از خانواده Cortex-M7 دارای حافظههای کش (Cache) سطح ۱ است که بهطور مستقیم روی عملکرد سیستم تأثیر میگذارد. در این آموزش، ما بهصورت عملی نشان میدهیم:
- کش دستورالعمل (I-Cache) چگونه سرعت اجرای برنامه را افزایش میدهد.
- کش داده (D-Cache) در چه شرایطی باعث ناسازگاری (Coherency) با DMA میشود.
- چگونه میتوان با استفاده از دستورهای Cache Maintenance این مشکل را حل کرد.
ویدئو آموزش STM32H7 | قسمت چهارم:
بخش اول – بررسی I-Cache در STM32H745
I-Cache چیست؟
Instruction Cache یا I-Cache بخشی از پردازنده است که دستورالعملهایی که از حافظه Flash خوانده میشوند را در خود نگه میدارد. در حالت عادی، هر بار اجرای دستور باید از Flash خوانده شود (که سرعت کمتری دارد). اما وقتی I-Cache فعال باشد، پردازنده بسیاری از دستورالعملهای پرکاربرد را مستقیم از کش اجرا میکند و این باعث افزایش چشمگیر سرعت میشود.

آزمایش عملی – تاثیر I-Cache
برای نشان دادن اثر I-Cache، یک حلقه ساده جمع اعداد اجرا کردیم. این حلقه یک بار با I-Cache خاموش و یک بار با I-Cache روشن تست شد.
;char msg[100]
// بدون I-Cache
SCB_DisableICache();
uint32_t t1 = HAL_GetTick();
test_loop();
uint32_t t2 = HAL_GetTick();
sprintf(msg, "Without I-Cache: %lu ms\r\n", (t2 - t1));
HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
// با I-Cache
SCB_EnableICache();
uint32_t t3 = HAL_GetTick();
test_loop();
uint32_t t4 = HAL_GetTick();
sprintf(msg, "With I-Cache: %lu ms\r\n", (t4 - t3));
HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
نتایج آزمایش
با نمایش زمان اجرای حلقه روی سریال، اختلاف کاملاً محسوس است.
بخش دوم – بررسی D-Cache و مشکل Coherency
D-Cache چیست؟
Data Cache یا D-Cache دادههایی را که CPU روی آنها کار میکند در خود ذخیره میکند. این کار باعث میشود دسترسی به دادهها بسیار سریعتر از حافظه اصلی (SRAM) انجام شود. اما زمانی که دستگاه دیگری مثل DMA بخواهد به همان حافظه دسترسی پیدا کند، ممکن است اختلافی بین داده موجود در کش CPU و داده موجود در SRAM واقعی ایجاد شود. این مشکل همان Cache Coherency است.

آزمایش عملی – خطای D-Cache
برای تست این مشکل:
- بافر مبدأ (src) توسط CPU پر میشود.
- DMA آن را به بافر مقصد (dst) کپی میکند.
- چون داده جدید هنوز در کش CPU است و به SRAM نوشته نشده، DMA داده قدیمی را منتقل میکند → نتیجه غلط میشود.
/* USER CODE BEGIN 2 */
char msg[100];
// فعالسازی D-Cache
SCB_EnableDCache();
fill_src_buffer();
// حالت مشکلدار: CPU داده را نوشته اما هنوز در کش است
// DMA داده قدیمی را از SRAM میخواند
HAL_DMA_Start(&hdma_memtomem_dma1_stream0, (uint32_t)src_buffer, (uint32_t)dst_buffer, BUFFER_SIZE);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma1_stream0, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
// احتمال عدم تطابق وجود دارد
for (int i = 0; i < BUFFER_SIZE; i++)
{
if (src_buffer[i] != dst_buffer[i])
{
sprintf(msg, "ERR\r\n");
HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
}
}
/* USER CODE END 2 */
رفع مشکل – استفاده از Cache Maintenance
برای حل این مشکل، باید قبل از DMA کش منبع را پاکسازی (Clean) کنیم تا داده به SRAM نوشته شود. بعد از انتقال هم کش مقصد را Invalidate میکنیم تا CPU داده بهروز را از حافظه بگیرد.
char msg[100];
// فعالسازی D-Cache
SCB_EnableDCache();
fill_src_buffer();
SCB_CleanDCache();
// حالت مشکلدار: CPU داده را نوشته اما هنوز در کش است
// DMA داده قدیمی را از SRAM میخواند
HAL_DMA_Start(&hdma_memtomem_dma1_stream0, (uint32_t)src_buffer, (uint32_t)dst_buffer, BUFFER_SIZE);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma1_stream0, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
// احتمال عدم تطابق وجود دارد
for (int i = 0; i < BUFFER_SIZE; i++)
{
if (src_buffer[i] != dst_buffer[i])
{
sprintf(msg, "ERR\r\n");
HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
}
}
نتایج آزمایش
- در حالت بدون مدیریت کش → تعداد زیادی mismatch بین src و dst مشاهده شد.
- با استفاده از Clean و Invalidate → دادهها بهطور کامل درست منتقل شدند.
جمعبندی قسمت چهارم
- فعال بودن I-Cache باعث افزایش چشمگیر سرعت اجرای کد میشود.
- D-Cache دسترسی CPU به دادهها را سریعتر میکند، اما هنگام کار با DMA یا واحدهای جانبی میتواند باعث ناسازگاری شود.
- راهحل:
- استفاده از توابع Cache Maintenance (Clean/Invalidate)
- یا تعریف نواحی Non-Cacheable در MPU برای حافظههایی که DMA روی آنها کار میکند.