Реалізація системи управління реального часу в ОС Windows

[ виправити ] текст може містити помилки, будь ласка перевіряйте перш ніж використовувати.

скачати

Кафедра "Програмне забезпечення ЕОМ та інформаційні технології»
Курсова робота
на Тему: «Реалізація системи управління реального часу в ОС Windows»

Зміст

1. Введення
2. Конструкторська частина
2.1. Загальні принципи
2.2. Програмне забезпечення
2.2.1. Драйвер режиму ядра
2.2.2. Управляє додаток
2.2.3. Додаток для створення навантаження
2.2.4. Зворотній зв'язок
3. Технологічна частина
3.1. Вибір засоби розробки
3.2. Організація затримок
3.3. Взаємодія з драйвером
4. Дослідницька частина
4.1. Цілі і завдання
4.2. Конфігурація тестового стенда
4.3. Робота на невеликих частотах
4.4. Точність зміни затримок
4.5. Точність роботи таймера
4.6. Збільшення частоти спрацьовування
4.7. Робота паралельно з іншими програмами
4.7.1. Навантаження на підсистему GDI
4.7.2. Робота зі сторінковими відмовами
5. Висновок
Додаток 1. Вихідний код керуючого потоку
Додаток 2. Вихідний код робочого потоку

1. Введення
В даний час комп'ютери міцно увійшли в наше життя. Складно знайти такий аспект повсякденної життєдіяльності, в якій ще не використовується сучасна обчислювальна техніка. Не є винятком і різні науково-дослідні роботи. Так, до нас у руки потрапило спеціальний пристрій, призначений для аналого-цифрового і цифро-аналогом перетворення сигналу на апаратному рівні. З пристроєм поставляється спеціальний драйвер для роботи в операційній системі (далі ОС) Windows.
Після перших же експериментів з пристроєм з'ясувалося, що робота з ним можлива тільки на невеликих частотах оброблюваного сигналу. При збільшенні частоти спостерігається спотворення сигналу пов'язане з тим, що система не встигає обробляти приходять дані і видавати дані у відповідь. Цей результат можна вважати закономірним, враховуючи що ОС Windows взагалі кажучи не є операційною системою реального часу. Однак, сама операційна система містить в собі набір засобів, які ймовірно можуть дозволити створити систему управління реального часу в ОС Windows.

2. Конструкторська частина
2.1 Загальні принципи
Одним з можливих способів вирішення поставленої задачі може бути використання спеціальних потоків реального часу ОС Windows. Такі потоки мають пріоритети від 16 до 31 і виконуються в режимі ядра. Крім того, важливою відмінністю таких потоків від звичайних є те, що вони є потоками з добровільною передіспетчерізаціей. Це означає, що якщо такий потік отримує процесор (як системний ресурс), то він буде займати його до тих пір, поки сам добровільно не поверне його системі, тобто не перейде в стан блокування (наприклад в очікування на функції WaitForSingleObject).
Саме цій особливість системних потоків реального часу ми й спробуємо скористатися при реалізації системи управління реального часу в ОС Windows.
2.2 Програмне забезпечення
Для проведення досліджень нам знадобиться наступний набір програмних засобів: драйвер режиму ядра, що управляє додаток, додаток для створення навантаження, зворотній зв'язок.
Кожен з цих пунктів докладніше розглядається далі в цьому розділі.
2.2.1 Драйвер режиму ядра
Для створення системних потоків нам необхідно використовувати драйвер, яким у нашому випадку є драйвер віртуального пристрою. Пов'язано це з тим, що в ході наших досліджень використання реального пристрою було неможливо, крім того, в цьому не було гострої необхідності. Роботу реального пристрою ми будемо емулювати за допомогою ще одного системного потоку всередині нашого драйвера.
Отже, при початковій ініціалізації (у функції DriverEntry) драйвер запускає два системних потоку. Перший з них (емулює реальний пристрій, керуючий потік, див. Додаток 1) виконується з пріоритетом 31 і чекає на системному об'єкті «очікує таймер» (waitable timer). Це дозволяє потоку прокидатися через заздалегідь певні проміжки часу і будити другий потік, імітуючи тим самим прихід деяких даних від зовнішнього пристрою.
Другий потік (робочий потік, див. Додаток 2) виконується з налаштованим пріоритетом (від 16 до 30) і призначений для обробки даних приходять від зовнішнього пристрою. Для цього він чекає на подію до тих пір, поки воно не буде зведений керівну логіку. Потім потік виконує деяке число неодружених циклів на процесорі для імітації обробки даних. Кількість таких циклів залежить від того, яку тривалість затримки ми хочемо використовувати.
2.2.2 Управляє додаток
За допомогою спеціального додатку відбувається керування роботою драйвера. Зовнішній вигляд цього додатка зображений на рис. 2.1.

Рис 2.1. Зовнішній вигляд керуючого додатки.

Верхня кнопка дозволяють встановити драйвер. Наступні три поля введення дозволяють задати відповідно пріоритет робочого потоку (від 2 до 30), частоту запитів від емульованого зовнішнього пристрою (у герцах) і затримку (у 100-наносекундних інтервалах), яка буде використана для імітації обробки отриманих від пристрою даних.
Нижня кнопка дозволяє застосувати зроблені зміни.
2.2.3 Програма для створення навантаження
Оскільки в реальних умовах паралельно з нашим драйвером будуть виконуватися і інші програми, важливо врахувати це в ході нашої дослідницької роботи. Для цих цілей було розроблено спеціальний додаток, зовнішній вигляд якого зображений на рис. 2.2.

Рис 2.2. Зовнішній вигляд програми для створення навантаження (фрагмент)
Перша пара кнопок дозволяє включати або вимикати навантаження на підсистеми GDI, друга пара кнопок відповідно впливає на генерацію множинних сторінкових відмов.
2.2.4 Зворотній зв'язок
Для визначення поточного стану драйвера необхідно підтримувати з ним зворотний зв'язок. З усіх можливих способів такого зв'язку був обраний найпростіший - посилка текстових рядків відладчику ядра функцією DbgPrint. Для читання таких рядків можна використовувати спеціальні програмні засоби, в нашому випадку буде використано додаток DebugView 4.31 від Марка Руссиновича (Mark Russinovich), зовнішній вигляд якого зображений на рис. 2.3.

Рис 2.3. Додаток DebugView

3. Технологічна частина
3.1 Вибір засоби розробки
Для розробки драйверів найбільш широке застосування отримали мови C / C + + і Асемблер. Для розробки цього драйвера була обрана мова C + +, оскільки він поєднує в собі простоту розробки програм з можливістю використання ассемблерних вставок для критичних ділянок коду. Крім того, заголовні файли для цієї мови йдуть у стандартній поставці DDK. Для складання кінцевого драйвера використовувалися компілятор і лінковщік з DDK.
3.2 Організація затримок
Для імітації обробки даних, отриманих від пристрою необхідно створювати затримки. Для цього можна використовувати виклик спеціальної функції ядра KeStallExecutionProcessor, проте в цьому випадку ми не можемо контролювати що насправді станеться з потоком і ми отримаємо менше інформації про те скільки тактів центрального процесора було затребувано.
Крім того, при реальній роботі замість фіктивних затримок будуть використані реальні математичні обчислення на центральному процесорі. Найбільш вдалою імітацією цього на наш погляд буде створення неодружених циклів за допомогою ассемблерних вставок наприклад такого вигляду:
mov ecx, count
label: xchg eax, eax
loop label
Тут параметр count визначає, скільки саме неодружених циклів потрібно виконати, причому ми навіть можемо приблизно припустити, скільки тактів центрального процесора на це піде.
Для приблизного перерахунку числа неодружених циклів у тимчасові інтервали при початковій ініціалізації драйвера виконується порядку 10 8 неодружених циклів з ​​обчисленням часу який було витрачено на цю операцію. Далі необхідне число неодружених циклів для організації затримки розраховується за наступною формулою:
,
де count 0 і time 0 відповідно кількість неодружених циклів і час на їх виконання при початковій ініціалізації драйвера, time - необхідна довжина затримки.
3.3 Взаємодія з драйвером
Управління параметрами роботи драйвером проводиться за допомогою наступної структури:
struct ControlStruct
{Int Priority;
int Frequency;
int Delay;};
Поле Priority задає поточний пріоритет робочого потоку драйвера (пріоритет керуючого потоку завжди 31). Поле Frequency задає частоту приходу даних від емульованого зовнішнього пристрою. Поле Delay визначає тривалість затримок на обробку даних від пристрою.
Передача оновленої структури з керуючого додатки в драйвер здійснюється наступним чином. Додаток відкриває віртуальний пристрій, асоційоване з драйвером, а замет викликом WriteFile передає в драйвер потрібні дані.
Драйвер отримує дані у своїй функції DispatchWrite і зберігає їх в глобальній змінній, вносячи необхідні зміни в свою роботу.

4. Дослідницька частина
4.1 Цілі і завдання
Для того щоб почати дослідження, необхідно визначитися, як використовуватиметься отримане програмне забезпечення в ході його проведення, і яких результатів ми хочемо досягти.
За допомогою керуючого потоку ми будемо імітувати роботу реального пристрою на деякій частоті. Почавши з невеликих частот ми спробуємо довести частоту до 1 кГц і домогтися стійкої роботи на ній.
Слід також визначитися з тим, що ми будемо розуміти під стійкою роботою. Оскільки мова йде про систему управління реального часу, то необхідно, щоб до моменту приходу наступного запиту від пристрою попередній був вже повністю оброблений. Якщо по приходу запиту ми виявимо що попередній запит ще обробляється, ми будемо вважати що на даній частоті з даними часом затримки на використовуваної системі реалізація системи управління реального часу неможлива.
4.2 Конфігурація тестового стенда
Дослідження проводилися на комп'ютері з наступною конфігурацією: AMD Duron 1000 MHz, EPoX 8KHA + (VIA KT266A), 384 Mb DDR SDRAM. Файли підкачки системи розташовувалися на вінчестерах Seagate Barracuda і Western Digital зі швидкістю обертання шпінделя 7200 об / хв, підключеними по інтерфейсу IDE.
Операційна система, встановлена ​​на тестовій машині, Microsoft Windows XP Pro SP2. Система нещодавно заново, працює стабільно.

4.3 Робота на невеликих частотах
Почнемо наше дослідження з запуску драйвера на невеликих частотах, а саме обмежимося частотою в 1 Гц і поспостерігайте які максимальні затримки ми зможемо виставити збережемо стабільну роботу драйвера.
Для простоти поки будемо припускати що крім нашого драйвера система більше не завантажена ніякими ресурсоємними додатками. Тобто в диспетчері завдань понад 95% процесорного часу припадає на псевдо-процес Idle («Бездіяльність системи»). Пріоритет робочого потоку виставимо в значення 16.
Частота 1 Гц дає нам прихід запитів від імітованого пристрої кожні 1000 мс. Спочатку була виставлена ​​затримка 100 мс. Це дає системі 900 мс на «накладні витрати», що дозволило драйверу стабільно виконати необхідні дії. На прикладному рівні робота драйвера без залучення спеціальних коштів не відчувалася.
Потім ми стали збільшувати тривалість затримки. Значення було доведено до 990 мс (що дає системі 10 мс на обробку «накладних витрат»). При такій затримці стабільна робота драйвера збереглася, однак на прикладному рівні серйозно відчувалися «ривки» - система витрачала 99% часу на обробку в драйвері.
Можливо, тривалість затримки можна було ще збільшити, проте це було зробити досить важко, тому що система погано реагувала на дії користувача. При значенні затримки 1000 мс, як і слід було очікувати, стабільність роботи драйвера порушувалася.
Ще потрібно сказати про те, що якщо для частоти 1 Гц витрати на накладні витрати системи довжиною в 10 мс можна вважати нормальними, то на більш високих частотах (вище 100 Гц) це буде неприпустимо великий паузою.

4.4 Точність зміни затримок
Далі по ходу дослідження нам буде необхідно збільшувати частоту запитів і зменшувати тривалість затримок. Не зайвим буде по ярку роботи драйвера переконається, що обраний нами спосіб організації затримок працює коректно. На рис 4.1 показаний один з ділянок логу.

Рис 4.1. Точність вимірювання затримок
Початок затримки 990 мс - час 398.11619158, кінець - 399.10677251. Розходження з розрахунковим часом склало 0.00058093 с. Звичайно, при зменшенні затримок і при включенні зовнішнього навантаження похибка збільшиться, проте такий результат все одно можна назвати досить хорошим.
4.5 Точність роботи таймера
Замість зовнішнього пристрою ми використовували очікує таймер, тому цікаво буде перевірити, наскільки точно він дозволить нам витримувати необхідну частоту спрацьовування. На рис. 4.5 представлені два моменти спрацьовування таймера для частоти 1 Гц.


Рис. 4.5. Точність роботи таймера
Як видно, різниця склала 0.000195 с, що теж можна вважати хорошим результатом.
Подивимося які затримки ми зможемо використовувати у випадку більш високих частот (до 1 кГц) і що буде якщо запустити драйвер не на «холостих обертах» системи, а з наявністю зовнішнього навантаження.
4.6 Збільшення частоти спрацьовування
Драйвер був запущений для частоти 1 кГц. Збільшуючи поступово час затримки було отриманні граничне значення близько 200 мкс. Як видно, збільшення частоти в 1000 разів призвело до зменшення тривалості затримки більш ніж в 1000 разів. У принципі навіть такого інтервалу затримки могло б вистачити для реалізації системи управління реального часу, проте слід врахувати ще один фактор. У реальному системі крім нашого драйвера виконуються ще й інші програми, які теж вимагають процесорного часу та інших системних ресурсів. Перевіримо роботу драйвера у присутності таких додатків.
4.7 Робота паралельно з іншими програмами
Для проведення дослідження цього роду було написано спеціальний додаток, що може створювати навантаження певного роду.

4.7.1 Навантаження на підсистему GDI
Відомо, що підсистема GDI Windows має свій системний потік з пріоритетом реального часу. Можна очікувати, що при великій кількості запитів до цієї підсистеми може викликати збій в роботі нашого драйвера. Перевіримо це.
Драйвер був запущений на частоті 1 кГц паралельно з додатком, який виконує активну малювання засобами GDI. Стабільна робота драйвера збереглася, однак графічний висновок проводився з помітними «ривками».
4.7.2 Робота зі сторінковими відмовами
Серйозною проблемою можуть стати сторінкові відмови, що відбуваються в системі. Запуск на частоті 1 кГц паралельно з додатком, генеруючому множинні сторінкові відмови дав дуже цікаві результати. Драйвер не зміг витримати тимчасові затримки в 200 мкс. Більш того, навіть більш короткі затримки (до 25 мкс) не давали стійкої роботи драйвера.

Рис 4.6. Зупинка при виявленні збою
Ситуація змінюється на краще при збільшенні пріоритету потоку драйвера. Можна припустити, що обробка сторінкових відмов виконується також за допомогою системного потоку. Якщо ми встановлюємо свій пріоритет вище його, то стабільність роботи підвищується. На пріоритеті 30 і частоті 1 кГц вдалося досягти стабільної роботи при сторінкових відмовах із затримками до 100 мкс.

5. Висновок
Ми поспостерігали роботу драйвера, призначеного для реалізації системи реального часу, що містить в собі системний потік, що виконується з пріоритетом реального часу.
Після проведення деякої кількості експериментів були отримані допустимі часи затримок для частоти 1 кГц в «холостому» режимі роботи системи і в режимі множинних сторінкових відмов. Для тестової системи в першому випадку час склало 200 мкс, а в другому 100 мкс.
Теоретична межа для частоти 1 кГц очевидно 1000 мкс, тобто для корисної обробки даних зовнішнього пристрою можуть бути використані 10-20% процесорного часу.
При дотриманні цих умов на операційній системі Windows може бути реалізована система керування реального часу запропонованого типу.

Приложени е 1
Вихідний код керуючого потоку
VOID TimerThreadProc (PVOID startContext)
{TRACE ("-> TimerThreadProc, IRQL =% d",
KeGetCurrentIrql ());
KeSetPriorityThread ((PKTHREAD) pTimerThread, 31);
KPRIORITY priority =
KeQueryPriorityThread ((PKTHREAD) pTimerThread);
TRACE ("TimerThread Priority:% d", priority);
SetTimer ();
while (! bExitThread)
{KeWaitForSingleObject (& kTimer,
Executive, KernelMode, FALSE, 0);
if (bExitThread) break;
LONG state = KeReadStateEvent (& kEvent);
if (state == 0)
{TRACE ("TimerThreadProc: KeSetEvent");
KeSetEvent (& kEvent, FALSE, FALSE);}
else
{TRACE ("[!] Event already in signaled "
"State; aborted");
bTimerWorks = false;
break;}}
KillTimer ();
TRACE ("<- TimerThreadProc, exiting");
PsTerminateSystemThread (STATUS_SUCCESS);}

Додаток 2
Вихідний код робочого потоку
VOID ThreadProc (PVOID startContext)
{TRACE ("-> ThreadProc, IRQL =% d", KeGetCurrentIrql ());
KeSetPriorityThread ((PKTHREAD) pThread, curSett.Priority);
for (int i = 0;! bExitThread; i + +)
{TRACE ("* ThreadProc: loop% d,"
"Priority% d", i,
KeQueryPriorityThread ((PKTHREAD) pThread));
KeWaitForSingleObject (& kEvent, Executive, KernelMode,
FALSE, 0);
if (bExitThread) break;
/ / Імітуємо роботу
TRACE (">> Start \" working \ "");
DELAY (curSett.Delay);
TRACE (">> Stop \" working \ "");
/ / Скидаємо подія щоб знову почати його чекати
KeResetEvent (& kEvent);}
TRACE ("<- ThreadProc, exiting");
PsTerminateSystemThread (STATUS_SUCCESS);}
Додати в блог або на сайт

Цей текст може містити помилки.

Програмування, комп'ютери, інформатика і кібернетика | Курсова
34.4кб. | скачати


Схожі роботи:
Розробка системи реального часу у вигляді планувальника виконання завдань
Особливості операційних систем реального часу
Основні поняття та програмне забезпечення систем реального часу
Операційні системи WINDOWS NT NetWare UNIX Оперцiйна система Windows NT
Панель керування в ОС Windows Панель управління пристороями Пк у середовищі Windows
Операційні системи Windows
Операційні системи альтернативні Windows
Операційні системи Unix і Windows NT
Управління латками в ОС Windows
© Усі права захищені
написати до нас