суббота, 20 октября 2012 г.

Обнаружение и разруливание коллизий в сети на протоколе UART

Я долго думал над проблемой объединения кучи микроконтроллеров (МК AVR) в общую сеть. Хотелось иметь простой протокол, в идеале - UART. Но он во-первых не умеет разруливать коллизии, и во-вторых вообще-то даже не предусматривает присутствие нескольких устройств на общей шине!
Но нас такими глупостями не испугаешь.
Поскольку UART мне был нужен также "для самых маленьких" МК (вплоть до tiny13), его пришлось программить самому. Ну а раз пишем сами, то и правила устанавливаем свои :)

Описать сеть я мог бы так: один ПК, много МК на общей шине, полный дуплекс, т.е. отдельные линии RxD и TxD, ПК рассылает на всех разом, МК могут инициировать связь с ПК (но не друг с другом). Схема будет под катом.

В итоге был реализован немного расширенный UART-протокол общения с ПК, который вообще-то полностью совместим с generic-UART, имеет обнаружение коллизий, режим пакетной передачи и позволяет иметь на линии сколь угодно много МК, каждый из которых совершенно свободно может передавать данные в сеть, как только пожелает.
Особенности: никаких арбитров, маркеров, "ответов-только-если-спросили" и прочих ограничений. Абсолютная демократия!
То есть посылаешь в сеть широковещательное "Кто тут?!" и получаешь в ответ аккуратные пакеты, содержащие ответ с адресом каждого МК. Никакой каши.
В виде бонуса, каждому МК можно поставить 3 светика, которые будут отражать соответствующие системные флаги "Линия занята", "Коллизия" и "FRAME ERROR".

Как же я этого добился?!

понедельник, 15 октября 2012 г.

Пишем приложение для Android в Appcelerator (Titanium Studio)

Небольшой tutorial "как писать приложения под Android" от человека, который под телефоны никогда ничего не писал, Java не знает и вообще PHP-разработчик.

PHP-разработчики не всегда знают Java, зато они все должны знать JavaScript. Есть такая штука, Titanium Studio, позволяет писать мобильные приложения на JavaScript. Она еще и бесплатная. Какая удача!

четверг, 11 октября 2012 г.

Не работает CURLOPT_CONNECTTIMEOUT_MS

Очередной квест при работе с curl.
Нужны были таймауты в миллисекундах, версия libcurl 7.21, версия php 5.3, т.е. условиям соответствует.

Но не работает..

тестовый код
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://192.168.0.1/");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 300);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
$res = curl_exec($ch);
var_dump($res, curl_error($ch));
выводит

* Closing connection #0
* Timeout was reached
bool(false)
string(19) "Timeout was reached"

Т.е. даже никаких тебе About to connect и Trying 192.168.0.1, сразу Closing connection, и хоть ты волком вой.
Пробовал переустанавливать libcurl, php5-curl, не помогло.
Полез в гугл по запросу "curlopt_connecttimeout_ms,  timeout was reached" и вышел на спасительный комментарий в мануале:
http://www.php.net/manual/ru/function.curl-setopt.php#104597
The problem is that on (Li|U)nix, when libcurl uses the standard name resolver, a SIGALRM is raised during name resolution which libcurl thinks is the timeout alarm.

т.е. если libcurl использует стандартный name resolver, в процессе резолвинга посылается сигнал SIGALRM, который libcurl принимает за таймаут!

Установка опции nosignal решила проблему.
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);

SOLVED

среда, 3 октября 2012 г.

Интересное поведение mkdir в php

Внезапно обнаружилось, что mkdir не работает с указанием прав так, как от нее ожидается. По крайней мере при запуске скриптов из крона.
Пытаешься указать ей права 770 - папка создается как 750.
Пытаешься 777 - создается как 755. Явно просматривается ограничение по umask.
Но что интересно, chmod() на 770 говорит ОК, следом тут же проверка fileperms() говорит 770, НО по факту в ФС - 755! Ну нихрена себе, мир рушится! Как я теперь могу доверять PHP?!?

В итоге было выяснено, что пых работает с umask 0022.
Вызов umask(0002) перед файловыми операциями привел права в норму, но поведение chmod+fileperms все равно удивляет.

Значит надо запускать php-fpm с явным заданием umask 0002 например.
Однако в дефолтном /etc/bashrc было задано 0002. WTF?!?

Оказалось, что крон просто не цепляет bashrc!