Пользовательский интерфейс

Предыдущая  Содержание  Следующая  V*D*V

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

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

Вывод осуществляется на графический ЖК дисплей.

Энкодер

Драйвер энкодера при повороте генерирует коды щелчков по кнопкам BTN_FORWARD и BTN_BACK.

При нажатии и отпускании кнопки генерируется BTN_MOUSE.

Для работы необходимо иметь в ядре включённой опцию Event interface и узел /dev/input/event0.

 

Код модуля драйвера rotary_encoder.zip.

 

Код для проверки работы:

 

#include <stdio.h>// printf

#include <memory.h>// memset

#include <unistd.h>// open, close, write

#include <fcntl.h>// file flags

#include <errno.h>

#include <linux/input.h>// Evdev

 

static int m_device_fd = -1;

static input_event m_input_data;

static size_t m_nbytes;

static bool RE_Open()

{

    m_device_fd = ::open( "/dev/input/event0", O_RDONLY | O_NONBLOCK );

    if( m_device_fd < 0 )

    {

        ::printf("can not open input device");

        return false;

    }

    // reset internal buffer

    m_nbytes = 0;

    ::memset( &m_input_data, 0, sizeof(input_event) );

    return true;

}

//

// 28 = KEY_ENTER

// 42 = LEY_LEFTSHIFT

// 105 = KEY_LEFT

// 106 = KEY_RIGHT

//#define BTN_MOUSE                0x110

//#define BTN_FORWARD                0x115

//#define BTN_BACK                0x116

//

static void RE_ReadData()

{

    int n;

 

    while( (n = ::read(m_device_fd, (((char*)&m_input_data) + m_nbytes), sizeof(m_input_data) - m_nbytes)) != 0 )

    {

        if( n < 0 )

        {

            if( errno == EINTR )

                continue;

            else

                return;// -1;

         }

 

        m_nbytes += n;

 

        if( m_nbytes == sizeof(m_input_data) )

        {

            m_nbytes = 0;

            printf("time:%ld.%.6ld type:%u code:%u value:%d\r\n",

                        m_input_data.time.tv_sec, m_input_data.time.tv_usec,

                        m_input_data.type, m_input_data.code, m_input_data.value);

            return;// 1;

        }

    }

    return;// 0;

}

 

int main(int argc, char *argv[])

{

    if( !RE_Open() ) return 0;

    // endless loop

    while( true )

    {

        RE_ReadData();

        ::usleep( 10000 );// 10 msec

    }

    return 0;

}

 

Результат работы:

 

нажатие кнопки

time:840.728617 type:1 code:272 value:1   нажатие BTN_MOUSE

time:840.728660 type:0 code:0 value:0     код завершения пакета

time:842.150084 type:1 code:272 value:0   отпускание BTN_MOUSE

time:842.150117 type:0 code:0 value:0     код завершения пакета

 

поворот вправо на один щелчок

time:845.887811 type:1 code:277 value:1   нажатие BTN_FORWARD

time:845.887834 type:0 code:0 value:0     код завершения пакета

time:845.887853 type:1 code:277 value:0   отпускание BTN_FORWARD

time:845.887860 type:0 code:0 value:0     код завершения пакета

 

поворот влево на один щелчок

time:846.653097 type:1 code:278 value:1   нажатие BTN_BACK

time:846.653120 type:0 code:0 value:0     код завершения пакета

time:846.653137 type:1 code:278 value:0   отпускание BTN_BACK

time:846.653144 type:0 code:0 value:0     код завершения пакета

 

Дисплей

Используется чёрно-белый WG19232 с разрешением 192 на 32, подключенный к портам ввода/вывода.

Для работы необходимо иметь в ядре включенной опцию Device Drivers -> Graphics support -> Support for frame buffer devices.

 

Код модуля драйвера и драйвера платформы display.zip.

 

Подключение драйвера платформы описано в "Добавление видеодрайвера с поддержкой кадрового буфера".

 

Для проверки работы драйвера можно направить вывод любого файла размером не больше размера памяти кадрового буфера на экран (в данном случае не более 768 байт):

 

cat test > /dev/fb0

 

или так:

 

echo test > /dev/fb0

 

После выполнения команды на экране должен появиться мусор.

 

Для проверки гашения/включения экрана, если это реализовано в драйвере:

 

echo 1 > /sys/class/graphics/fb0/blank

echo 0 > /sys/class/graphics/fb0/blank

 

Экранное меню

Экранное меню реализовано с помощью библиотеки libgui.

Документация библиотеки: libgui_doc.zip.

 

Пример реализации главного цикла и экранных форм: gui_sample.zip.

Веб интерфейс

Веб интерфейс может быть выполнен с использованием библиотеки LUA или libmicrohttpd.

 

Для libmicrohttpd:

Исправить в connection.c:

 

(time (NULL) - timeout > connection->last_activity)

 

на

 

(time (NULL) - connection->last_activity > timeout)

 

Шаблонный проект для построения страниц: webguitemplate.zip.

Чтение ini-файлов

В Linux почему-то отсутствует стандартная возможность чтения-записи ini-файлов.

Простой вариант (в данной версии строка внутри кавычек не может содержать кавычки):

 

#include <string>

 

//FIXME quotes inside quotes

#define F_INI_SECTION 1

#define F_INI_KEY 2

#define F_INI_DATA 4

/**

 * Reads one line with a key and a data from ini-file.

 * File must have the next structure:

 *

 * # comment

 * [section]# comment

 * key = data # comment

 * key = "#data"

 *

 * @param        f - the input file

 * @return        section - the name of section

 * @return        key - the key of a data

 * @return        data - the data

 */

static int read(FILE* f, std::string* section, std::string* key, std::string* data)

{

    bool iscomment = false;

    char mode = F_INI_KEY;

    bool isquotes = false;

    *key = "";

    *data = "";

    int c;

    while( (c = ::fgetc( f )) != EOF )

    {

        char ch = (char)c;

        if( ch == '#' && !isquotes ) iscomment = true;

        if( ch == '\n' )

        {

            if( mode & F_INI_DATA ) return 1;

            iscomment = false;

            mode = F_INI_KEY;

        }

        if( iscomment ) continue;

        if( mode & F_INI_DATA )

        {

            if( (ch > ' ' || isquotes) && (ch != '\"') ) (*data) += ch;

            if( ch == '\"' ) isquotes = !isquotes;

        }

        if( ch < ' ' ) continue;

        if( ch == ']' ) mode &= ~F_INI_SECTION;

        if( mode & F_INI_SECTION ) (*section) += ch;

        if( ch == '=' ) mode = F_INI_DATA;

        if( ch == '[' )

        {

            mode = F_INI_SECTION;

            *section = "";

        }

        if( (mode & F_INI_KEY) && (ch != ' ') ) (*key) += ch;

    }

    return 0;

}

 

int main(int argc, char* argv[])

{

    FILE* f = ::fopen("app.conf", "r");

    std::string section = "";

    std::string key = "";

    std::string data = "";

    while( read( f, &section, &key, &data ) > 0 )

    {

        printf("\"%s\", \"%s\", \"%s\"\r\n", section.data(), key.data(), data.data() );

    }

    ::fclose( f );

}

Смотри также

Text Interfaces for Embedded Systems by STEVE DREVIK, EMBEDDED SYSTEMS PROGRAMMING SEPTEMBER 1995, p.66.

Локальная копия текста статьи.

Embedded Linux system design and development, Chapter 9, Embedded Graphics.

http://books.google.ru

Essential Linux Device Drivers, Chapter 7. Input Drivers, Chapter 12. Video Drivers.

http://books.google.ru

Choosing a GUI Library for Your Embedded Device

http://www.linuxjournal.com/article/9403

PicoGUI

http://www.picogui.org/

Greg Haerr's Nano-X Window System

http://www.microwindows.org/

Qt - A cross-platform application and UI framework

http://qt.nokia.com/

MiniGUI - A cross-operating-system graphics user interface support system for embedded devices

http://www.minigui.org/

easyGUI - Graphical user interface tool for embedded system

http://www.easygui.com/

Графический интерфейс пользователя с применением микроконтроллеров Microchip

http://www.microchip.com.ru/Support/GUI.html

The Linux keyboard and console HOWTO

http://tldp.org/HOWTO/Keyboard-and-Console-HOWTO.html

Serial Programming HOWTO, перевод

http://linuxland.itam.nsc.ru/howto/Serial-Programming-HOWTO_ru.html

Keyboard scancodes

http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html

В.Костромин, "Linux для пользователя", Глава 9. Подключение и настройка аппаратных устройств

http://www.linuxcenter.ru/lib/books/kostromin/gl_09_03.phtml

GNU libmicrohttpd

http://www.gnu.org/software/libmicrohttpd/

dlib

http://dlib.net/

Wt is a C++ library for developing interactive web applications.

http://www.webtoolkit.eu/wt

Evtest, утилита для отладки системы сообщений, пример работы с системой сообщений Linux

http://beagleboard.googlecode.com/files/evtest.c

SimpleINI

http://code.jellycan.com/simpleini/

BitFontCreator, утилита для генерации шрифтов

http://www.iseasoft.com/bfc.htm

Шрифты Unicode

http://unifoundry.com

http://www.alanwood.net/unicode/fonts.html

 

Предыдущая  Содержание  Следующая