Міністерство освіти і науки України
Національний університет “Львівська політехніка”
Кафедра електронних обчислювальних машин
Лабораторні роботи з дисципліни “Програмування систем реального часу”
Львів-2007.
В цьому збірнику інструкцій лабораторних робіт з дисципліни “Програмне забезпечення систем реального часу” наведені основні вимоги до виконання лабораторних робіт, базові теоретичні відомості, які необхідні для виконання робіт з даної дисципліни та безпосередньо інструкції до виконання самих лабораторних робіт.
Перш за все відзначимо, що звіт до лабораторної роботи здається викладачу в паперовому варіанті. В звіті повинні бути присутніми наступні елементи:
Завдання до лабораторної роботи;
Теоретичні відомості: список використаних специфічних функцій, опис запропонованих алгоритмів і особливості їх реалізації.
Текст розробленої студентом програми;
Отримані результати виконання роботи.
Лабораторна робота №1.
Тема роботи: Ознайомлення з операційною системою UCOS-II.
Завдання до роботи: Ознайомитися з операційною системою реального часу UCOS-II і навчитися розробляти найпростіші програми в даній системі.
Система UCOS-II – компактна, із пріорітетним планувальним операційна система реального часу. Завдяки тому, що ядро системи практично повністю написано на мові програмування С, система легко може бути портована практично на будь-який процесор який дозволяє зберігати в стеку дані і надає програмний доступ до вказівника стеку. В системі використовується лише один програмний модуль, виконаний на асемблері для реалізації перемикання задач, який є специфічним для обраної архітектури процесора. На сьогоднішній день система портована на 60 різних типів процесорів, орієнтованих на застосування у вбудованих системах, починаючи від дешевих 8-розрядних мікроконтроллерів і закінчуючи потужними 64-розрядними процесорами. Детальніша інформація подана на Інтернет сторінці розробника http://www.micrium.com/ports_v2.htm.
Система дозволяє розробляти програми із максимальною кількістю задач 56, причому одним із недоліків системи є те, що кожна із задач характеризується своїм рівнем пріорітету, що не дозволяє реалізувати так званий карусельний принцип диспечирезації.
Розглянемо застосування системи при розробці програмного забезпечення систем реального часу. Перш за все, зупинимось на інсталяції і перекомпіляції ядра системи. Для навчальних цілей будемо використовувати останню версію системи 2.51. Після розархівування дистрибутиву системи - архіву із назвою ucos251.exe в вибрану Вами директорію буде створено декілька піддиректорій:
\Software
\Blocks
\HpListC
\To
\Ucos-ii\
Можливими є декілька варіантів компіляції ядра. Розглянемо один із найпростіших, при використанні версії системи для архітектури x86 і компілятора Borland C v.3.1-4.5 із можливістю генерації виконавчих файлів для операційної системи DOS. Розглянемо варіант компіляції системи, який базується на підключенні вихідних текстових файлів системи у проект, створений у інтегрованому середовищі розробника.
Із каталогу, де розпакований дистрибутив, переписуємо наступні файли у вибраний Вами каталог, наприклад \UCOS-ii\source\
OS_CORE.C
OS_CPU.H
OS_CPU_A.ASM (із каталогу \x86l-FL\Bc45, зберігає стан FPU процесора)
OS_CPU_C.C
OS_FLAG.C
OS_MEM.C
OS_MUTEX.C
OS_Q.C
OS_SEM.C
OS_TASK.C
OS_TIME.C
PC.C
PC.H
UCOS_II.C
UCOS_II.H
Створюємо каталог, де будуть розміщуватись робочі файли проекту, наприклад \UCOS-ii\test
Копіюємо туди наступні файли із каталогу Ex1_X86L:
INCLUDES.H – головний файл включень
OS_CFG.H – файл конфігурацій системи
TEST.C – тестовий приклад
Викликаємо IDE компіляторa із робочого каталогу проекту, в нашому випадку це буде \UCOS-ii\test і створюємо новий проект. До проекту слід додати наступні файли:
UCOS_II.C – головний файл включень системи.
os_cpu_c.c – реалізація функцій, специфічних для даної архітектури процесора.
os_cpu_a.asm – реалізація функцій на асемблері (варіант із підтримкою операцій з плаваючою комою)
pc.c – реалізація специфічних функцій вводу-виводу на дисплей, зчитування з клавіатури, обліку виконання програми тощо.
test.c – вихідний код демонстраційного прикладу
Після чого, при необхідності, відредагувати шляхи у включаємих файлах і директивах конфігурації компілятора та задати наступні опції компілятора:
Code generation: Model : Large Options : Treat enums as ints Assume SS Equals DS : Default for memory model Optimizations: Global register allocation Invariant code motion Induction variables Loop optimization Suppress redundant loads Copy propagation Dead code elimination Jump optimization Inline intrinsic functions Register variables: Automatic Common subexpressions: Optimize globally Optimize for: Speed
Після чого слід перекомпілювати приклад і запустити програму на виконання. При виникненні помилок компіляції слід усунути причини їх виникнення. Найчастіше вони бувають зумовлені відсутністю певних файлів чи неправильно заданими шляхами до них. При виникненні помилок типу Cannot transfer TASM (неможливо викликати турбо-асемблер) слід переконатись в його наявності в каталозі bin директорії, куди проінстальований Borland C.
Потрібно уважно проаналізувати вихідний текст демонстраційного прикладу і пояснити код. Зауважимо, що обробник переривання від системного таймера системи слід встановлювати виключно в одній із задач, попередньо заборонивши переривання. Цього ні в якому випадку не можна робити із коду в функції main програми.
Лабораторна робота №.2
Тема роботи: Створення різних процесів із одного тіла функції. Передача параметрів процесу при ініціалізації.
Завдання до роботи: розробити програму в якій створюються 3 різних задачі, використовуючи ідентичний код самого процесу. Кожен із процесів повинен виводити лічильник, значення якого інкрементується через заданий інтервал часу. Задачі передаються 3 параметри: координати рядку, в якому виводиться лічильник, значення інкременту і період затримки в тіках системного таймеру, через які повинен лічильних інкрементуватися.
В системі UCOS-II функція процесу являє собою функцію, яка не повертає значення і в якості параметру отримує нетипізований вказівник:
void Task (void *par);
Саму вказівник par використовується для передачі задачі параметрів. Для передачі задачі параметрів необхідно створити структуру, полями якої будуть необхідні для задачі параметри і передати при створенні задачі вказівник на неї. Оскільки при створенні задачі за допомогою функції OSTaskCreate копіюється лише сам вказівник, а не структура із параметрами, то для кожної задачі доцільно мати окрему структуру, адреса якої передається при створенні процесу (задачі).
Лабораторна робота №3..
Тема роботи: Функції обліку часу виконання програми в системах реального часу.
Завдання до роботи. Проаналізувати механізми обліку часу в системах реального часу, навчитися вимірювати часові інтервали, реалізації функцій затримки і механізми очікування надходженні подій. Виміряти час виконання системних функцій системи UCOS-II використовуючи RDTSC інструкцію Pentium процесора.
При розробці програмного забезпечення систем реального часу часто постають задачі вимірювання часових інтервалів виконання визначених фрагментів коду із достатньо високою точністю. Із цими задачами пов’язані питання формування визначених затримок, зокрема при роботі із апаратними засобами. Для вирішення таких питань можуть бути використані декілька механізмів.
Використання системного таймера операційної системи. Практично будь-яка операційна система реального часу використовує переривання від системного таймера для реалізації механізму квантування часу процесора, реалізації системних затримок, таймаутів. В системі UCOS-II всі функції із використанням таймаутів, системна функція затримки OSTimeDly використовують лічильники, які змінюються кожного переривання таймера. При виклику функцій затримки, які використовують цей механізм, ресурси процесора, які використовують цей механізм перерозподіляються між іншими задачами, тобто, процесор може виконувати корисну роботу. Час затримки обмежується тільки розрядністю змінних, використаних під внутрішні лічильники переривань таймера і може бути великим. Використання цього механізму характеризується наступними недоліками:
фактичний час затримки визначається біжучими станами процесів в системі і може змінюватись як в більшу так і меншу сторони, тобто спостерігається дрожання (jitter) затримки.
затримки, які можуть бути отримані в такий спосіб не можуть бути дуже малими. Типові значення – одиниці, десятки мілісекунд. Це зумовлено тим, що частота переривання системного таймера не може бути встановлена занадто високою. Чому? (пояснити самостійно!)
Використання годинника реального часу. В багатьох системах передбачена наявність апаратного годинника реального часу, який інкрементується певну кількість разів на секунду, наприклад, раз в секунду. Оскільки дискретність такого годинника є достатньо великою, то він не може бути використаний для вимірювання/формування малих затримок.
Використання апаратно-залежних механізмів. Розглянемо їх на прикладі архітектури IBM сумісного комп’ютера. Перший спосіб полягає у використанні другого каналу системного таймера для обліку часових інтервалів. Всі ЕОМ даного класу містять 16-розрядний таймер-лічильник, сумісний із Intel8254, вхід якого подається сигнал із частотою 1.19318 MHz. Оскільки лічильник є 16 розрядний, то максимальний інтервал часу може бути виміряний рівний 65536*0.838097 = 55мс. Цей механізм підтримується системою UCOS-II. В бібліотеці функцій, прототипи яких наведено в pc.h, вказано три функції:
PC_ElapsedInit() ініціалізація системи обліку часу.
PC_ElapsedStart() – встановлення часової мітки. Використовується для позначення першої ділянки коду, час виконання якого слід виміряти.
PC_ElapsedStop() – обчислення часу виконання фрагменту програми із моменту виклику функції PC_ElapsedStart, в мікросекундах.
Інший, більш досконалий механізм, полягає у використанні інструкції RDTSC (Real Time Stamp Counter) процесорів Pentium і вище. В процесорі вмонтований 64-лічильник, який інкрементується кожен машиннимй такт. В результаті виконання цієї інструкції значення лічильника заносяться в пару 32 розрядних регістрів. edx, eax. Оскільки лічильник 64 розрядний, то необхідно виконувати операції над 64 розрядними числами, і вносити поправку на можливе переповнення лічильника. Для обчислення конкретних часових інтервалів перш за все необхідно визначити частоту процесора, використовуючи точні часові мітки. Їх зручно сформувати, використовуючи годинник реального часу комп’ютера. Для визначення тактової частоти можна скористатись функцією biostime(), яка повертає значення лічильника, який інкрементується приблизно 18 раз щосекунди.
При використанні цієї функції слід забезпечити точне дотримання інтервалу між двома базовими точками. Можна запропонувати наступний алгоритм:
Зчитуємо значення лічильника, пов’язаного з таймером.
Чекаємо поки значення лічильника зміниться.
Зчитуємо значення лічильника RDTSC процесора .
Чекаємо визначену кількість інтервалів таймера.
Знову зчитуємо значення лічильника RDTSC .
Обчислюємо тактову частоту процесора в наступний спосіб:
При виконанні роботи необхідно передбачити можливість роботи із 64 розрядними числами. Найпростіше це можна зробити, використовуючи числа з плаваючою комою подвійної точності чи реалізувавши спеціальні процедури для роботи із числами, представленими у вигляді структур.
Приклад реалізації використання RDTSC:
unsigned long int a,b;
asm {
DB 0FH
DB 031H
mov a,edx
mov b,eax
}
В результаті виконання цієї функції значення змінних будуть містити значення лічильника. Після його можна перетворити у число з плаваючою комою і використовувати для подальших обчислень.
Лабораторна робота 4.
Використання семафорів і мютексів для реалізації доступу до спільних ресурсів системи.
Завдання до роботи:
Розробити програму, в якій декілька задач імітують доступ до деякого спільного ресурсу використовуючи семафори та м’ютекси. Кожна із задач захоплює ресурс на випадковий інтервал часу із наперед заданого діапазону , який є однаковим для всіх задач. Якщо ресурс є недоступний протягом часу , то надсилається повідомлення про помилку. Окрім задач, які саму імітують використання ресурсу, існує додаткова задача, яка виводить повідомлення про те, яка із задач отримала спільний ресурс і повідомлення про помилку, якщо вибраний ресурс не був доступний в межах заданого інтервалу часу.
Окрім виводу повідомлень про використання певних ресурсів, додаткова задача здійснює збір статистичних даних про мінімальний, середній і максимальний час доступу до ресурсу для кожної із задач. Виконати дві реалізації програми – використовуючи семафори та використовуючи м’ютекси для реалізації доступу до спільного ресурсу. Порівняти отримані результати для часу доступу із використанням механізму семафорів і механізму м’ютексів. Пояснити відмінності в отриманих часових параметрах.