roboforum.ru

Технический форум по робототехнике.

Интеграция исполняемых файлов в веб-интерфейс, потоки данных

Интеграция исполняемых файлов в веб-интерфейс, потоки данных

Сообщение Palachzzz » 10 июл 2010, 20:47

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

Для работы необходимы:
-подключение по локальной сети
-включенный FTP сервер
-Notepad++ или что то подобное


Файлы веб-сервера находятся в /www/
Можете скопировать файлы которые там находятся и сохранить их на память, они нам не понадобятся.


Я буду писать веб страницу с нуля, чтобы все было понятно, и без кучи лишней красоты.

Сначала создадим главную страницу index.html

Код: Выделить всёРазвернуть
<html><head> <meta http-equiv=Content-Type content=text/html> 
<title>Test page</title> </head>
<body>
<body bgcolor="#AAAAAA">
<table width="300" align="center" cellpadding="0">
   <tr>
      <td width="100">
         <p align="center"><a href="index.html">Home</a>
      </td>
      <td width="100">
         <p align="center"><a href="input.cgi">Input</a>
      </td>
      <td width="100">
         <p align="center"><a href="output.html">Output</a>
      </td>
   </tr>
   <tr>
   <td colspan=3><p align="center">MINI 2440 TEST PAGE by Z_Z_Z</td>
   </tr>

</table>
</body></html>


Вверху страницы три ссылки Home (заглавная страница), Input (работа с вводом), Output (работа с выводом).

Теперь создаем файл input.cgi, вообще файлы cgi могут быть написаны на любом языке программирования, и они являются шлюзами между веб-сервером и остальной системой.
Этот файл будет у нас представлять обычный исполняемый файл шела (/bin/sh)
Но если кому то более удобно это может быть файл perl'a (/usr/bin/perl) (если он установлен), можно использовать даже откомпилированный ELF..
При нажатии на ссылку Input этот файл .cgi выполнится, и если не хотим смотреть на пустой экран или ошибки, он должен вывести страницу.
Наш файл input.cgi будет опрашивать АЦП с переменным резистором, установленным на плате, и кнопки, находящиеся там же, и выводить на экран веб-страничку с данными.

Код: Выделить всёРазвернуть
#!/bin/sh   //указываем с помощью чего надо это открывать
echo "Content-type: text/html; charset=utf-8" //начинаем выводить страницу
echo
/bin/cat temp.template         //берем заготовку веб-страницы из файла
echo "<p align=center>"        //выравнивание по центру
echo                           
/root/adctest                  //запускаем программу опроса АЦП и выводим результат
echo
/root/buttonstest              //запускаем программу опроса кнопок и выводим результат
echo "</p><p align="center"><a href="input.cgi">Refresh</a></body>"   //дописываем ссылку Refresh и завершаем страницу

exit 0


Чтобы не мучаться с выводом страницы, я создал файл заготовки веб страницы: temp.template
Код: Выделить всёРазвернуть
<html><head>
<title>Input test</title>
<style type="text/css">
<!--
body {
   background-color: #AAAAAA;
}
-->
</style>
</head>
<table width="300" align="center" cellpadding="0">
   <tr>
      <td width="100">
         <p align="center"><a href="index.html">Home</a>
      </td>
      <td width="100">
         <p align="center"><a href="input.cgi">Input</a>
      </td>
      <td width="100">
         <p align="center"><a href="output.html">Output</a>
      </td>
   </tr>


</table>


Заготовка - немного измененная заглавная страница. В общем то все готово.. Осталось только упомянуть использованые программы adctest и buttonstest.
Они были взяты из исходников на диске (linux/examples) и были немного откорректированны, для работы с веб интерфейсом. Это то что осталось от обработки АЦП:

Код: Выделить всёРазвернуть
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <errno.h>
#include <string.h>

int main(void)
{
   int fd = open("/dev/adc", 0);    //открываем файл  АЦП
   if (fd < 0) {
      perror("open ADC device:");  // ошибка при открытии
      return 1;
   }
   {
      char buffer[30];
      int len = read(fd, buffer, sizeof buffer -1);
      if (len > 0) {
         buffer[len] = '\0';
         int value = -1;
         sscanf(buffer, "%d", &value);
         printf("ADC Value: %d\n", value);
      } else {
         perror("read ADC device:");
         return 1;
      }

   }
   
   close(fd);
}


А это от кнопок:

Код: Выделить всёРазвернуть
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>

int main(void)
{
   int buttons_fd;   

   buttons_fd = open("/dev/buttons", 0);   //открываем файл обработки кнопок
   if (buttons_fd < 0) {
      perror("open device buttons");      //если ошибка-выводим ошибку
      exit(1);
   }
   char current_buttons[6];        //массив из состояния 6 кнопок
   int i;
      if (read(buttons_fd, current_buttons, sizeof current_buttons) != sizeof current_buttons) {  //читаем состояния кнопок
         perror("read buttons:");    //если ошибка-выводим ошибку
         exit(1);
      }
      printf("<br>");
      for (i = 0; i < 6; i++) {
         printf("Key %d is %s\n <br>", i+1, current_buttons[i] == '0' ? "up" : "down");  //выводим состояния кнопок
      }


   close(buttons_fd);   //закрываем файловую переменную
   return 0;
}


Особенностью является, что обе программы выполняются не в цикле, а один раз, и в проге кнопок пришлось добавить в некоторые места <br> для перевода строки в HTML'е (иначе все в одну строку).
После копирования файлов на девайс обязательно сделать
chmod +x adctest
chmod +x buttonstest
chmod +x input.cgi

Вот результат с получившейся страницы input:
ADC Value: 404
Key 1 is up
Key 2 is up
Key 3 is down
Key 4 is up
Key 5 is down
Key 6 is up


Подведем итог:
Для запуска файлов достаточно сделать исполняемый файл .cgi, и вызывать его по ссылке из html'а.
Файл .cgi может быть написан как на любом скриптовом языке, так и на нормальном C++.
Файл .cgi может вызывать любые исполняемые файлы в ОС.
Файл .cgi может обмениваться данными с помощью стандартного вывода, а так же через сторонние файлы с приложениями ОС, а затем выводить их на веб-страницу


Работа с выводом:
Принцип тот же самый, только необходимо знать некоторые особенности.
Для ввода данных в HTML используются формы:
Код: Выделить всёРазвернуть
<FORM ACTION="output.cgi" METHOD="get">...</FORM> 

В форме может быть несколько разных элементов INPUT различных типов.
Помещаем на страницу элементы ввода:
Код: Выделить всёРазвернуть
<form method="get" action="output.cgi" name="PWM-TEST">
<input type="radio" value="on" checked name="type">On</td>
<input type="radio" name="type" value="off">Off</td>
<input type="submit" value="OK" name="submit"></td>
</form>

Переключатель On/Off и кнопка ОК.
При нажатии кнопки ОК сформируется строка такого вида:
Код: Выделить всёРазвернуть
action?name=value&name=value&name=value 

В нашем случае будет выглядеть так:
Код: Выделить всёРазвернуть
output.cgi?type=on&submit=ok 

в результате запустится output.cgi :
Код: Выделить всёРазвернуть
#!/bin/sh
case $QUERY_STRING in
   *on*)
      /usr/bin/nohup /root/pwmtest >/dev/null &
      ;;
   *off*)
      /bin/kill -9 `/bin/pidof pwmtest`
      ;;
esac

//здесь должен быть вывод страницы после выполнения команды
exit 0

Строка передается в .cgi в виде переменной QUERY_STRING.
Проверка на содержание этой строки в данном примере - халтурная, разборка строки на составляющие не происходит, просто проверяется, есть ли в строке слово On и Off.
а это исходник pwmtest:
Код: Выделить всёРазвернуть
#include <stdio.h>
#include <stropts.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

#define PWM_IOCTL_SET_FREQ      1
#define PWM_IOCTL_STOP         0


static int fd = -1;
static void close_buzzer(void);
static void open_buzzer(void)
{
   fd = open("/dev/pwm", 0);
   if (fd < 0) {
      perror("open pwm_buzzer device");
      exit(1);
   }

   // any function exit call will stop the buzzer
   atexit(close_buzzer);
}

static void close_buzzer(void)
{
   if (fd >= 0) {
      ioctl(fd, PWM_IOCTL_STOP);
      close(fd);
      fd = -1;
   }
}

static void set_buzzer_freq(int freq)
{
   // this IOCTL command is the key to set frequency
   int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, freq);
   if(ret < 0) {
      perror("set the frequency of the buzzer");
      exit(1);
   }
}
static void stop_buzzer(void)
{
   int ret = ioctl(fd, PWM_IOCTL_STOP);
   if(ret < 0) {
      perror("stop the buzzer");
      exit(1);
   }
}

int main(int argc, char **argv)
{
   
   int freq = 400 ;
   bool upe = true;
   open_buzzer();
   if (argc==2) {
   sscanf(argv[1], "%d", &freq);
   set_buzzer_freq(freq);
   while (true) sleep(1000);
   } else {   
   while( true )
   {
      if (upe) {
      if (freq<3000) {
      freq+=100;}
         else upe = false;
      } else {
      if (freq>500) {
      freq-=100;}
         else upe = true;
      }
      set_buzzer_freq(freq);


   usleep(20000);
   }
   }
}

Ну вот собственно и все. Как видно в исходнике pwmtest, если его запускать без команды, то будет сирена, если запускать с цифрой - будет воспроизводить звук с той частотой что установлена в командной строке, проверки на валидность введенного числа нет.
Если есть желание можно дополнить веб страницу полем ввода частоты воспроизведения. Но тогда придется разбирать строку на составляющие.

В архиве adctest, buttonstest с исходниками, index.html, input.cgi, temp.template
Вложения
www2.rar
(6.98 КиБ) Скачиваний: 0
Последний раз редактировалось Palachzzz 12 июл 2010, 21:44, всего редактировалось 1 раз.
Palachzzz
 
Сообщения: 73
Зарегистрирован: 13 июн 2010, 13:34
Skype: Z_Z_Z-77
прог. языки: С++, Delphi
ФИО: Павел Новиков

Re: Интеграция исполняемых файлов в веб-интерфейс, потоки да

Сообщение Resident » 10 июл 2010, 21:21

Palachzzz писал(а):Особенностью является, что обе программы выполняются не в цикле, а один раз
А чтобы оно опрашивало постоянно в цикле, это нужно писать скрипт регенерации страницы?
или есть другие варианты?
Любой прибор, защищённый плавким предохранителем, сможет защитить этот предохранитель, сгорев первым.
Resident
 
Сообщения: 167
Зарегистрирован: 14 июн 2010, 17:19
прог. языки: Qt/C/C++

Re: Интеграция исполняемых файлов в веб-интерфейс, потоки да

Сообщение avr123.nm.ru » 10 июл 2010, 22:14

Мне очень интересно. Для отладки и чтоб посмотреть как работает нужно сервер на ПК поставить с поддержкой cgi или как ?
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва
Предупреждения: -8

Re: Интеграция исполняемых файлов в веб-интерфейс, потоки да

Сообщение Palachzzz » 10 июл 2010, 22:23

2 Resident, ну мне на ум приходит только flash или какой-нибудь замудреный javascript, но тогда мне кажется проще написать спецпрограмму..
2 avr123.nm.ru, если на ПК поставить, то что опрашивать будешь?) какую информацию выводить?) если очень очень интересно, я конечно могу расшарить свою MINI в интернет, но только не на долго :)
если ты имеешь ввиду как я просматриваю, то просто, переделал что-то, закинул по ФТП на MINI, открываю браузер и смотрю что получилось)
Palachzzz
 
Сообщения: 73
Зарегистрирован: 13 июн 2010, 13:34
Skype: Z_Z_Z-77
прог. языки: С++, Delphi
ФИО: Павел Новиков

Re: Интеграция исполняемых файлов в веб-интерфейс, потоки да

Сообщение Resident » 11 июл 2010, 13:01

Palachzzz писал(а):ну мне на ум приходит только flash
А минька флеш осилит?
Palachzzz писал(а):или какой-нибудь замудреный javascript
Тогда уже AJAX :D
Palachzzz писал(а):но тогда мне кажется проще написать спецпрограмму..
Всмысле которая бинарник на сях? тогда каким образом обновленные данные будут вываливатся в веб-страницу? корректно ли? и в каком формате?
avr123.nm.ru писал(а): Для отладки и чтоб посмотреть как работает нужно
Купить миньку и посмотреть :)
Любой прибор, защищённый плавким предохранителем, сможет защитить этот предохранитель, сгорев первым.
Resident
 
Сообщения: 167
Зарегистрирован: 14 июн 2010, 17:19
прог. языки: Qt/C/C++

Re: Интеграция исполняемых файлов в веб-интерфейс, потоки да

Сообщение MiBBiM » 11 июл 2010, 17:58

простейший яваскрипт заставит браузер автоматом перегружать страницу. let me google that for you: javascript обновить страницу
Tomorrow will be. Better
Аватара пользователя
MiBBiM
 
Сообщения: 1866
Зарегистрирован: 29 окт 2007, 18:11
Откуда: Пермь
прог. языки: Brainfuck/Basic/Delphi/C++/Lisp/x86asm/JavaScript

Re: Интеграция исполняемых файлов в веб-интерфейс, потоки да

Сообщение Palachzzz » 11 июл 2010, 19:06

Resident писал(а):А минька флеш осилит?

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

нет, не вижу смысла выводить какую то срочную информацию через браузер, ну не для таких задач сделан HTTP, если нужна приемлемая скорость обновления, думаю проще и правильнее будет написать простейшее клиент-серверное приложение, которое будет обмениваться с мини нужной инфой... например в примерах на диске есть udptalk, на основе которого легко написать такое приложение...
Palachzzz
 
Сообщения: 73
Зарегистрирован: 13 июн 2010, 13:34
Skype: Z_Z_Z-77
прог. языки: С++, Delphi
ФИО: Павел Новиков

Re: Интеграция исполняемых файлов в веб-интерфейс, потоки да

Сообщение Palachzzz » 12 июл 2010, 21:45

Добавил работу с выводом.
Palachzzz
 
Сообщения: 73
Зарегистрирован: 13 июн 2010, 13:34
Skype: Z_Z_Z-77
прог. языки: С++, Delphi
ФИО: Павел Новиков


Вернуться в mini2440

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

cron