Главная страница

Курсовая работа. Любчич.28п.Пояснительная записка к курсовой работе по дисциплине. омский государственный университет путей сообщения


Скачать 62.41 Kb.
Названиеомский государственный университет путей сообщения
АнкорКурсовая работа
Дата16.06.2022
Размер62.41 Kb.
Формат файлаdocx
Имя файлаЛюбчич.28п.Пояснительная записка к курсовой работе по дисциплине.docx
ТипРеферат
#597192

ФЕДЕРАЛЬНОЕ АГЕНСТВО ЖЕЛЕЗНОДОРОЖНОГО ТРАНСПОРТА

федеральное государственное бюджетное образовательное

учреждение высшего образования

«ОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

ПУТЕЙ СООБЩЕНИЯ»

(ОмГУПС (ОмИИТ))
Кафедра «Информационная безопасность»

РЕАЛИЗАЦИЯ ДЕСКРИПТОРА, ИНИЦИАЛИЗАЦИИ И ЗАДАЧ В ОПЕРАЦИОННОЙ СИСТЕМЕ РЕАЛЬНОГО ВРЕМЕНИ



Пояснительная записка к курсовой работе

по дисциплине «Технологии и методы программирования»



Студент гр. 28-п

          ____________В.А. Любчич
Руководитель:

к.т.н., доцент кафедры ИБ

_________С.С.Грицутенко

«__»_____________2020г.


Омск 2020

Задание

Разработать программу для реализации операционной системы реального времени, а конкретно частей этой программы, реализующих дескриптор, инициализацию и задачи операционной системы реального времени.

Реферат

Пояснительная записка к курсовой работе содержит 20 страниц, включая приложение и 4 приложения.

Объектом разработки является часть программы, реализующая дескриптор, инициализацию и задачи операционной системы реального времени.

Цель курсовой работы – закрепление, систематизация и практическое применение знаний, приобретенных в процессе изучения дисциплины «Технологии и методы программирования», а именно написание частей программы, реализующих дескриптор, инициализацию и задачи операционной системы реального времени.

Программа разработана с использованием свободной среды разработки программного обеспечения Keil uVision 5. Исходный код частей программы, представленных в данной курсовой работе написан на языке С++.

Пояснительная записка выполнена в текстовом редакторе Microsoft Word 2010.

Содержание


Введение 6

1. Теоретическая часть 7

1.1 Операционная система реального времени 7

1.2 Язык и среда программирования 8

1.3 Дескриптор 9

1.4 Инициализация 10

1.5 Задачи 11

2. Практическая часть 12

Заключение 15

Библиографический список 16

Приложение А 17

Приложение Б 18

Приложение В 20

Приложение Г 21



Введение


Современные системы компьютерной автоматики обычно работают под управлением операционных систем реального времени, которые позволяют одновременно решать ряд необходимых задач и обеспечивают требуемую реакцию на происходящие в системе события. Основной задачей в таких системах является своевременность выполнения обработки данных. ОСРВ обязаны поддерживать многопоточность, гарантированное время реакции на внешнее событие, простой доступ к таймеру и внешним устройствам. Способность гарантировать время реакции является отличительным признаком подобных систем.

Однако важно учитывать различие между гарантированностью и просто высокой производительностью и низкими накладными расходами. Далеко не все алгоритмы и технические решения, даже и обеспечивающие отличное среднее время реакции, годятся для операционных систем реального времени. В настоящее время пользователям предлагается большой выбор операционных систем реального времени различных производителей, которые отличаются по своим технико-экономическим характеристикам.

Специфика применения операционных систем реального времени требует гарантий надежности, причем гарантий в том числе и юридических - этим, видимо, можно объяснить тот факт, что среди некоммерческих систем реального времени нет сколько-нибудь популярных.

Выбор ОСРВ для конкретного применения является очень важным. Для этой цели необходимо провести анализ предметной области операционных систем реального времени, дать основополагающие определения и развернутые толкования отдельных терминов, рассмотреть структуру операционных систем реального времени и выделить наиболее распространенные и общепризнанные.

Основной целью курсовой работы является разработка частей программы, реализующих дескриптор, инициализацию и задачи операционной системы реального времени [2].

1. Теоретическая часть

1.1 Операционная система реального времени


Основой любого аппаратно-программного комплекса, в том числе работающего в режиме реального времени, является операционная система.

Операционной системой реального времени называют комплекс программ, обеспечивающий управление ресурсами аппаратно-программного комплекса (вычислительной системы) и процессами, использующими эти ресурсы при вычислениях.

Ресурсом в данном контексте является любой логический или физический (и в совокупности) компонент вычислительной системы или аппаратно-программного комплекса и предоставляемые им возможности. Основными ресурсами являются процессор (процессорное время), оперативная память и периферийные устройства. В настоящее время существует большое разнообразие операционных систем реального времени, которые классифицируются по следующим признакам: − количество пользователей, одновременно обслуживаемых системой; − число процессов, которые могут одновременно выполняться под управлением операционной системы реального времени; − тип доступа пользователя к системе; − тип аппаратно-программного комплекса. В соответствии с первым признаком различаются одно- и многопользовательские операционные системы реального времени. Второй признак делит операционные системы на одно- и многозадачные.

Система реального времени – это система, правильность функционирования которой зависит не только от логической корректности вычислений, но и от времени, за которое эти вычисления производятся.

Для событий, происходящих в такой системе, важно время, когда эти события происходят, и их логическая корректность. Система работает в реальном времени, если ее быстродействие адекватно скорости протекания физических процессов на объектах контроля или управления (имеются в виду процессы, непосредственно связанные с функциями, выполняемыми конкретной системой реального времени). Система управления должна собрать данные, произвести их обработку по заданным алгоритмам и выдать управляющее воздействие за такой промежуток времени, который обеспечивает успешное выполнение поставленных задач [1].

1.2 Язык и среда программирования


В данной курсовой работе был выбран такой язык программирования, как С++. Это связано с тем, что он состыкуется с языком низкого уровня – ассемблером. А так как программа создается для операционной системы реального времени, то потребуются оба данные языка.

Команды языка ассемблера соответствуют командам процессора. Одной команде языка ассемблера может соответствовать несколько вариантов команд процессора.

В данной курсовой работе представлены части программы, написанные только на языке С++.

C++ - компилируемый, статически типизированный язык программирования общего назначения.

Поддерживает такие парадигмы программирования, как процедурное программирование, объектно-ориентированное программирование, обобщённое программирование. Язык имеет богатую стандартную библиотеку, которая включает в себя распространённые контейнеры и алгоритмы, ввод-вывод, регулярные выражения, поддержку многопоточности и другие возможности. C++ сочетает свойства как высокоуровневых, так и низкоуровневых языков.

C++ широко используется для разработки программного обеспечения, являясь одним из самых популярных языков программирования. Область его применения включает создание операционных систем, разнообразных прикладных программ, драйверов устройств, приложений для встраиваемых систем, высокопроизводительных серверов, а также игр. Существует множество реализаций языка C++, как бесплатных, так и коммерческих и для различных платформ.

Синтаксис C++ унаследован от языка C. Одним из принципов разработки было сохранение совместимости с C. Тем не менее, C++ не является в строгом смысле надмножеством C; множество программ, которые могут одинаково успешно транслироваться как компиляторами C, так и компиляторами C++, довольно велико, но не включает все возможные программы на C [3].

В качестве среды программирования была выбрана Keil uVision 5. Это объясняется тем, что она поддерживает язык С++ и ассемблер одновременно.

Keil uVision позволяет работать с проектами любой степени сложности, начиная с введения и правки исходных текстов и заканчивая внутрисхемной отладкой кода и программированием ПЗУ микроконтроллера. От разработчика скрыта большая часть второстепенных функций, что сильно разгружает интерфейс и делает управление интуитивно понятным. Однако при возрастании сложности реализуемых задач, всегда можно задействовать весь потенциал модулей, функционирующих под управлением единой оболочки.

1.3 Дескриптор


Системные данные, используемые ядром в течении времени жизни процесса, составляют дескриптор процесса. Дескриптор процесса резервируется ядром при образовании процесса и освобождается при его завершении.

Процесс – это абстракция, описывающая выполняющуюся программу. Для ОС это единица работы, заявка на потребление системных ресурсов.

Состояние процесса: выполнение, ожидание, завершение.

Дескриптор процесса, handle – это описатель (идентификатор) процесса, который содержит номер процесса, область памяти, где размещен сегмент кода, данные приоритетности процесса, данные о состоянии процесса. Каждый дескриптор процесса содержит ссылку на другой дескриптор.

Контекст – хранит состояние регистров, состояние программного счетчика, режим работы процессора, незавершенные операции ввода-вывода, информация о выполненных системных вызовах.

Структура данных, в которой хранится информация, необходимая для совершения операции над процессом называется PCB – Process Control Block – блок управления процессов. Информация в PCB разделяется на 2 части:

  1. Регистровый контекст процессора

  2. Системный контекст процессора

Помимо PCB используется информация для характеристики внутренней работы процесса, его код и данные, адресное пространство – пользовательский контекст процесса.

В данной курсовой работе дескриптор это объект структуры TaskDes , описанной в заголовочном файле des.h, дающий некое описание задачи.

Когда процесс создает или открывает объект по его имени, он получает дескриптор, дающий ему доступ к объекту. Ссылаться на объект по его дескриптору быстрее, чем использовать его имя, поскольку диспетчер объектов может не заниматься поиском по имени и находить объект напрямую [6].

1.4 Инициализация


Инициализация – определение параметров или конфигурации, подготовка к работе, процессы активации и т. д.

Инициализация, как некий процесс определения заданных параметров или их значений, в равной степени может применяться и к программным, и к аппаратным компонентам компьютерной системы.

Инициализация программы происходит следующим образом.

Считается, что в вопросе инициализации приложений приоритетными процессами являются задание корректных начальных переменных или установка их значений равными нулю. Сюда относятся переключатели, счетчики, адреса и т. д. Для ассемблерных программ, представленных в большинстве случаев исполняемыми файлами форматов COM и EXE, процесс инициализации состоит из четырех основных этапов:

  1. указание на то, какие именно сегментные регистры должны соответствовать определенным сегментам;

  2. сохранение адреса регистра DS в стеке при старте исполнения программы;

  3. запись в стек нулевого адреса;

  4. загрузка в DS-регистр адреса сегмента.

При обработке соответствующих массивов данных процесс имеет циклический характер, когда значения в массив, начинающийся с переменной со значением 0 или 1, попадают только после прохождения полного цикла и по мере выполнения приложения. И циклов может быть ровно столько, сколько переменных содержит весь массив [5].


1.5 Задачи


В обычных операционных системах реального времени задача может находиться в трёх возможных состояниях:

  1. задача выполняется;

  2. задача готова к выполнению, т.е. находится в режиме ожидания;

  3. задача заблокирована.

Большую часть времени основная масса задач заблокирована. Только одна задача может выполняться на центральном процессоре в текущий момент времени. В примитивных операционных системах реального времени список готовых к исполнению задач, как правило, очень короткий, он может состоять не более чем из двух-трёх наименований.

Основная функция администратора операционной системы реального времени заключается в составлении такого планировщика задач.

Если в списке готовых к выполнению задач последних имеется не больше двух—трёх, то предполагается, что все задачи расположены в оптимальном порядке. Если же случаются такие ситуации, что число задач в списке превышает допустимый лимит, то задачи сортируются в порядке приоритета.

Операционная система выполняет следующие основные функции, связанные с управлением процессами и задачами:

  1. создание и удаление задач;

  2. планирование процессов и диспетчеризация задач;

  3. синхронизация задач, обеспечение их средствами коммуникации [4].



2. Практическая часть


Начать следует с файла des.h. В нем содержится структура дескриптора, в которой объявляется компоненты, которые в него входят. А именно: переменная статуса; указатель на переменные начального и текущего адреса, начального и текущего адреса стека.

typedef struct//

{

int status;// Объявление целочисленной переменной status.

void* address;//Объявление указателя типа void на переменную address.

void* current_address;// Объявление указателя типа void на переменную current_address.

int* stack_add;// Объявление указателя типа int на переменную stack_add.

int* current_stack;// Объявление указателя типа int на переменную current_stack.

}TaskDes;//Имя структуры.

После этого переходим к файлу ini.c. В нем с самого начала нужно вызвать библиотеку дескриптора, описанную выше. После этого идет объявление внешних функций двух задач и внешних переменных двух дескрипторов и двух стеков.

#include "des.h"

extern void task_1(TaskDes*);// Объявление внешней функции первой задачи

extern void task_2(TaskDes*);// Объявление внешней функции второй задачи

extern TaskDes ddd1;// Объявление внешней переменной первого дескриптора особого пользовательского типа.

extern TaskDes ddd2;// Объявление внешней переменной второго дескриптора особого пользовательского типа.

extern int Stack1;// Объявление внешней целочисленной переменной первого стека.

extern int Stack2;// Объявление внешней целочисленной переменной второго стека.

После этого мы видим массив указателей на адреса дескрипторов типа TaskDes.

TaskDes* DES_ADD[2];

Сразу после переходим к функции инициализации массивов дескриптора. Адреса дескриптора первого и второго таска «складываем» в нулевую и первую ячейки массива указателей. Дескриптору первой задачи присваиваем статус 1 – выполнение задачи. Начальному адресу первой задачи присваиваем адрес task_1. Текущему адресу первой задачи присваиваем адрес task_1. Адресу стека первого дескриптора присваиваем адрес последней позиции первого стека, чтобы совершить перемещение в конец стека, на последнюю позицию, чтобы заполнять стек с конца. Текущему адресу стека первого дескриптора присваиваем адрес данной позиции первого стека, чтобы сдвинули начало стека на с последней позиции на 9 позиций.

void ini()

{

DES_ADD[0] = &ddd1;

DES_ADD[1] = &ddd2;

ddd1.status=1;

ddd1.address = task_1;

ddd1.current_address= task_1 ;// .При первом обращении текущий адрес совпадает с начальным.

ddd1.stack_add=&Stack1+98;

ddd1.current_stack=&Stack1+89;// Необходимо для сохранения контекста.

Для второго дескриптора проводим аналогичные присвоения, за исключением того, что второй задаче присваивается статус 2 – ожидание.

ddd2.status=0;

ddd2.address = task_2;

ddd2.current_address= task_2 ;

ddd2.stack_add=&Stack2+98;

ddd2.current_stack=&Stack2+89;/

}

После этого переходим к задачам. В имеющейся операционной системе реального времени имеются две задачи. При прерывании первой задачи контекст сохраняется и запускается вторая задача. После прерывания второй задачи, сохраняется контекст второй задачи и восстанавливается первая задачу с места ее остановки. Но об этом в данной курсовой работе говорить подробно не будем.

Начнем с первой задачи из файла task_1.c. После подключения библиотеки дескриптора, описанной выше, происходит объявление массива первого стека и дескриптора первой задачи, идет она сама.

#include "des.h"

int Stack1[99];// Объявление массива целочисленного типа первого стека, размером 99.

TaskDes ddd1;

Первая задача заключается в тривиальном сложении. Программа будет прибавлять к единице число i, пока i будет меньше пятидесяти.

void task_1()

{

int a=1, c;

for(int i=0; i<50; i++)

c=a+i;

Когда задача полностью выполнится, установится статус 2, что будет значить завершение.

ddd1.status=2;

while(1);

}

Последним файлом в данной курсовой работе является файл task_2.c.Он начинается идентично предыдущему. После подключения библиотеки дескриптора, описанной выше, происходит объявление массива второго стека и дескриптора второй задачи, идет она сама.

#include "des.h"

int Stack2[99];

TaskDes ddd2;

Вторая задача заключается в сложении двух переменных и их последующей проверки на четность и нечетность.

void task_2()

{

int x = 1;

int y = 1;

long unsigned int F = 0;

for (int i = 1; i < 100; i++)

{

F = x + y;

if (i % 2 == 0)

x = F;

if (i % 2 == 1)

y = F;

}

Когда задача полностью выполнится, установится статус 2, что будет значить завершение.

ddd2.status=2;

while(1);

}

Заключение


В процессе написания курсовой работы была изучена литература, включающая в себя основные понятия, необходимые для написания частей программы, реализующих дескриптор, инициализацию и задачи операционной системы реального времени. При выполнении курсовой работы были закреплены навыки работы в Keil uVision 5 и знания языка программирования С++.

В результате были написаны части программы, в которых были реализованы дескриптор, инициализацию и задачи операционной системы реального времени.


Библиографический список


  1. Операционные системы реального времени/ И.Б. Бурдонов, А.С. Косачев, В.Н. Пономаренко. М: Институт системного программирования РАН, 2006. – 49с.

  2. Операционные системы реального времени/ К. Ю. Богачев. М: МГУ им. Ломоносова, 2002. – 96с.

  3. Язык программирования C++/ Бьерн Страуструп. М: ЗАО “Издательство БИНОМ”, 2002. – 1099c.

  4. [Электронный ресурс] – Режим доступа: https://ru.wikipedia.org/wiki/Операционная_система_реального_времени

  5. [Электронный ресурс] – Режим доступа: https://tlt-pc.ru/trejding/kakim-obrazom-proishodit-initsializatsiya-programmy.html

  6. [Электронный ресурс] – Режим доступа: https://tehnar.net.ua/deskriptor-protsessa/


Приложение А


Файл des.h

typedef struct// Объявление структуры пользовательского типа данных.

{

int status;// Объявление целочисленной переменной status.

void* address;//Объявление указателя типа void на переменную address (начальный адрес) .

void* current_address;// Объявление указателя типа void на переменную current_address (текущий адрес).

int* stack_add;// Объявление указателя типа int на переменную stack_add (начальный адрес стека).

int* current_stack;// Объявление указателя типа int на переменную current_stack (текущий адрес стека).

}TaskDes;//Имя структуры.





Приложение Б


Файл ini.c

#include "des.h"// Вызов библиотеки дескриптора, написанной в Приложении А.

extern void task_1(TaskDes*);// Объявление внешней функции первой задачи

extern void task_2(TaskDes*);// Объявление внешней функции второй задачи

extern TaskDes ddd1;// Объявление внешней переменной первого дескриптора особого пользовательского типа.

extern TaskDes ddd2;// Объявление внешней переменной второго дескриптора особого пользовательского типа.

extern int Stack1;// Объявление внешней целочисленной переменной первого стека.

extern int Stack2;// Объявление внешней целочисленной переменной второго стека.
TaskDes* DES_ADD[2];// Массив указателей на адреса дескрипторов типа TaskDes
void ini()

{

DES_ADD[0] = &ddd1;// Адрес дескриптора первого таска «складываем» в нулевую ячейку массива указателей.

DES_ADD[1] = &ddd2;// Адрес дескриптора второго таска «складываем» в следующую ячейку массива указателей.

ddd1.status=1;// Дескриптору первой задачи присваивается статус 1 – выполнение задачи.

ddd1.address = task_1;// Начальному адресу первой задачи присваивается адрес task_1.

ddd1.current_address= task_1 ;// Текущему адресу первой задачи присваивается адрес task_1. (При первом обращении текущий адрес совпадает с начальным)

ddd1.stack_add=&Stack1+98;// Присваиваем адресу стека первого дескриптора адрес последней позиции первого стека, чтобы совершить перемещение в конец стека, на последнюю позицию, чтобы заполнять стек с конца.

ddd1.current_stack=&Stack1+89;// Присваиваем текущему адресу стека первого дескриптора адрес данной позиции первого стека, чтобы сдвинули начало стека на с последней позиции на 9 позиций. (это необходимо для сохранения контекста)

ddd2.status=0;// Дескриптору второй задачи присваивается статус 0 – ожидание.

ddd2.address = task_2;// Начальному адресу второй задачи присваивается адрес task_2.

ddd2.current_address= task_2 ;// Текущему адресу второй задачи присваивается адрес task_2.

ddd2.stack_add=&Stack2+98;// Присваиваем адресу стека второго дескриптора адрес последней позиции второго стека, чтобы совершить перемещение в конец стека, на последнюю позицию, чтобы заполнять стек с конца.

ddd2.current_stack=&Stack2+89;// Присваиваем текущему адресу стека второго дескриптора адрес данной позиции второго стека, чтобы сдвинули начало стека на с последней позиции на 9 позиций.

}


Приложение В


Файл task_1.c

#include "des.h"// Подключение библиотеки дескриптора, описанной в Приложении А.

int Stack1[99];// Объявление массива целочисленного типа первого стека, размером 99.

TaskDes ddd1;// Объявление дескриптора первой задачи.
void task_1()

{

int a=1, c;

for(int i=0; i<50; i++)

c=a+i;
ddd1.status=2;// Установление статуса 2 – завершение задачи.

while(1);

}


Приложение Г


Файл task_2.c

#include "des.h"// Подключение библиотеки дескриптора, описанной в Приложении А.

int Stack2[99];// Объявление массива целочисленного типа второго стека, размером 99.

TaskDes ddd2;// Объявление дескриптора второй задачи.
void task_2()

{

int x = 1;

int y = 1;

long unsigned int F = 0;

for (int i = 1; i < 100; i++)

{

F = x + y;

if (i % 2 == 0)

x = F;

if (i % 2 == 1)

y = F;

}

ddd2.status=2;// Установление статуса 2 – завершение задачи.

while(1);

}





написать администратору сайта