Файл: Министерство связи и массовых.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 29.04.2024

Просмотров: 5

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.


Министерство связи и массовых коммуникаций Российской Федерации Федеральное государственное образовательное бюджетное учреждение высшего образования «Сибирский государственный университет

телекоммуникаций и информатики» (ФГОБУ ВО «СибГУТИ»)
Практическое задание №5 Дисциплина: Архитектура ЭВМ

Выполнил студент 2 курса: Горбань Д.В.

Группа: ИП-Проверил преподаватель: Трусов Кирилл

Новосибирск, 2022

Цельработы

Изучить устройство клавиатуры и принципы обработки нажатия клавиш в текстовом терминале. Создать «распознаватель» нажатой клавиши по формируемой последовательности символов. Разработать библиотеку myReadkey. Доработать интерфейс консоли управления Simple Computer так, чтобы можно было изменять значения ячеек памяти и регистров.

Заданиеналабораторнуюработу

  1. Прочитайте главу 5 практикума по курсу «Организация ЭВМ и систем». Обратите особое внимание на параграф 5.1. Изучите страницу man для команд infocmp и read, базы terminfo.

  2. Используя оболочку bash и команду read, определите последовательности, формируемые нажатием на буквенно-цифровые, функциональные клавиши и клавиши управления курсором. Используя команду infocmp, убедитесь, что получены правильные последовательности символов, генерируемые функциональными клавишами «F5» и «F6».

  3. Разработайте функции:

  • int rk_readkey (enum keys *) - анализирующую последовательность символов (возвращаемых функцией read при чтении с терминала) и возвращающую первую клавишу, которую нажал пользователь. В качестве параметра в функцию передаѐтся адрес переменной, в которую возвращается номер нажатой (enum keys перечисление распознаваемых клавиш);

  • int rk_mytermsave (void) - сохраняет текущие параметры терминала;

  • int rk_mytermrestore (void) - восстанавливает сохранѐнные параметры терминала.

  • int rk_mytermregime (int regime, int vtime, int vmin, int echo, int sigint) - переключает терминала между режимами. Для неканонического режима используются значения второго и последующего параметров.

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

2. Используя команду read, я определил последовательности клавиш (F5, F6)




Библиотека myReadkeys


int rk_readkey (int *key) - анализирующую последовательность символов (возвращаемых функцией read при чтении с терминала) и возвращающую первую клавишу, которую нажал пользователь. В качестве параметра в функцию передаѐтся адрес переменной, в которую возвращается номер нажатой (enum keys – перечисление распознаваемых клавиш);


int rk_readkey(int *key)

{

char buf[32]; int readNum = 0;

readNum = read(STDIN_FILENO, &buf, 15);
if (readNum == 0)

{

return -1;

}
if (strcmp(buf, "l") == 0)

*key = KEY_l;

else if (strcmp(buf, "s") == 0)

*key = KEY_s;

else if (strcmp(buf, "r") == 0)

*key = KEY_r;

else if (strcmp(buf, "t") == 0)

*key = KEY_t;

else if (strcmp(buf, "i") == 0)

*key = KEY_i;

Для начала создаем буфер, куда считываем символы из входного потока. Если кол-во считанных символов равно 0, то функция возвращает -1. Затем начинаем с помощью ф- ии strcmp() сравнивать данные из буфера буквенно-цифровые, функциональные клавиши и клавиши управления курсором. Как видно из кода ниже, фунцкиональные клавиши требуют определенный набор последовательных символов. Если нашелся нужный нам символ, то по адресу key записывается номер этого символа из enum key.Если есть такие символы, то им присуждается одинаковый номер.




enum keys

{

KEY_l, KEY_s, KEY_r, KEY_t, KEY_i, KEY_q, KEY_f5, KEY_f6,

KEY_up, KEY_down, KEY_left, KEY_right, KEY_enter, KEY_other

};



int rk_mytermsave (void) - сохраняет текущие параметры терминала; Конфигурация терминала записывается в файл в бинарном виде.

int rk_mytermsave()

{

struct termios options;

FILE *sa

ve;

if (tcgetattr(STDIN_FILENO, &options) != 0) return -1;

if ((save = fopen("txt/termsettings", "wb")) == NULL)






Int rk_mytermrestore (void) - восстанавливает сохранѐнные параметры терминала.


int rk_mytermrestore()

{

struct termios options; FILE *save;
if ((save = fopen("termsettings", "rb")) == NULL) return -1;

if (fread(&options, sizeof(options), 1, save) > 0)

if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &options) != 0) return -1;

else

return -1;
return 0;

}

Если не удалось открыть файл, то ф-ия возвращает -1. С помощью ф-ии fread() записываем в структуру, описывающую общий терминальный интерфейс настройки, сохраненные раннее.

int rk_mytermregime (int regime, int vtime, int vmin, int echo, int sigint) - переключает терминала между режимами. Для неканонического режима используются значения второго и последующего параметров.

С помощью побитовых операций(И, ИЛИ, ПОБИТОВОЕ ОТРИЦАНИЕ) переключаем терминал из неканонического режима в канонический и обратно.

Структура termios:



Исходный код


myReadkey.c

#include "myReadkey.h"
int rk_readkey(int *key)

{

char buf[32];

int readNum = 0;

readNum = read(STDIN_FILENO, &buf, 15);
if (readNum == 0)

{

return -1;

}
if (strcmp(buf, "l") == 0)

*key = KEY_l;

else if (strcmp(buf, "s") == 0)

*key = KEY_s;

else if (strcmp(buf, "r") == 0)

*key = KEY_r;

else if (strcmp(buf, "t") == 0)

*key = KEY_t;

else if (strcmp(buf, "i") == 0)

*key = KEY_i;

else if (strcmp(buf, "q") == 0)

*key = KEY_q;

else if

(strcmp(buf, "\\EOM") == 0)

*key = KEY_enter;

else if (strcmp(buf, "\\E[15") == 0)

*key = KEY_f5;

else if (strcmp(buf, "\\E[17") == 0)

*key = KEY_f6;

else if (strcmp(buf, "\\EOA") == 0)

*key = KEY_up;

else if (strcmp(buf, "\\EOB") == 0)

*key = KEY_down;

else if (strcmp(buf, "\\EOC") == 0)

*key = KEY_right;

else if (strcmp(buf, "\\EOD") == 0)

*key = KEY_left;

else

*key = KEY_other;
return 0;

}
int rk_mytermsave()

{

struct termios options;

FILE *save;
if (tcgetattr(STDIN_FILENO, &options) != 0) return -1;

if ((save = fopen("txt/termsettings", "wb")) == NULL)

return -1;

fwrite(&options, sizeof(options), 1, save); fclose(save);
return 0;

}
int rk_mytermrestore()

{

struct termios options;

FILE *save;
if ((save = fopen("termsettings", "rb")) == NULL)

return -1;

if (fread(&options, sizeof(options), 1, save) > 0)

if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &options) != 0) return -1;

else

return -1;
return 0;

}
int rk_mytermregime(int regime, int vtime, int vmin, int echo, int sigint)

{

struct termios options;
if (tcgetattr(STDIN_FILENO, &options) != 0) return -1;

if (regime == 1) options.c_lflag |= ICANON;

else if (regime == 0) options.c_lflag &= ICANON;

else

return -1;

if (regime == 0)

{

options.c_cc[VTIME] = vtime; options.c_cc[VMIN] = vmin; if (echo == 1)

options.c_lflag |= ECHO;

else if (echo == 0) options.c_lflag &= ECHO;

else

return -1;

if (sigint == 1) options.c_lflag |=
ISIG;

else if (sigint == 0) options.c_lflag &= ISIG;

else

return -1;

}

if (tcsetattr(STDIN_FILENO, TCSANOW, &options) != 0) return -1;
return 0;

}

myReadKey.h


Makefile

CC = gcc CFLAGS = -g2

SOURCES = main.c libSC.c myTerm.c myBigChars.c myReadkey.c OBJECT_FILES = $(addprefix obj/, $(SOURCES:.c=.o)) EXECUTABLE = SCtest
all: obj lib lib/libmemory.a lib/libTerm.a lib/libBigChars.a lib/libReadkey.a

$(SOURCES) $(EXECUTABLE)
obj:

mkdir obj
lib:

mkdir lib
$(EXECUTABLE): $(OBJECT_FILES)

$(CC) obj/main.o lib/libmemory.a lib/libTerm.a lib/libBigChars.a lib/libReadkey.a $(LDFLAGS) $(CFLAGS) -o $@
obj/%.o: %.c

$(CC) $(CFLAGS) -c $< -o $@
lib/libmemory.a: $(OBJECT_FILES)

ar rc lib/libmemory.a obj/libSC.o
lib/libTerm.a: $(OBJECT_FILES)