STM32 DMA Təlimatı – STM32-də Birbaşa Yaddaş Girişindən İstifadə
Bu yazıda biz STM32 mikrokontrollerlərində “birbaşa yaddaş girişi” bölməsini (DMA – Direct Memory Access) müzakirə edəcəyik. DMA aparatının(elementinin) nə olduğu, nə vaxt və nə üçün istifadə ediləcəyi ilə bağlı girişlə başlayacağıq. Bundan sonra biz STM32 DMA aparatını, onun xüsusiyyətlərini və layihələrinizdə onu necə konfiqurasiya edəcəyinizi müzakirə etməyə başlayacağıq. Və bu kurs boyu quracağımız bəzi nümunə tətbiqlərlə tanış olacağıq.
Direct Memory Access (DMA) nədir?
Birbaşa Yaddaş Girişi (DMA) elementi kompüter arxitekturasında yaddaş ötürmə əməliyyatlarını boşaltmaq üçün eyni çipdəki əsas mikroprosessorla birlikdə istifadə edilə bilən rəqəmsal məntiq elementidir. Bu, CPU yükünü əhəmiyyətli dərəcədə azaldır. Çünki DMA nəzarətçisi (kontrolleri) yaddaşdan yaddaşa məlumat ötürülməsi, eləcə də periferikdən yaddaşa məlumat ötürülməsi və ya əksinə həyata keçirə bilər. CPU ilə DMA-nın mövcudluğu onun ötürmə qabiliyyətini böyük ölçüdə sürətləndirə bilər.
DMA olmayan kompüter arxitekturasında siz onun aşağıdakı diaqramda göstərildiyi kimi göründüyünü görərsiniz.
Gördüyünüz kimi, CPU (əsas prosessor) flaşdan təlimatların (kodların) alınması, deşifrə edilmiş təlimatların yerinə yetirilməsi, məlumatların periferiya və yaddaşa köçürülməsi ilə bağlı bütün işləri görməlidir. Təsəvvür edin ki, hər hansı bir məlumat paketini itirməmək üçün CPU dərhal yaddaşdakı yerli buferə köçürməli olduğu məlumat axını əldə edən UART1 məlumat qəbuledicisi var. Bu, UART, SPI, ADC və s. kimi müxtəlif periferik qurğular tərəfindən saniyədə çılğın sayda kəsilmələrə (interrupt) çevrilir. Və CPU hər şeyi idarə etməli və getdikcə daha çox vaxt itirməlidir.
Kəsmə(interrupt) işləyiciləri ilə kontekstin (mənbənin) dəyişdirilməsi və kəsmə işləyicilərindən (interrupt handlers) keçidin bəzən tamamilə boşa çıxmış dövrlərin alınması və davamlı kəsmə siqnallarının işə salınması səbəbindən vaxtaşırı baş verməsi bu arxitekturanı bir qədər problemli edir. 10kB/s məlumat axınına malik olmaq, DMA-sı olmayan CPU-nu çox məşğul edə bilər və qurğu üçün vaxt məhdudiyyətlərini əldən verə bilər. CPU sıxılmış(yüklənmiş) kimi görünə bilər və tam işləmə gücünü ortaya çıxarmaq üçün bu məlumat ötürmə tapşırığı başqa bir bölməyə təhvil verilməlidir və burada bu yorucu məlumat əməliyyatlarını CPU-dan boşaltmaq üçün DMA bölməsi gəlir.
Yuxarıdakı diaqramda gördüyünüz kimi, DMA bölməsinin mövcudluğu indi UART periferiyasından gələn məlumat axınını birbaşa yaddaşa yönləndirə bilər, prosessor isə digər işlər və hesablamalar həyata keçirir. CPU və DMA arasındakı bu paralel əməkdaşlıq sürətlənmənin qaynaqlandığı yerdir.
DMA bölməsinin mövcudluğu bəzən bəzi problemlər yarada bilər. Məsələn, DMA elementi məlumat yaddaşına daxil olduqda (müraciət etdikdə) və keş yaddaşında əks olunan yerə yazdıqda CPU keşi olan bir arxitekturada bu, keş yaddaşındakı məlumatları etibarsız edəcək. Bunun aradan qaldırılması çətin bir işdir və başqa problemlər də var, lakin bu gələcək məqalə üçün mövzu olacaq. Mən sadəcə bu nöqtəyə bir qədər işıq salmaq istədim, DMA faydalı olmaqla yanaşı bəzi məsələləri də təqdim edə bilər.
STM32 DMA aparatı (DMA Hardware)
STM32F103C8T6 üçün (“Blue Pill” MCU)
Birbaşa yaddaşa giriş (DMA) periferik qurğular və yaddaş, eləcə də yaddaşdan yaddaşa yüksək sürətli məlumat ötürülməsini təmin etmək üçün istifadə olunur. Data heç bir CPU hərəkəti olmadan DMA tərəfindən sürətlə köçürülə bilər. Bu, CPU resurslarını digər əməliyyatlar üçün boş saxlayır.
İki DMA nəzarətçisində (kontrollerində) cəmi 12 kanal var (DMA1 üçün 7 və DMA2 üçün 5), hər biri bir və ya daha çox periferiyadan yaddaşa giriş sorğularını idarə etməyə həsr olunub. DMA sorğuları arasında prioriteti idarə etmək üçün vasitəçiyə (arbiter) malikdir.
The two DMA controllers have 12 channels in total (7 for DMA1 and 5 for DMA2), each dedicated to managing memory access requests from one or more peripherals. It has an arbiter for handling the priority between DMA requests.
DMA nəzarətçisi sistem “şin”ini (bus) Cortex®-M3 nüvəsi ilə paylaşaraq birbaşa yaddaş ötürməsini həyata keçirir. DMA sorğusu CPU və DMA eyni təyinat yerini (yaddaş və ya periferik) hədəflədikdə bəzi məlumat yolu (şin) dövrləri üçün CPU-nun sistem şininə çıxışını dayandıra bilər. Şin matrisi döngü sistemli planlaşdırmanı həyata keçirir, beləliklə, CPU üçün sistem şininin bant genişliyinin ən azı yarısını (həm yaddaşa, həm də periferiyaya) təmin edir.
STM32F103-dəki DMA Bölmələri Aşağıdakı Xüsusiyyətlərə malikdir
- 12 müstəqil şəkildə konfiqurasiya edilə bilən kanal (sorğular): DMA1 üçün 7 və DMA2 üçün 5
- 12 kanalın hər biri xüsusi aparat DMA sorğularına bağlıdır, proqram tətikləyicisi də hər kanalda dəstəklənir. Bu konfiqurasiya proqram təminatı ilə həyata keçirilir.
- Bir DMA-nın kanallarından gələn sorğular arasında prioritet, proqramlaşdırıla bilən proqram təminatı (çox yüksək, yüksək, orta, aşağı səviyyələrdən ibarət 4 səviyyə) və ya bərabərlik halında aparat təminatıdır (sorğu 1 sorğu 2-dən üstündür və s.)
- Müstəqil mənbə və təyinat köçürmə ölçüsü (Independent source and destination transfer size)(bayt, yarım söz, söz), paketləmə və paketdən çıxarma (emulating packing, and unpacking). Mənbə/təyinat ünvanları məlumat ölçüsünə uyğunlaşdırılmalıdır.
- Dairəvi bufer idarəetməsi üçün dəstək
- 3 event flags (DMA Yarım Transfer, DMA Transferi tamamlandı və DMA Transfer Xətası) məntiqi ORed olaraq hər bir kanal üçün tək kəsmə sorğusunda bir araya toplandı.
- Yaddaşdan yaddaşa köçürmə
- Periferiyadan yaddaşa və yaddaşdan periferiyaya və periferikdən periferikə köçürmələr
- Flash, SRAM, APB1, APB2 və AHB periferiyalarına mənbə və təyinat yeri kimi giriş
- Köçürüləcək məlumatların proqramlaşdırıla bilən sayı: 65536-a qədər
DMA Məlumat Əməliyyatları (Data Transactions)
“Event”-dən sonra periferiya DMA Nəzarətçisinə sorğu siqnalı göndərir. DMA nəzarətçisi kanal prioritetlərindən asılı olaraq sorğuya xidmət edir. DMA Nəzarətçisi periferiyaya daxil olan kimi, DMA Nəzarətçisi tərəfindən periferiyaya təsdiq (Acknowledge) göndərilir. Periferiya DMA Nəzarətçisindən təsdiq alan kimi sorğunu buraxır. Sorğu periferiya tərəfindən təsdiqləndikdən sonra DMA Nəzarətçisi təsdiqləməni buraxır. Daha çox sorğu olarsa, periferiya növbəti əməliyyata başlaya bilər.
Xülasə, hər bir DMA transferi üç əməliyyatdan ibarətdir:
- Periferik məlumat registrinə və ya daxili cari periferik/yaddaş ünvan registrindən istifadə edərək ünvanlanan yaddaşdakı yerdən məlumatların yüklənməsi. (The loading of data from the peripheral data register or a location in memory addressed through an internal current peripheral/memory address register.). İlk köçürmə üçün istifadə edilən başlanğıc ünvanı DMA_CPARx və ya DMA_CMARx registrində proqramlaşdırılmış əsas periferik/yaddaş ünvanıdır.
- Daxili cari periferik/yaddaş ünvan registrindən istifadə etməklə periferik məlumat registrinə və ya yaddaşda yerləşdiyi yerə yüklənmiş məlumatların saxlanması. İlk köçürmə üçün istifadə edilən başlanğıc ünvanı DMA_CPARx və ya DMA_CMARx registrində proqramlaşdırılmış əsas periferik/yaddaş ünvanıdır.
- Hələ yerinə yetirilməli olan əməliyyatların sayını ehtiva edən DMA_CNDTRx registrinin azaldılması.
DMA Arbitri
Arbitr kanal sorğularını onların prioriteti əsasında idarə edir və periferik/yaddaş giriş ardıcıllığını işə salır. Prioritetlər iki mərhələdə idarə olunur:
- Proqram təminatı: hər bir kanal prioriteti DMA_CCRx registrində konfiqurasiya edilə bilər. Dörd səviyyə var:
- -Çox yüksək prioritet
- -Yüksək prioritet
- -Orta prioritet
- Aşağı prioritet
- Avadanlıq: Əgər 2 sorğu eyni proqram təminatının prioritet səviyyəsinə malikdirsə, ən aşağı nömrəyə malik kanal ən yüksək nömrəyə malik kanala qarşı prioritet əldə edəcək. Məsələn, 2-ci kanal 4-cü kanala üstünlük verir.
DMA kanalları
Hər bir kanal sabit ünvanda yerləşən periferik registr və yaddaş ünvanı arasında DMA transferini idarə edə bilər. Köçürüləcək məlumatların miqdarı (65535-ə qədər) proqramlaşdırıla bilər. Köçürüləcək məlumat elementlərinin miqdarını ehtiva edən registr hər əməliyyatdan sonra azalır (decremented).
Periferiya və yaddaşın ötürülən məlumat ölçüləri DMA_CCRx registrindəki PSIZE və MSIZE bitləri vasitəsilə tam proqramlaşdırıla bilir.
Periferik və yaddaş göstəriciləri DMA_CCRx registrindəki PINC və MINC bitlərindən asılı olaraq hər əməliyyatdan sonra isteğe bağlı olaraq avtomatik əlavə oluna bilər. Artırılmış (incremented) rejim aktivdirsə, növbəti köçürmənin ünvanı seçilmiş məlumat ölçüsündən asılı olaraq 1, 2 və ya 4 artırılan əvvəlkinin ünvanı olacaq.
DMA dairəvi rejimi (DMA Circular Mode)
Dairəvi rejim dairəvi buferləri və davamlı məlumat axınlarını idarə etmək üçün mövcuddur (məsələn, ADC skan rejimi). Bu funksiya DMA_CCRx registrindəki CIRC bitindən istifadə etməklə aktivləşdirilə bilər. Dairəvi rejim aktivləşdirildikdə, ötürüləcək məlumatların sayı kanalın konfiqurasiya mərhələsində proqramlaşdırılmış ilkin dəyərlə avtomatik olaraq yenidən yüklənir və DMA sorğularına xidmət göstərilməyə davam edir.
DMA Yaddaşdan Yaddaşa Rejim (DMA Memory-To-Memory Mode)
DMA kanalları da periferiyadan gələn sorğu ilə işə düşmədən işləyə bilər. Bu rejim Yaddaşdan Yaddaşa rejimi adlanır. Yaddaşdan Yaddaşa rejimi Dairəvi rejimlə eyni vaxtda istifadə edilə bilməz.
STM32 DMA kəsmələri (STM32 DMA Interrupts)
Hər bir DMA kanalı üçün Yarım köçürmə, Köçürmə tamamlandı və ya Köçürmə xətasında fasilə yarana bilər. (Half-transfer, Transfer complete, or Transfer error) .Çeviklik üçün ayrıca kəsilməyə imkan verən bitlər mövcuddur.
DMA Request Mapping
Periferik DMA sorğuları müvafiq periferik registrlərdə DMA idarəetmə bitini proqramlaşdırmaqla müstəqil olaraq aktivləşdirilə/deaktiv edilə bilər.
STM32 DMA Konfiqurasiyası
DMA CHANNELx-i konfiqurasiya etmək üçün aşağıdakı ardıcıllığa əməl edilməlidir (burada x kanal nömrəsidir).
- DMA_CPARx registrində periferik registr ünvanını təyin edin. Məlumat periferik hadisədən(event) sonra bu ünvandan yaddaşa/yaddaşdan köçürüləcək.
- DMA_CMARx registrində yaddaş ünvanını təyin edin. Məlumat periferik hadisədən sonra bu yaddaşa yazılacaq və ya ondan oxunacaq.
- DMA_CNDTRx registrində ötürüləcək məlumatların ümumi sayını konfiqurasiya edin. Hər periferik hadisədən sonra bu dəyər azalacaq.
- DMA_CCRx registrindəki PL[1:0] bitlərindən istifadə edərək kanal prioritetini konfiqurasiya edin
- DMA_CCRx registrində məlumat ötürmə istiqamətini, dairəvi rejimi, periferik və yaddaş artımı rejimini, periferik və yaddaş məlumat ölçüsünü konfiqurasiya edin və yarım və/və ya tam ötürülmədən sonra kəsin
- DMA_CCRx registrində ENABLE bitini təyin etməklə kanalı aktivləşdirin.
Kanal aktivləşdirildikdən sonra o, kanala qoşulmuş periferiyadan istənilən DMA sorğusuna xidmət edə bilər. Baytların yarısı köçürüldükdən sonra, yarım köçürmə bayrağı (half-transfer flag) (HTIF) təyin edilir və Yarım Transfer Kəsmə Aktiv biti (Half Transfer Interrupt Enable bit ) (HTIE) təyin olunarsa, kəsmə yaradılır. Köçürmənin sonunda Tam Transfer Bayrağı (Transfer Complete Flag) (TCIF) təyin edilir və Transfer Tam Kəsinti Aktiv biti (Transfer Complete Interrupt Enable bit ) (TCIE) təyin olunarsa, kəsmə yaradılır.
DMA elementlərini konfiqurasiya etmək və bufer uzunluqlarını, DMA mənbəyini, təyinatı və bütün digərləri proqramlı şəkildə təyin etmək üçün CubeMX proqram alətindən və HAL API-lərdən istifadə edəcəyik. Hər bir konfiqurasiya üçün dəqiq addımlar DMA-nın istifadə olunacağı gələcək yazılarda daha sonra müzakirə olunacaq.
STM32 DMA Nümunələri
STM32 mikrokontrollerlərində DMA elementləri üçün bir neçə istifadə halları var. Biz onlardan bəzilərini qarşıdakı dərsliklərin LAB-larında və layihələrində həyata keçirəcəyik. Bununla belə, burada bir neçə mümkün ssenari var:
- UART məlumatlarının terminaldan yerli buferə qəbulu.
- Capacitive touchPAD (toxunma panelləri) bağlı olan çoxlu kanallar üçün ADC dairəvi bufer çevrilmələri.
- Yüksək sürətli məlumat qeydi üçün SPI xarici yaddaş interfeysi.
- SPI kamera interfeysi.
- və daha çox…