Разработка Linux-приложений
1.Обзор предмета
linux программирование операционный система
Курс «Операционные системы и оболочки» рассчитан
на ознакомление с основным инструментарием и возможностями различных
операционных систем, в частности подробное ознакомление с семействами Windows и
Linux.
Помимо теоретического материала, включающего в
себя подробное рассмотрение истории развития операционных систем, их структуры,
особенностей реализации и т.д., было сделано 7 лабораторных работ, целью
которых было непосредственное ознакомление с инструментарием и внутренним
устройством операционных систем упомянутых выше семейств.
Итогом курса стала курсовая работа, состоящая в
разработке трёх приложения для системы семейства Linux,
используя такой язык программирования, как С++.
2.Постановка
задачи
Целью данной работы была выработка навыков
программирования с использованием терминала в Unix
подобных системах.
Для осуществления данной цели были поставлены
следующие задачи:
Установить на персональном компьютере одни из Unix
подобных систем;
Написать приложение для Linux, управляющее
светодиодами клавиатуры CAPS, SCROLL, NUM lock через драйвер консоли tty(4) и
реализующее новогоднюю гирлянду в нескольких режимах работы: бегущие огни,
случайное мерцание, цветомузыка;
Написать приложение для Linux, управляющее
лотком CD-привода через драйвер cdrom и реализующее несколько новогодних танцев
из балета 'Щелкунчик': танец феи Драже, вальс Цветов;
Написать приложение для Linux, управляющее
встроенной пищалкой через драйвер pcspkr и реализующее несколько незамысловатых
звуковых эффектов: сирену, барабанную дробь.
3.Решение
Для выполнения поставленных целей была выбрана
операционная система Ubuntu
12.10. С помощью программы LinuxLive USB Creator 2.8.18 была создана
загрузочный flash-накопитель,
с которого велась установка новой операционной системы. После изменения
настроек приоритета Boot
в BIOS, была произведена
установка Ubuntu параллельно
с уже установленной Windows
(которая после всего выше описанного перестала грузиться).
Имея среду разработки, были написаны следующие
программы 1led.c,
2cd.c,
3musicbox.c.
4.Общие
сведения
о
запуске
Для запуска программ выполним следующие
операции:
. Открытие терминала (можно
воспользоваться Ctrl
+ Alt + T);
. Для проверки файла можем
воспользоваться:
ls (Выводит список
файлов и каталогов по порядку, можем использовать для проверки наличия файла в
данной директории);
nano (вызов
редактор в терминале).
. Необходимо запустить стандартный
компилятор, для этого вводим команду:
gcc -o
program_name
program_name.c,
где:
gcc (или cc)
- компилятор С;
о - параметр для записи результата в файл;
program_name
- имя будущего исполняемого файла;
program_name.c
- исходный файл с нашей программой.
Для удобства файл программы следует хранить в
директории ~/bin внутри
директории /Home. Это
позволит запускать программу из любой текущей директории. Создать её можно с
помощью «mkdir».
. Запуск осуществляется с помошью команды
sudo ./program_name *parameters*, где
sudo - режим
суперпользователя, команда потребует ввода пароля;
./program_name
- директория и имя исполняемого файла;
*parameters*
- перечисление возможных параметров программы.
. Получение результата программы.
Рис. 1. Иллюстрация корректности компиляции всех
3-х программ и получение 3-х исполняемых файлов.
Рис.
.Запуск программы 1led c sudo ./led
1
Программа работает в режиме «1» - поочерёдное
мигание каждого из светодиодов создает эффект гирлянды. Для этого реализован
цикл из 3 итераций для того, чтобы функции ioctl (fd,KDSETLED,LED[j]) в качестве
параметра передавать поочерёдно из массива идентификатор каждого из
светодиодов. Мигание представляет собой включение и отключение
(ioctl(fd,KDSETLED,0)) светодиодов через некоторые интервалы времени. Программа
совершает 25 итераций, после чего мы вновь можем обращаться к терминалу.
6.Запуск программы 1led с sudo ./led
2
Программа работает в режиме «2» - случайное
мигание одного из светодиодов. Генерация случайного значение происходит таким
образом: ioctl(fd,KDSETLED,LED[rand()%3]). Программа совершает 25 итераций,
после чего мы вновь можем обращаться к терминалу.
При неверном вводе параметров будет выдано
сообщение об ошибки, после чего мы вновь можем обращаться к терминалу.
Запуск программы 2cd.c sudo ./cd В данном случае
запуск производится без параметров. Благодаря функциям открытия дисковода
(ioctl(fd,CDROMEJECT,0)) и его закрытия (ioctl(fd,CDROMCLOSETRAY,0))
реализуется подобие «танца» под саундтрек к фильму «Звездные Войны».
Запуск программы 3musicbox.c sudo modprobe
pcspkr sudo ./ music
Перед запуском программы необходимо включить
pcspkr - спикер персонального компьютера. После запуска программы
воспроизводятся мелодии, определяемые параметрами:
- эффект сирены (нарастание и убывание частоты
звучание спикера)
- эффект барабанной дроби
- воспроизведение композиции «В лесу родилась
ёлочка».
Изначально мы тестировали мелодии в Windows MVS
с помощью функции beep. Затем мы преобразовали из 10-ой системы (с которой
работает beep) счисления в 16-ую (в ней формируются системные вызовы) с помощью
такой операции: 1193180/frequency. Где было возможно, мы явно преобразовывали в
16-ую систему счисления. Также продолжительность для вызовов терминала пришлось
увеличить, умножив на 1000. Подобное решение было взято, после прочтения
следующего форума: #"701318.files/image002.gif">
Рис. 2. Часть данных, полученных после
трассировки первой программы.
Как мы видим, в ходе исполнения первой
программы, сначала открывается файловый дескриптор, значение которого равно 3,
то есть неотрицательно, а значит корректно. Далее strcmp
- проверка параметров, ioctl
- системные вызовы функций с идентификатором 19250 и параметром в 16-ой системе
счисления. Все описанные функции вернули 0, что гарантирует корректность их
работы.
Для второй программы можно увидеть следующее: сначала
запускается музыка, затем открывается дисковод, потом воспроизводится фрагмент
емлодии, затем дисковод закрывается и так далее.
Третья программа также корректно работает во
всех 3-х режимах.
Для эксперимента программа также запускалась на
компьютере, без функции закрытия cd
лотка и без драйвера для спикера. Были получены следующие результаты:
Рис. 3. Часть данных, полученных после
трассировки второй программы на компьютере, без функции закрытия cd лотка и без
драйвера для спикера.
Видно, что в случаях обращения к несуществующим
функциям, возвращается -1, после чего программа выполняется дальше. При
отсутствии драйвера программа не находит устройство (что вполне логично). При
обращении к драйверу с несуществующей функцией, системы выдаёт ошибку
ввода-вывода, что тоже логично.
.Анализ результатов
Была успешно установлена операционная система Ubuntu
семейства Linux.
Были разработаны 3 приложения, каждое из которых
работает.
Нами были закреплены навыки использования терминала
для управления персональным компьютером, как то:
использование стандартных команд;
написание своих программ, в частности во
встроенном редакторе, их сборка и отладка;
тестирование команд с помощью стандартных
средств, изучений обращений программ к уже готовым функциям, драйверам и
библиотекам.
Источники
.http://ubuntu.ru/
.http://lxr.linux.no/linux/
.http://www.linuxmanpages.com/man4/console.4.php
.http://www.linuxmanpages.com/man4/console_ioctl.4.php
.http://lxr.linux.no/linux+v3.6.6/Documentation/ioctl/cdrom.txt#L251
.http://ru.wikipedia.org/wiki/%D0%A9%D0%B5%D0%BB%D0%BA%D1%83%D0%BD%D1%87%D0%B8%D0%BA
.http://ru.wikipedia.org/wiki/%D4%E0%E9%EB%EE%E2%FB%E9_%E4%E5%F1%EA%F0%E8%EF%F2%EE%F0
.http://ubuntuforums.org/showthread.php?t=873679
.man
- (manual) - команда вызова справки через терминал (manual)
Приложение
1. Программа 1led.c
#include
<stdio.h>
int main( int argc , char *argv[])
{fd = 0;leds;i=0;LED[] = {LED_NUM,LED_CAP,LED_SCR};inter
= 0;= open("/dev/console",O_RDWR);(fd<0)
{("open(/dev/console)");1; }(fd,KDGETLED, &leds);(argc != 2)
{("%s\n","Error.
Rewrite parametrs!");2;
}(strcmp(argv[1],"1")==0)
{j=0;(i=0;i<25;i++)
{(j=0;j<3;j++)
{(fd,KDSETLED,0);(fd,KDSETLED,LED[j]);(100000);
}
}
}(strcmp(argv[1],"2")==0)
{(i=0;i<25;i++)
{(fd,KDSETLED,0);(fd,KDSETLED,LED[rand()%3]);(100000);
}
}(fd);0;}
. Программа
2cd.c
#include <stdio.h>
#include <signal.h>
#include <linux/kd.h>
#include <sys/types.h>
#include <fcntl.h>
#include
<linux/cdrom.h>main(int argc, char* argv[])
{fd;i
=0;frequency[]={300,0,300,0,300,0,250,0,350,300,0,250,0,350,300,0};duration[]={500,50,500,50,500,50,500,50,250,500,50,500,50,250,500,50};=
open("/dev/sr0", O_RDWR|O_NONBLOCK);(fd<0) {("open(/dev/cdrom)");1;
}(i=0;i<16;i++)
{if((i==0)||(i==8))
{ioctl(fd,CDROMEJECT,0);}((i==5)||(i==13))
{ioctl(fd,CDROMCLOSETRAY,0);}(frequency[i]!=0)
{frequency[i]=1193180/frequency[i];}(fd, KIOCSOUND,
frequency[i]);(1000*duration[i]);
}(fd);0;}
. Программа
3musicbox.c
#include <stdio.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/kd.h>
#include <sys/types.h>
#include <fcntl.h>main(int
argc, char* argv[]){fd;i = 0;j = 0;= open("/dev/tty0",
O_WRONLY);(fd<0)
{perror("open(/dev/tty0)");return
1;}(argc != 2)
{printf("%s\n","Error.
Rewrite parametrs!");2; }(strcmp(argv[1],"1")==0)
{for (j=0;j<5;j++)
{int frequency = 0x0384;deltafreq =
0x000A;(i=0;i<200;i++)
{frequency=frequency+deltafreq;(fd,
KIOCSOUND, frequency);(10000);}(i=0;i<200;i++)
{=frequency-deltafreq;(fd,
KIOCSOUND, frequency);(10000);
}
}
}(strcmp(argv[1],"2")==0)
{frequency;duration[] = {300, 900,
300, 900, 100, 400, 100, 1000};(i=0;i<5;i++)
{(j=0;j<8;j++)
{= 0x0064;(j%2==0)
{frequency=0;}(fd, KIOCSOUND, frequency);(1000*duration[j]);
}
}
}(strcmp(argv[1],"3")==0)
{frequency[] = {247, 417, 417, 370,
417, 329, 247, 247, 417, 417, 370, 417, 497, 0, 497, 277, 277, 440, 440, 417,
370, 329, 247, 417, 417, 370, 417};(i=0;i<27;i++)
{(frequency[i]!=0) {frequency[i]=1193180/frequency[i];}(fd,
KIOCSOUND, frequency[i]);(500000);
}
}(fd, KIOCSOUND, 0);(fd);return 0;}