Спілкування з контролером dma - системи прямого доступу до пам'яті

Після реєстрації основна частина роботи драйвера полягає в налаштуванні для належного функціонування контролера DMA. Це завдання не тривіальна, але, на щастя, ядро ​​експортує всі функції, необхідні для типового драйвера.

Драйверу необхідно налаштувати контролер DMA або коли викликаються read або write. або при підготовці до асинхронним передачам. Ця остання задача виконується або під час відкриття. або у відповідь на команду ioctl. в залежності від драйвера і політики, яку він реалізує. Код, наведений тут, являє собою код, який зазвичай викликається методами пристрої read або write.

У цьому розділі наводиться короткий огляд нутрощів контролера DMA, щоб ви зрозуміли наведений тут код. Якщо ви хочете дізнатися більше, ми б настійно закликали вас прочитати і деякі керівництва до обладнання з описом архітектури ПК. Зокрема, ми не маємо справу з питанням про 8-ти розрядних передач даних замість 16-ти розрядних. Якщо ви пишете драйвери пристроїв для плат ISA пристроїв, для таких пристроїв вам слід знайти відповідну інформацію в керівництві по обладнанню.

Контролер DMA є ресурсом і могла б виникнути плутанина, якби його спробував запрограмувати одночасно більш ніж один процесор. З цієї причини контролер захищений спін-блокуванням, званої dma_spin_lock. Драйверів не слід маніпулювати з цієї блокуванням безпосередньо, проте, щоб зробити це, для вас надані дві функції:

unsigned long claim_dma_lock ();

Набуває спін-блокування DMA. Ця функція також блокує переривання на місцевому процесорі; тому повертається значення являє собою набір прапорів, що описують попередній стан переривання; він повинен бути переданий наступної функції для відновлення стану переривання, коли ви завершили роботу з блокуванням.

void release_dma_lock (unsigned long flags);

Повертає спін-блокуванням DMA і відновлює попередній статус переривання.

При використанні функцій, описаних далі, повинна утримуватися спін-блокування. Однак, не слід її утримувати в ході фактичного введення / виведення. При утриманні спін-блокування драйвер ніколи не повинен засипати.

void set_dma_mode (unsigned int channel, char mode);

void set_dma_addr (unsigned int channel, unsigned int addr);

void set_dma_count (unsigned int channel, unsigned int count);

Задає кількість байт для передачі. Аргумент count представляє число байтів також і для 16-ти розрядних каналів; в цьому випадку число повинне бути парним.

На додаток до цих функцій існує ряд можливостей для ведення домашнього господарства, які повинні використовуватися при роботі з пристроями DMA:

void disable_dma (unsigned int channel);

Канал DMA може бути відключений в контролері. Для запобігання збоїв в роботі, до того, як налаштований контролер, канал повинні бути відключений. (В іншому випадку, може виникнути пошкодження, оскільки контролер програмується за допомогою 8-ми розрядних передач даних і, отже, жодна з попередніх функцій не виконується атомарному).

void enable_dma (unsigned int channel);

Ця функція повідомляє контролеру, що канал DMA містить достовірні дані.

int get_dma_residue (unsigned int channel);

Іноді драйверу необхідно знати, коли передача DMA завершена. Ця функція повертає кількість байтів, які ще не передані. Значення, що повертається 0 після успішної передачі і непередбачувано (але не 0), поки контролер працює. Непередбачуваність виходить з необхідності отримання 16-ти розрядного залишку через дві 8-ми розрядні операції введення.

void clear_dma_ff (unsigned int channel);

Ця функція очищає тригер (flip-flop, регістр даних) DMA. Тригер використовується для управління доступом до 16-ти розрядних регістрів. Регістри доступні через дві послідовні 8-ми розрядні операції, а для вибору молодшого байта (коли він очищається), або старшого байта (якщо він встановлюється) використовується тригер. Після передачі восьми біт тригер автоматично змінює стан; перед зверненням до регістрів DMA програміст повинен очистити тригер (щоб встановити його в відоме стан).

Використовуючи ці функції, для підготовки до передачі DMA драйвер може реалізувати наступну функцію:

int dad_dma_prepare (int channel, int mode, unsigned int buf, unsigned int count)

unsigned long flags;

Потім для перевірки для успішного завершення DMA використовується наступна функція:

int dad_dma_isdone (int channel)

unsigned long flags = claim_dma_lock ();

return (residue == 0);

Єдине, що залишається зробити, це налаштувати плату пристрою. Це завдання залежить від пристрою і зазвичай складається в читанні або записі кількох портів введення / виводу. Пристрої відрізняються дуже сильно. Наприклад, деякі пристрої очікують, що програміст повідомить обладнанню, наскільки великий буфер DMA, а іноді драйвер повинен прочитати значення, які перебувають у пристрої. Для настройки плати вашим єдиним другом буде керівництво по обладнанню.

Закон функціонування автомата Мілі задається рівняннями:

Закон функціонування автомата Мура задається рівняннями:

Стек (англ. Stack - стопка; Новомосковскется стек) - абстрактний тип даних, що представляє собою список елементів, організованих за принципом LIFO (англ. Lastin - firstout. «Останнім прийшов - першим вийшов»).

Кеш - проміжний буфер з швидким доступом, що містить інформацію, яка може бути запрошена з найбільшою ймовірністю. Доступ до даних в кеші здійснюється швидше, ніж вибірка вихідних даних з більш повільної пам'яті або віддаленого джерела, однак її обсяг істотно обмежений у порівнянні зі сховищем вихідних даних.

Кеш-пам'ять, яка зазвичай відсутня в найпростіших процесорних пристроях. У більш складних ЕОМ кеш має кілька рівнів, причому кеш верхнього рівня завжди знаходиться в кристалі процесора

Переривання (англ. Interrupt) - сигнал, що повідомляє процесору про настання якої-небудь події. При цьому виконання поточної послідовності команд припиняється і керування передається обробнику переривання, який реагує на подію і обслуговує його, після чого повертає управління в перерваний код

Залежно від джерела виникнення сигналу переривання діляться на:

· Асинхронні, або зовнішні (апаратні) - події, які виходять від зовнішніх джерел (наприклад, периферійних пристроїв) і можуть статися в будь-який довільний момент: сигнал від таймера, мережевої карти або дискового накопичувача, натискання клавіш клавіатури, рух миші. Факт виникнення в системі такого переривання трактується як запит на переривання (англ. Interruptrequest, IRQ);

· Програмні (окремий випадок внутрішнього переривання) - ініціюються виконанням спеціальної інструкції в коді програми. Програмні переривання, як правило, використовуються для звернення до функцій програмно-апаратних засобів (firmware), драйверів і операційної системи.

Прямий доступ до пам'яті. Процесор в передачі даних не бере. Він відключається від системної магістралі, а всі операції обміну даними йдуть під управлінням спеціального керуючого пристрою - контролера ПДП. Цей режим використовується для швидкодіючих ПУ, коли пропускної здатності процесора недостатньо.

Шина пам'яті призначена для передачі інформації між ОП і МП, а також ВП і ПУ в режимі ПДП. Інформація по шині пам'яті передається із значно меншою швидкістю, ніж по шині процесора. Це пов'язано з тим, що шина пам'яті містить менше ліній даних. Їх число визначається шириною вибірки. Крім того, як вже зазначалося, швидкодія мікросхем пам'яті завжди відстає від швидкодії процесора, тому процес передачі інформації по шинам пам'яті і процесора.

Якщо Ви помітили помилку в тексті виділіть слово і натисніть Shift + Enter