четверг, 23 декабря 2010 г.

Руководство по программированию СОМ-порта

Руководство по программированию СОМ-порта в POSIX операционных системах
Перевод руководства по программированию СОМ-порта в POSIX операционных системах

Управление linux-машиной через последовательный порт

Иногда бывает такое, что по сети компьютер не доступен, а управлять им как-то надо. Обычно в результате ошибок настройки сети. Особенно обидно, когда к нему нет прямого физического доступа. Можно использовать KVM-переключатель с поддержкой сети, но такие устройства пока еще очень дороги, да и требуют достаточно быстрого подключения, потому как передают изображение, а не текст. Сервера известных производителей обычно имеют собственные средства управления (вроде iLo), но эти решения тоже весьма недешевы.
Здесь мы посмотрим на более простой и исторически важный способ удаленного управления. Когда-то давно так осуществлялось управление вообще всеми компьютерами. Да и сейчас он широко применяется для настройки управляемого сетевого оборудования. Это подключение через последовательный порт (он же RS232, он же COM).
Для минимальной настройки нам потребуются всего две строки. Первая в настройках загрузчика (обычно /boot/grub/grub.conf или /boot/grub/menu.lst).

title openSUSE 11.0 root (hd0,0) kernel /boot/vmlinuz root=/dev/disk/by-id/scsi-SATA_ST3200826AS_4ND1LX0B-part1 resume=/dev/sda2 splash=silent showopts console=tty0 console=ttyS0,9600n8 initrd /boot/initrd 

Мы добавили к параметрам ядра строку console=tty0 console=ttyS0,9600n8, которой включили поддержку serial-консоли. Теперь осталось запустить на ней процесс, ответственный за терминал. Это делается в /etc/inittab. Добавим туда строку:

S0:12345:respawn:/sbin/agetty -L 9600 ttyS0 vt102  

Теперь соединяем компьютеры кабелем. В наше время кабель с двумя DB9 Female разъемами еще поискать надо, но найти можно. Осталось настроить программу-терминал. Мы возьмем minicom как наиболее распространенную и присутствующую в большинстве дистрибутивов. Запустите его с ключом -s (minicom -s) чтобы настроить программу. Нам нужно выставить в свойствах com-порта скорость 9600 бит/с, порт /dev/ttyS0, остальное можно оставить по умолчанию. /dev/ttyS0 это порт COM1, если у вас их несколько, укажите соответствующее устройство (они будут называться ttyS1 и так далее). Сохраните как настройки по умолчанию (dfl) и можете соединяться. Для соединения теперь достаточно запустить minicom без параметров.
Единственной проблемой является то, что терминалы не поддерживают Unicode, поэтому русские буквы с высокой вероятностью правильно отображаться не будут. С другой стороны как основной способ управления это использовать никто не будет, а для средства «последней надежды» это не существенно.

суббота, 30 октября 2010 г.

Qt + CodeBlocks

Взято http://jenyay.net/Programming/Codeblocks

По пунктам, что надо сделать для успешной компиляции и отладки.

Компиляция

1. Установить Qt и CodeBlocks :)
2. Скомпилировать вручную Qt. Для этого надо:
- Запустить configure.exe. По умолчанию будет отключена поддержка gif. Чтобы ее включить, надо компилировать с параметром -qt-gif
- Скомпилировать отладочные модули. В папке c:\Qt\4.1.3\src\ запустить make. После долгой компиляции получим отладочные и релизные модули в {QTDir}\lib. Релизные уже есть сразу без компиляции после установки Qt.
3. Прописать переменные окружения
- В PATH добавить C:\Qt\4.1.3\bin и C:\Program Files\CodeBlocks\bin
- Создать переменную QTDIR = C:\Qt\4.1.3 4. Перед компиляцией из CodeBlocks не забыть создать проект Qt с помощью qmake. Для этого надо запустить:
- qmake -project -o projectname.pro
- qmake
5. Вручную исправить полученный проект .pro, например, добавить модули, удалить из проекта лишние файлы.
6. После изменения проекта не забыть запустить qmake, чтобы тот создал makefile, по которому будет компилировать CodeBlocks.
7. Создать проект в CodeBlocks (если его еще нет), куда поместить все файлы исходника
8. Настроить CodeBlocks.
- В настройках Settings->Compiler->Вкладка Other->Build method установить на "Work with Makefiles"
- В свойстве проекта на вкладке Project поставить галку "This is custom Makefile"

Отладка

Дальше идет описание настройки CodeBlocks. Все настройки находятся в свойствах проекта.
1. Для отладки в Makefile записать "Makefile.debug" вместо "Makefile"
2. На вкладке Targets изменить путь к скомпилированному exe-шнику на тот, который реально получается (папка Debug)

четверг, 21 октября 2010 г.

Qt Designer Tutorial

Qt 4.4.3, MinGW, Qt Creator и статическая линковка

Так вот. Линковка по умолчанию занимает 15гиг на винте и 5+ часов. А все почему? А потому, что там примеры и туториалы разные линкуются тоже. Понял я это на утро второго дня. Вообще в линковку через батнички и все такое я втыкал по ходу дела. Отвык уже от командной строки. Свой выбор я сделал еще в 1998 году и привык жмакать на всякие кнопочки на разных формочках. Вобщем, в конце концов я все-таки нашел и немного грубовато заставил линковать только Src папку и вспомогательные тулзы. Как - об этом ниже. Результат - линковка занимает меньше 2х часов на моей машинке.
Значит так. Путем экспериментов у меня получились следующие файлы:
mmake.bat:
call bin\qtvars.bat
pause
configure -static -release -no-exceptions -no-qt3support -qt-gif -qt-libpng -qt-libjpeg -no-phonon -no-webkit -no-phonon-backend -no-assistant-webkit -platform win32-g++
pause
make src
Лежать он должен в папке %QTDIR%. В моем случае я сделал отдельную папку для сборки “static release” - C:\Programming\Qt\4.4.3-1\
Файл qtvars.bat:
echo Setting up a Qt environment...
 
set QTDIR=C:\Programming\Qt\4.4.3-1
echo -- QTDIR set to C:\Programming\Qt\4.4.3-1
set PATH=C:\Programming\Qt\4.4.3-1\bin;%PATH%
echo -- Added C:\Programming\Qt\4.4.3-1\bin to PATH
set MINGWDIR=C:\Programming\MinGW
echo -- MINGWDIR set to C:\Programming\MinGW
set PATH=C:\Programming\MinGW\bin;%PATH%
echo -- Added C:\Programming\MinGW\bin to PATH
set QMAKESPEC=win32-g++
echo -- QMAKESPEC set to "win32-g++"
Файл должен находиться в папке %QTDIR%\bin\.
Далее надо поправить строчку в файле qmake.conf:
QMAKE_LFLAGS_DLL        = -static
Файл лежит в папке %QTDIR%\mkspecs\win32-g++\. Напоминаю, настройки для MinGW, для Студии будет в другом месте и другие строчки. Я настраивал, сохранил кучу текста/подсказок. Возможно со временем напишу инструкцию по линковке и подключению в Visual Studio, но позже. Мне Qt Creator понравился, для моих нужд - самое оно!
И, наконец, шаманим projects.pro файл:
#process the projects
for(PROJECT, $$list($$lower($$unique(QT_BUILD_PARTS)))) {
    isEqual(PROJECT, tools) {
       !cross_compile:SUBDIRS += tools
       else:SUBDIRS += tools/qtestlib
    } else:isEqual(PROJECT, examples) {
#       SUBDIRS += examples
    } else:isEqual(PROJECT, demos) {
#       SUBDIRS += demos
    } else:isEqual(PROJECT, libs) {
       include(src/src.pro)
    } else:isEqual(PROJECT, docs) {
       contains(QT_BUILD_PARTS, tools):include(doc/doc.pri)
    } else:isEqual(PROJECT, translations) {
       contains(QT_BUILD_PARTS, tools):include(translations/translations.pri)
    } else:isEqual(PROJECT, qmake) {
#      SUBDIRS += qmake
    } else {
       message(Unknown PROJECT: $$PROJECT)
    }
}
Файл лежит в %QTDIR%. По сути, я просто закомментировал добавление в CONFIG папки с демками и примерами. У команды config есть ключ -fast, он тоже собирает только сорцы, без лишних вещей, но, по-моему, он еще не собирает папку tools и еще что-то.
Ну вот с настройками и все собственно. Запускаем cmd, в нем >mmake.bat и ждем пока все сконфигурируется и слинкуется.
Коротко про конфигурирование. Фонон нельзя собирать в статике, Веб-Кит тоже. Лицензия не позволяет, однако. Мне и не надо, собирать с ними статику не пробовал. Эта сборка для release. Пишу и дебажу в shared сборке, она у меня лежит в отдельной папке (4.4.3 для shared debug и 4.4.3-1 для static release). Есть проблема с загрузкой jpeg файлов. Посоветовали добавить Q_IMPORT_PLUGIN( qjpeg ) в программу и QTPLUGIN += qjpeg в файл проекта. Будем посмотреть.
Со сборкой вроде все. Буду редактировать, если что вспомню. Вообще как само-цель - сделать из блога мини-справку, возможно не так уж и мини, по Qt. Буду своими словами объяснять, что понял из книг и работы с библиотекой.

Взято: http://www.learnqt.com/category/how-to-learn-qt/qt-install/

пятница, 9 июля 2010 г.

OpenEvent

HANDLE OpenEvent(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName);

Возвращаемое значение
В случае успешного завершения функции возвращается дескриптор объекта события. Если в процессе работы функции возникла ошибка, возвращается нулевое значение. Более подробную информацию об ошибке можно получить, вызвав функцию GetLastError.
Аргументы
dwDesiredAccess - определяет режим доступа к объекту события. В системах, обеспечивающих безопасность объектов, данная функция аварийно завершает свою работу, если дескриптор указанного объекта не допускает использование указанного режима доступа для вызывающего процесса. Этот аргумент может принимать одно из следующих значений:
EVENT_ALL_ACCESS - устанавливает все возможные флаги доступа к объекту события;
EVENT_MODIFY_STATE - обеспечивает возможность использования дескриптора объекта события в функциях SetEvent и ResetEvent, изменяющих состояние объекта события;
SYNCHRONIZE - используется в Windows NT и позволяет использовать дескриптор объекта события в любой из функций ожидания для задания состояния объекта.
bInheritHandle - определяет возможность наследования возвращаемого дескриптора. Если этот аргумент имеет значение TRUE, то процесс, созданный функцией CreateProcess, может наследовать дескриптор. В противном случае дескриптор не может наследоваться.
lpName - указатель на заканчивающуюся нулем строку, содержащую имя открываемого объекта события. При сравнении имен учитывается регистр используемых символов.
Описание
Функция OpenEvent возвращает дескриптор существующего именованного объекта события. Данная функция позволяет нескольким процессам открывать дескрипторы одного и того же объекта события. Функция нормально завершает свою работу только в том случае, когда уже существует объект события с таким именем, созданный другим процессом с помощью функции CreateEvent. вызывающий процесс может использовать возвращаемый данной функцией дескриптор в качестве аргумента любой функции, использующей дескриптор объекта события, при условии соблюдения ограничений, налагаемых значением аргумента dwDesiredAccess. Дескриптор может быть дублирован с использованием функции DuplicateHandle. Для уничтожения дескриптора используется функция CloseHandle. Система автоматически уничтожает дескриптор при завершении процесса. Объект события уничтожается при уничтожении его последнего дескриптора.

среда, 10 марта 2010 г.

Qt/Windows & VC++ 2008 Express

Тут кратко - как построить Qt4 с MS Visual C++ 2008 (9.0) Express

Потребуется:
  1. MS Visual C++ 2008 (9.0) Express
  2. Qt/Windows Open Source Edition (.Zip version )
Шаги:
  • распаковать файлы в папку QtSource :
    • C:\QtSource\

Обновите:"Visual Studio 2008 Command Prompt":

  • запустить "configure.exe"
    • C:\QtSource> configure

configure

  • теперь выполните команду 'nmake" , to compile the source ( придется подождать, от 1 до 4-х часов) :
    • C:\QtSource> nmake

Building

  • Готово , можно посмотреть демонстрацию ( QtSource\bin\qtdemo.exe ):
    • C:\QtSource> cd bin
    • C:\QtSource> qtdemo

Demos

Конфигурация переменных окружения:

Назначено:

    • Папка Qt bin --> C:\QtSrouce\bin
    • Папка Qt lib --> C:\QtSrouce\lib
    • Папка Qt Headers --> C:\QtSource\include

Конфигурация в системе:

  1. Открыть My Computer -> Properties -> Advanced -> Environment Variables
  2. Добавить новую переменную QTDIR:

    • QTDIR=C:\QtSource

  3. Отредактировать переменную PATH добавив следующий путь path:
    • ;%QTDIR%\bin

Конфигурирование VC++: (Tool -> Options , VC++ Directories)

  • Добавить путь в директориях для: Include files:

$(QTDIR)\include

Include files

  • Добавить путь в директориях для: Library files:

$(QTDIR)\lib

Library files

Ну вот и все.

пятница, 26 февраля 2010 г.

Публикация html кода

Для публикации html кода в виде кода)) его надо обработать "заескейпить" - заменить < и > на < и >.

столкнулся при публикации прошлой заметки, воспользовался сиим

tak.ru в отдельном окне

Реализовал это на своем рекламном блоке. Можете попробовать.

Вот крипт, который бы делал видимой ссылку на скачивание допустим файла, после клика по любой из ссылок рекламы с tak.ru . Ну вот собственно результат. Возможно кому ни будь понадобится. Решение состоит из блока с определенным id (Блок может находится в любом месте страницы, но должен быть в единственном числе)...
<div id="hidden" style="display:none;">
То что скрыто!
</div>

...и из скрипта обработчика. Скрипт должен обязательно находится после скрипта с tak.ru (желательно в самом низу body). Вот сам скрипт:
<script>
function payForFiles(){
var hid,tak,elems,num,pat,j,i;
hid = document.getElementById("hidden");
tak = new Array();
elems = document.getElementsByTagName('A');
num = elems.length;
pat = new RegExp("(^|\\b)(takru)(\\b|$)");
j = 0;
for (i=0;i<num;i++){
if(pat.test(elems[i].className)){
elems[i].setAttribute('target','_blank');
if (elems[i].addEventListener)
elems[i].addEventListener("click", 
function(){hid.style.display = ""}, false);
else if (elems[i].attachEvent)
elems[i].attachEvent("onclick", 
function(){hid.style.display = ""});
else elems[i].onclick = function()
{hid.style.display = ""};
j++;}
}
};
payForFiles();
</script>

При клике по любой из ссылок в новом окне открывается рекламируемый сайт а на вашем сайте становится видимым скрытый блок.

studioad.ru

понедельник, 8 февраля 2010 г.

TThread в Delphi

Delphi представляет программисту полный доступ к возможностям программирования интерфейса Win32. Для чего же тогда фирма Borland представила специальный класс для организации потоков? Вообще говоря, программист не обязан разбираться во всех тонкостях механизмов, предлагаемых операционной системой. Класс должен инкапсулировать и упрощать программный интерфейс; класс TThread — прекрасный пример предоставления разработчику простого доступа к программированию потоков. Сам API потоков, вообще говоря, не очень сложен, но предоставленные классом TThread возможности вообще замечательно просты. В двух словах, все, что вам необходимо сделать, — это перекрыть виртуальный метод Execute.

Другая отличительная черта класса TThread — это гарантия безопасной работы с библиотекой визуальных компонентов VCL. Без использования класса TThread во время вызовов VCL могут возникнуть ситуации, требующие специальной синхронизации (см. разд. "Проблемы при синхронизации потоков" далее в этой главе).

Нужно отдавать себе отчет, что с точки зрения операционной системы поток — это ее объект. При создании он получает дескриптор и отслеживается ОС. Объект класса TThread — это конструкция Delphi, соответствующая потоку ОС. Этот объект VCL создается до реального возникновения потока в системе и уничтожается после его исчезновения.

Изучение класса TThread начнем с метода Execute:

procedure Execute; virtual; abstract;

Это и есть код, исполняемый в создаваемом вами потоке TThread.

Примечание

Хотя формальное описание Execute — метод abstract, но мастер создания нового объекта TThread создает для вас пустой шаблон этого метода.

Переопределяя метод Execute, мы можем тем самым закладывать в новый потоковый класс то, что будет выполняться при его запуске. Если поток был создан с аргументом CreateSuspended, равным False, то метод Execute выполняется немедленно, в противном случае Execute выполняется после вызова метода Resume (см. описание конструктора ниже).

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

Если же в потоке будет выполняться какой-то цикл, и поток должен завершиться вместе с приложением, то условия окончания цикла должны быть примерно такими:

procedure TMyThread.Execute;

begin

repeat

DoSomething;

Until CancelCondition or Terminated;

end;

Здесь CancelCondition — ваше личное условие завершения потока (исчерпание данных, окончание вычислений, поступление на вход того или иного символа и т. п.), а свойство Terminated сообщает о завершении потока (это свойство может быть установлено как изнутри потока, так и извне; скорее всего, завершается породивший его процесс).

Конструктор объекта:

constructor Create(CreateSuspended: Boolean);

получает параметр CreateSuspended. Если его значение равно True, вновь созданный поток не начинает выполняться до тех пор, пока не будет сделан вызов метода Resume. В случае, если параметр CreateSuspended имеет значение False, конструктор завершается и только затем поток начинает исполнение.

destructor Destroy; override;

Деструктор Destroy вызывается, когда необходимость в созданном потоке отпадает. Деструктор завершает его и высвобождает все ресурсы, связанные с объектом TThread. function Terminate: Integer;

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

property Terminated: Boolean;

в значение True. Таким образом, Terminate — это указание потоку завершиться, выраженное "в мягкой форме", с возможностью корректно освободить ресурсы. Если вам нужно немедленно завершить поток, используйте функцию Windows API TerminateThread.

Примечание

Метод Terminate автоматически вызывается и из деструктора объекта. Поток— объект VCL будет дожидаться, пока завершится поток— объект операционной системы. Таким образом, если поток не умеет завершаться корректно, вызов деструктора потенциально может привести к зависанию всей программы.

Еще одно полезное свойство:

property FreeOnTerminate: Boolean;

Если это свойство равно True, то деструктор потока будет вызван автоматически по его завершении. Это очень удобно для тех случаев, когда вы в своей программе не уверены точно, когда именно завершится поток, и хотите использовать его по принципу "выстрелил и забыл" (fire and forget).

function WaitFor: Integer;

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

Code := SecondThread.WaitFor;

то это означает, что поток FirstThread останавливается до момента завершения потока SecondThread. Метод WaitFor возвращает код завершения ожидаемого потока (см. свойство Returnvalue).

property Handle: THandle read FHandle;

property ThreadID: THandle read FThreadID;

Свойства Handle и ThreadID дают программисту непосредственный доступ к потоку средствами API Win32. Если разработчик хочет обратиться к потоку и управлять им, минуя возможности класса TThread, значения Handle и ThreadID могут быть использованы в качестве аргументов функций Win32 API. Например, если программист хочет перед продолжением выполнения приложения дождаться завершения сразу нескольких потоков, он должен вызвать функцию API waitForMuitipieObjects; для ее вызова необходим массив дескрипторов потоков.

property Priority: TThreadPriority;

Свойство Priority позволяет запросить и установить приоритет потоков. Приоритеты потоков в деталях описаны выше. Допустимыми значениями приоритета для объектов TThread являются tpidle, tpLowest, tpLower, tpNormai, tpHigher, tpHighest и tpTimeCritical.

procedure Synchronize(Method: TThreadMethod);

Этот метод относится к секции protected, т. е. может быть вызван только из потомков TThread. Delphi предоставляет программисту метод Synchronize для

безопасного вызова методов VCL внутри потоков. Во избежание конфликтных ситуаций, метод synchronize дает гарантию, что к каждому объекту VCL одновременно имеет доступ только один поток. Аргумент, передаваемый в метод Synchronize, — это имя метода, который производит обращение к VCL; вызов Synchronize с этим параметром — это то же, что и вызов самого метода. Такой метод (класса TThreadMethod) не должен иметь никаких параметров и не должен возвращать никаких значений. К примеру, в основной форме приложения нужно предусмотреть функцию

procedure TMainForm.SyncShowMessage; begin

ShowMessagedntToStr (ThreadListl. Count) ) ; // другие обращения к VCL

end;

а в потоке для показа сообщения писать не

ShowMessage(IntToStr(ThreadListl.Count));

и даже не

MainForm.SyncShowMessage;

а только так:

Synchronize(MainForm.SyncShowMessage);

Примечание

Производя любое обращение к объекту VCL из потока, убедитесь, что при этом используется метод Synchronize; в противном случае результаты могут оказаться непредсказуемыми. Это верно даже в том случае, если вы используете средства синхронизации, описанные ниже.

procedure Resume;

Метод Resume класса TThread вызывается, когда поток возобновляет выполнение после остановки, или для явного запуска потока, созданного с параметром CreateSuspended, равным True.

procedure Suspend;

Вызов метода Suspend приостанавливает поток с возможностью повторного запуска впоследствии. Метод suspend приостанавливает поток вне зависимости от кода, исполняемого потоком в данный момент; выполнение продолжается с точки останова.

property Suspended: Boolean;

Свойство suspended позволяет программисту определить, не приостановлен ли поток. С помощью этого свойства можно также запускать и останавливать поток. Установив свойство suspended в значение True, вы получите тот же результат, что и при вызове метода Suspend — приостановку. Наоборот, установка свойства Suspended в значение False возобновляет выполнение потока, как и вызов метода Resume.

property ReturnValue: Integer;

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

На этом завершим подробный обзор класса TThread. Для более близкого знакомства с потоками и классом Delphi TThread создадим многопоточное приложение. Для этого нужно написать всего несколько строк кода и несколько раз щелкнуть мышью.

/Учебник по Delphi для профессионалов/
http://www.intbook.info/delphi/Index.html