Bootloader for ATMega

Jun 16, 2006 Last reply: 19 years ago 57 Replies

Hello Michael!

23 Jul 34 17:40, Michael Mamaev wrote to Sergei Podstrigailo:

SP>> SetCommBreak(ComHandle); SP>> ClearCommBreak(ComHandle); MM>>> á ÔÏ ÅÓÌÉ ÔÁÍ ÚÁÂÙÌÉ ÐÏÌÏÖÉÔØ ÔÁËyÀ MM>>> ÆyÎËÃÉÏÎÁÌØÎÏÓÔØ, ÔÏ ÚÁÔÅÑ ÔÅpÑÅÔ ÓÍÙÓÌ... SP>> HÅ ÚÁÂÙÌÉ. SP>> èÏÔÑ ÚÁÔÅÑ ×ÓÅ pÁ×ÎÏ ÓÔpÅÍÎÁÑ - ÐpÉ ÏÔËÌÀÞÅÎÎÏÍ SP>> ËÁÂÅÌÅ ÐpÅÏÂpÁÚÏ×ÁÔÅÌØ ypÏ×ÎÅÊ RS232 ÉÍÅÅÔ ÐpÁ×Ï ×ÙÄÁÔØ SP>> × ËÏÎÔpÏÌÌÅp ÌÀÂÏÅ ÚÎÁÞÅÎÉÅ (ÚÏÎÁ ÎÅÏÐpÅÄÅÌÅÎÎÏÓÔÉ ÐÏ ÓÔÁÎÄÁpÔy). MM> âpÅÄÉÛØ :) MM> ÷Ï-1È, ÄÏËyÍÅÎÔÉpÏ×ÁÎÎÙÍÉ ÓpÅÄÓÔ×ÁÍÉ UART'Á ÐpÏÇpÁÍÍÎÏ ÏÔËÌÀÞÉÔØ MM> ËÁÂÅÌØ ÎÅÌØÚÑ.

úÁÔÏ ÅÇÏ ÍÏÖÎÏ ×ÙÄÅÒÎÕÔØ ÉÚ ËÏÍÐØÀÔÅÒÁ ÒÕËÁÍÉ (ÎÏÇÁÍÉ, Û×ÁÂÒÏÊ...)

MM> HÁ ×ÙÈÏÄÅ ËÏÍÐÁ × ÌÀÂÏÍ ÓÌyÞÁÅ ÂyÄÅÔ ÌÉÂÏ 0, ÌÉÂÏ 1. MM> ÷Ï-2È, break ÉÍÅÅÔ ×ÐÏÌÎÅ ÏÐpÅÄÅÌÅÎÎÙÊ ypÏ×ÅÎØ, ÓÏ×ÓÅÍ ÎÅ ÎyÌÅ×ÏÊ.

þÔÏ ÔÙ ÉÍÅÅÛØ × ×ÉÄÕ??? BREAK - ÄÌÉÎÎÙÊ SPACE (+3...+15V ÎÁ RS232, ÉÌÉ "ÌÏÇÉÞÅÓËÉÊ 0").

HÏÌØ ×ÏÌØÔ ÎÁ ×ÈÏÄÅ RS232 - ÚÏÎÁ ÎÅÏÐÒÅÄÅÌÅÎÎÏÓÔÉ, ÉÍÅÅÔ ÐÒÁ×Ï ×ÏÓÐÒÉÎÉÍÁÔØÓÑ ËÁË ÕÇÏÄÎÏ (ÈÏÔÑ ÔÁËÉ, ËÁË ÐÒÁ×ÉÌÏ, ×ÏÓÐÒÉÎÉÍÁÅÔÓÑ ËÁË MARK (ÌÏÇ.1).

Sergei

Hello Sergei.

Sun Jul 23 2006 23:52, Sergei Podstrigailo wrote to Michael Mamaev:

SP> HÏÌØ ×ÏÌØÔ ÎÁ ×ÈÏÄÅ RS232 - ÚÏÎÁ ÎÅÏÐÒÅÄÅÌÅÎÎÏÓÔÉ, ÉÍÅÅÔ ÐÒÁ×Ï SP> ×ÏÓÐÒÉÎÉÍÁÔØÓÑ ËÁË ÕÇÏÄÎÏ (ÈÏÔÑ ÔÁËÉ, ËÁË ÐÒÁ×ÉÌÏ, ×ÏÓÐÒÉÎÉÍÁÅÔÓÑ ËÁË SP> MARK (ÌÏÇ.1).

ëÁË Ñ ÕÖÅ Ë×ÏÔÉÌ, ÐÒÏÉÚ×ÏÄÉÔÅÌÉ ÐÒÅÏÂÒÁÚÏ×ÁÔÅÌÅÊ ÕÒÏ×ÎÑ ÄÅÌÁÀÔ "ÓÒÅÄÎÀÀ ÔÏÞËÕ" ÚÁ×ÅÄÏÍÏ ×ÙÛÅ ÎÕÌÑ (2-3 ×ÏÌØÔÁ), ÐÌÀÓ ÇÉÓÔÅÒÅÚÉÓ.

Dimmy.

ðpÉ×ÅÔ, Dimmy!

*** 24 Jul 06 11:06, Dimmy Timchenko wrote to Sergei Podstrigailo:

SP>> HÏÌØ ×ÏÌØÔ ÎÁ ×ÈÏÄÅ RS232 - ÚÏÎÁ ÎÅÏÐÒÅÄÅÌÅÎÎÏÓÔÉ, ÉÍÅÅÔ ÐÒÁ×Ï SP>> ×ÏÓÐÒÉÎÉÍÁÔØÓÑ ËÁË ÕÇÏÄÎÏ (ÈÏÔÑ ÔÁËÉ, ËÁË ÐÒÁ×ÉÌÏ, ×ÏÓÐÒÉÎÉÍÁÅÔÓÑ SP>> ËÁË MARK (ÌÏÇ.1).

DT> ÐÒÏÉÚ×ÏÄÉÔÅÌÉ ÐÒÅÏÂÒÁÚÏ×ÁÔÅÌÅÊ ÕÒÏ×ÎÑ ÄÅÌÁÀÔ "ÓÒÅÄÎÀÀ ÔÏÞËÕ" DT> ÚÁ×ÅÄÏÍÏ ×ÙÛÅ ÎÕÌÑ (2-3 ×ÏÌØÔÁ),

á ÔÉÐÉÞÎÏ ÞÕÔØ ÂÏÌØÛÅ ×ÏÌØÔÁ.

DT> ÐÌÀÓ ÇÉÓÔÅÒÅÚÉÓ.

Ó Õ×ÁÖÅÎÉÅÍ ÷ÌÁÄÉÓÌÁ×

А вот у меня VMWare, тварь, не передаёт! :-(

:-O Сам бы никогда не додумался. :-)

Hello Kirill!

27 Jul 34 00:53, Kirill Frolov wrote to Vasiliy Andreev:

KF> :-O óÁÍ ÂÙ ÎÉËÏÇÄÁ ÎÅ ÄÏÄÕÍÁÌÓÑ. :-)

åÝÅ ÂÙ, ÎÁÄÏ ×ÅÄØ ÎÅ FF ÐÅÒÅÄÁ×ÁÔØ, Á 0 :-)

Sergei

ïÞÅÎØ ÒÁÄ ×ÁÓ ×ÉÄÅÔØ, Sergei!

SP> 27 Jul 34 00:53, Kirill Frolov wrote to Vasiliy Andreev:

AVL

Hello Michael.

Sun Jul 30 2006 15:07, Michael Mamaev wrote to me:

MM>>> á ÅÓÌÉ yÄÅpÖÉ×ÁÑ break ×ËÌÀÞÉÔ ÐÉÔÁÎÉÅ? DT>> Hy É? äÁÌØÛÅ ÄÏÌÖÎÁ ÉÄÔÉ ÓÉÇÎÁÔypÁ É ËÏÍÁÎÄÙ ÐpÏÇpÁÍÍÉpÏ×ÁÎÉÑ. åÓÌÉ DT>> ÎÅ ÐÏÓÔyÐÉÌÉ - ÐÅpÅÈÏÄÉÍ ÎÁ ÏÂÙÞÎÙÊ ÓÔÁpÔ. MM> ðpÏÓÔÏÊ É ÈÏpÏÛÉÊ ÁÌÇÏpÉÔÍ ÏÂpÁÓÔÁÅÔ ×ÓÅ ÎÏ×ÙÍÉ ÐÏÄpÏÂÎÏÓÔÑÍÉ :)

üÔÏ ÔÙ ÐÒÏÓÔÏ ËÁÐÒÉÚÎÉÞÁÅÛØ. HÁ ÒÏ×ÎÏÍ ÍÅÓÔÅ.

MM> éÌÉ ÜÔÏ ×ÓÅ ÓÌÉÛËÏÍ ÓÌÏÖÎÏ pÁÂÏÔÁÅÔ, ÉÌÉ ÔÙ ÓÌÉÛËÏÍ ÓÌÏÖÎÏ ÉÚÌÁÇÁÅÛØ. MM> ïÔËyÄÁ ËÏÍÐ yÚÎÁÅÔ, ÞÔÏ ÎyÖÎÏ ÐpÅËpÁÔÉÔØ break É ×ÙÓÌÁÔØ ËÏÍÁÎÄy? ïÔ MM> Ó×ÑÔÏÇÏ ÄyÈÁ?

óÌÏ×Ï "ÈÜÎÄÛÅÊË" ÐÒÉÈÏÄÉÌÏÓØ ÓÌÙÛÁÔØ? ðÏÓÙÌÁÅÍ break, ÐÏÌÕÞÁÅÍ ÅÇÏ ÖÅ, ÓÎÉÍÁÅÍ break, ÐÏÌÕÞÁÅÍ mark. ÷ÏÔ ÞÕÔØ ÐÏÚÖÅ ÓÄÅÌÁÀ ÔÁËÕÀ ÛÔÕËÏ×ÉÎÕ ÄÌÑ AVR-Á - ×ÙÌÏÖÕ × ÜÈÕ, ÐÏÓÍÏÔÒÉÛØ, ÓÌÏÖÎÏ ÌÉ ÜÔÏ...

MM> P.S. õ ÍÅÎÑ Ó ÐpÏÐÉÈÉ×ÁÎÉÅÍ ÄÁÎÎÙÈ ÞÅpÅÚ CTS/RTS ×? ÄÅÊÓÔ×Ï MM> yÍÅÓÔÉÌÏÓØ × MM> ÎÅÓËÏÌØËÏ ÓÔpÏË ËÏÄÁ.

ñ Ö ÔÅÂÅ ÕÖÅ Ä×Á :) ÒÁÚÁ ÎÁÐÉÓÁÌ: ÓÞÉÔÁÅÛØ Ó×ÏÊ ×ÁÒÉÁÎÔ ÂÏÌÅÅ ÈÏÒÏÛÉÍ/ÐÒÁ×ÉÌØÎÙÍ/ÕÄÏÂÎÙÍ - ÎÉËÔÏ ÎÅ ÚÁÓÔÁ×ÌÑÅÔ ÐÅÒÅÄÅÌÙ×ÁÔØ. á ÔÙ ÜÔÉ ÍÏÉ ÓÌÏ×Á ÓËÉÐÁÅÛØ É ÐÒÏÄÏÌÖÁÅÛØ ÓÐÏÒÉÔØ ÄÁÌØÛÅ. :)

Dimmy.

èÁÊÌØ çÉÔÌÅp ËÁÐyÔ, Sergei! ÷ÏÓËpÅÓÅÎØÅ éÀÌØ 23 2006 23:52, Sergei Podstrigailo wrote to Michael Mamaev:

MM>> HÁ ×ÙÈÏÄÅ ËÏÍÐÁ × ÌÀÂÏÍ ÓÌyÞÁÅ ÂyÄÅÔ ÌÉÂÏ 0, ÌÉÂÏ 1. MM>> ÷Ï-2È, break ÉÍÅÅÔ ×ÐÏÌÎÅ ÏÐpÅÄÅÌÅÎÎÙÊ ypÏ×ÅÎØ, ÓÏ×ÓÅÍ ÎÅ MM>> ÎyÌÅ×ÏÊ. SP> þÔÏ ÔÙ ÉÍÅÅÛØ × ×ÉÄy??? SP> BREAK - ÄÌÉÎÎÙÊ SPACE (+3...+15V ÎÁ RS232, ÉÌÉ "ÌÏÇÉÞÅÓËÉÊ 0"). õÇy.

SP> HÏÌØ ×ÏÌØÔ ÎÁ ×ÈÏÄÅ RS232 - ÚÏÎÁ ÎÅÏÐpÅÄÅÌÅÎÎÏÓÔÉ, SP> ÉÍÅÅÔ ÐpÁ×Ï ×ÏÓÐpÉÎÉÍÁÔØÓÑ ËÁË yÇÏÄÎÏ (ÈÏÔÑ ÔÁËÉ, SP> ËÁË ÐpÁ×ÉÌÏ, ×ÏÓÐpÉÎÉÍÁÅÔÓÑ ËÁË MARK (ÌÏÇ.1). HÁÓËÏÌØËÏ Ñ ÐÏÍÎÀ, y ÐpÉÌÉÞÎÙÈ ÐpÅÏÂpÁÚÏ×ÁÌÏË ÜÔÏ ÄÏËyÍÅÎÔÉpÏ×ÁÎÎÁÑ ÆÉÞÁ. úÁ×ÔpÁ ÎÁ pÁÂÏÔÅ yÔÏÞÎÀÓØ.

íÁÊËÌ
íÅÄÂpÁÔØÑ ÐÏ pÁÚyÍy ÖÄyÔ ÷ÁÓ × ÄÁÌÅËÉÈ ÍÉpÁÈ, Dimmy... ÷ÏÓËpÅÓÅÎØÅ éÀÌØ 23 2006 21:35, Dimmy Timchenko wrote to Michael Mamaev:

MM>>>> åÓÌÉ ËÔÏ-ÔÏ ÓÎÁpyÖÉ ÓyÎÅÔ break, ×ÅÓÔÉÍÏ. DT>>> é, yÄÅpÖÉ×ÁÑ break, ÎÁÖ?Ô reset? üÔÏ Hå ÎÁÚÙ×ÁÅÔÓÑ DT>>> ÎÅÐpÏÉÚ×ÏÌØÎÙÍ ÓpÁÂÁÔÙ×ÁÎÉÅÍ. MM>> á ÅÓÌÉ yÄÅpÖÉ×ÁÑ break ×ËÌÀÞÉÔ ÐÉÔÁÎÉÅ? DT> Hy É? äÁÌØÛÅ ÄÏÌÖÎÁ ÉÄÔÉ ÓÉÇÎÁÔypÁ É ËÏÍÁÎÄÙ ÐpÏÇpÁÍÍÉpÏ×ÁÎÉÑ. åÓÌÉ DT> ÎÅ ÐÏÓÔyÐÉÌÉ - ÐÅpÅÈÏÄÉÍ ÎÁ ÏÂÙÞÎÙÊ ÓÔÁpÔ. ðpÏÓÔÏÊ É ÈÏpÏÛÉÊ ÁÌÇÏpÉÔÍ ÏÂpÁÓÔÁÅÔ ×ÓÅ ÎÏ×ÙÍÉ ÐÏÄpÏÂÎÏÓÔÑÍÉ :)

éÌÉ ÜÔÏ ×ÓÅ ÓÌÉÛËÏÍ ÓÌÏÖÎÏ pÁÂÏÔÁÅÔ, ÉÌÉ ÔÙ ÓÌÉÛËÏÍ ÓÌÏÖÎÏ ÉÚÌÁÇÁÅÛØ. ïÔËyÄÁ ËÏÍÐ yÚÎÁÅÔ, ÞÔÏ ÎyÖÎÏ ÐpÅËpÁÔÉÔØ break É ×ÙÓÌÁÔØ ËÏÍÁÎÄy? ïÔ Ó×ÑÔÏÇÏ ÄyÈÁ?

P.S. õ ÍÅÎÑ Ó ÐpÏÐÉÈÉ×ÁÎÉÅÍ ÄÁÎÎÙÈ ÞÅpÅÚ CTS/RTS ×? ÄÅÊÓÔ×Ï yÍÅÓÔÉÌÏÓØ × ÎÅÓËÏÌØËÏ ÓÔpÏË ËÏÄÁ.

íÁÊËÌ

Вот на "получаем mark" хотелось бы остановиться подробнее. Как можно получить mark средствами современных ОС? (Как я думаю -- никак).

Равно как и послать break любой длительности не всегда возможно. Вот MOXA не даёт (т.е. она может и даёт, но драйвер -- нет).

Откуда ты узнаешь, что break кончился? (тебе break сигнализируется как /событие/, *не состояние*. Речь разумеется о программном интерфейсе со стороны ОС (win32, *nix). Осциллографом на ножке ты конечно mark увидишь, не спорю.

Ага. Я только пытаюсь понять, как оно (не) будет работать.

C168H/PCI 8 port multiport board

Мы говорим о 16550A и совместимых или API соответствующей ОС?

В твоём алгоритме я придираюсь не к тому моменту где оно устанавливается (хотя и тут работать не будет -- по той же самой причине), а к тому месту, где определяется что уже вот mark наступил. Вот оно статически только в виде сигналов на проводах присутствует. Но толку-то от этого?

Т.е. он с какой-то вероятностью просто работать не будет. Ибо выставить статический BREAK можно не везде. Как в виндах не знаю (там, вроде, другого и не предусмотрено -- не знаю как эта MOXA себя поведёт), в линуксах/BSD разных версий приключения тебе гарантированы. А как mark поймать я не знаю безотносительно ОС вообще...

По факту возникновения *состояния* BREAK возникает *событие* EV_BREAK. А по факту возникновения состояния /отличного/ от BREAK -- что возникает?

Так вот ни послать BREAK (верней снять его в определённый момент времени), ни определить факт его "снятия" -- в общем случае никак. Частные случаи малоинтересны. BREAK -- это *сигнал*. Ключевое слово -- СИГНАЛ. Это не состояние (хотя с точки зрения сигналов в проводах -- именно состояние).

Bootloader в момент сброса может просто некоторое время ожидать некую кодовую посылку и как-то на неё отвечать. Будет ли там BREAK -- безрзлично. Лишь бы оно в нормальном потоке данных не встречалось. Где тот же BREAK может быть, а может и не быть.

Было бы интересно. В плане реализации ожидания конца BREAK'а.

Я не знаю подробностей. Но мне кажется, что всё-таки не совместим. Ей отдельный драйвер полагается.

Наткнулся, тоже полагаясь на возможность посылки BREAK произвольной длительности.

Разбирался сейчас более детально. Таки она (карточка) запросто даёт. Путаница имеется в её драйвере. Linux (и не только...) как известно очень гибкая система и в нём имеется аж несколько разных способов установить BREAK: путём ioctl TIOCSBRK и TIOCCBRK -- вроде как очень совместимый (и как выяснилось -- в данном случае не работающий), путём TCSBRK и TCSBRKP -- последние два генерируют или стандартную или указанную аргументом длительность сигнала BREAK. На уровне libc по стандарту положена tcsendbreak(), дающая BREAK заданной или стандарной длительности, и которая наличествует не везде, как следует из некоторых источников. Для меня так и осталось загадкой назначение функции break_ctl() , видно только, что остальные ioctl в отличии от TIOCSBRK и TIOCCBRK обрабатываются именно как соответствующий ioctl, без break_ctl. В целом можно сказать, это не проблема, это -- баг.

Нашёл заодно определение BREAK: In the context of asynchronous serial data transmission, a break condition shall be defined as a sequence of zero-valued bits that continues for more than the time to send one byte. The entire sequence of zero-valued bits is interpreted as a single break condition, even if it continues for a time equivalent to more than one byte.

Суть в общем одна. На уровне libc существует лишь способ генерации сигнала BREAK как *сигнала*, а не состояния. (ioctl не рассматриваю). И метод сигнализации о возникновении BREAK рассматривает его как *сигнал*, а не состояние. То-есть по факту конечно состояние, но в программу прикладного уровня будет доставлен, буквально, сигнал.

С pl2313 (вроде, не ошибся) -- работает.

Вспоминается тут в соседнем треде предлагали 0 слать, на медленной скорости. Допустим, нормальный BREAK -- 200ms. Это нужна скорость порядка

50бит/сек. Не все могут такую поддерживать.

Что значит не полностью? Как не 16550A -- сразу не полностью?

Что подтверждать? У меня вот не работает. Именно мультипортовка эта.

Я не вижу путей, как это сделать. И мне думается -- это невозможно.

Hello Kirill.

Wed Aug 02 2006 15:22, Kirill Frolov wrote to me:

KF> öÄÕ ÐÒÉÍÅÒÁ, ËÁË ÉÍÅÎÎÏ ÜÔÏ ÍÏÖÎÏ ÓÄÅÌÁÔØ.

÷ ÏÂÝÅÍ, ÎÅ ×ÉÖÕ ÓÍÙÓÌÁ × ÄÁÌØÎÅÊÛÅÍ ÏÂÓÕÖÄÅÎÉÉ. ÷ӣ ÜÔÏ ÓÈÏÌÁÓÔÉËÁ ËÁËÁÑ-ÔÏ. ëÁË ÂÕÄÅÔ Õ ÍÅÎÑ ÖÅÌÅÚÏ É ÓÄÅÌÁÀ ÚÁÇÒÕÚÞÉË - ËÉÎÕ ÓÀÄÁ. íÏÖÅÔ, ËÏÍÕ-ÔÏ ÐÒÉÇÏÄÉÔÓÑ. òÁÄÉ ÜËÓÐÅÒÉÍÅÎÔÁ ÄÕÍÁÀ ÓÄÅÌÁÔØ ÎÁ C. :)

Dimmy.

Ты упорно не различаешь событие (сигнал) и состояние. Согласно приведённому определению (в моём прошлом письме) BREAK, не важно насколько он длинный, воспринимается как ЕДИНОЕ СОБЫТИЕ. Или сигнал. Ещё раз -- ключевое слово тут *СИГНАЛ*. Внеполосной сигнал RS232 интерфейса. Имеется ввиду не электрический сигнал, как состояние, а сигнал информационный, как событие. Например, приём символа -- это тоже сигнал.

Указанное событие наступит ОДИН РАЗ, независимо на какой период времени будет установлен BREAK.

Специально для тебя написал две тестовые программы: одна для заданного аргументом в командной строке порта (пример: break.exe com1 5) и времени в секундах устанавливает состояние BREAK. Т.е. BREAK в примере будет установлен на 5 секунд для COM1. Другая программа для заданного в командной строке аргументом порта отображает счётчики произошедших событий и последний принятый символ. Опционально вторым аргументом могут идти настройки порта точно также, как у mode com1: ...

Соединяй два порта нуль-модемным кабелем и ставь эксперимент по обнаружению конца BREAK...

=== Makefile ===

.PHONY: all clean all: test.exe break.exe

%.exe: %.c gcc -std=gnu99 -Wall -O2 -o $@ $<

clean: rm -rf test.exe break.exe

=== end of Makefile ===

=== break.c ===

#include <windows.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <errno.h>

#include <ctype.h>

int main(int argc, char *argv[]) { if (2 != argc && 3 != argc) { fprintf(stderr, "Usage: %s <port> [time in seconds]\n", argv[0]); exit(1); }

char *device = argv[1]; unsigned delay = 1000;

if (NULL != argv[2]) { if (1!=sscanf(argv[2], "%u", &delay) || 0==delay || 10<delay ) { fprintf(stderr, "invalid time argument: %s\n", argv[2]); exit(1); } delay*=1000; }

HANDLE fd = CreateFile( device, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 ); if (INVALID_HANDLE_VALUE == fd) { char *msg; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msg, 0, NULL ); fprintf(stderr, "can't open serial device '%s': %s\n", device, msg); exit(1);

}

SetCommBreak(fd); Sleep(delay); ClearCommBreak(fd);

return 0; }

=== end of break.c ===

=== test.c ===

#include <windows.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <errno.h>

#include <ctype.h>

//#include <alloca.h>

#define alloca malloc

int main(int argc, char *argv[]) { if (2 > argc) { fprintf(stderr, "Usage: %s <port> [options...]\n", argv[0]); exit(1); }

char *device = argv[1];

HANDLE fd = CreateFile( device, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 ); if (INVALID_HANDLE_VALUE == fd) { char *msg; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msg, 0, NULL ); fprintf(stderr, "can't open serial device '%s': %s\n", device, msg); exit(1);

}

{ size_t n=1; for (int x=2; x<argc; x++) n+=strlen(argv[x])+1; char *conf = alloca(n); conf[0]=0; for (int x=2; x<argc; x++) (x==2?0:strcat(conf, " ")), strcat(conf, argv[x]); DCB dcb; GetCommState(fd, &dcb); if (!BuildCommDCB(conf, &dcb)) { char *msg; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msg, 0, NULL ); fprintf(stderr, "%s: %s\n", conf, msg); exit(1); } SetCommState(fd, &dcb);

printf("Serial device:\t%s\n", device); printf("Baud rate:\t%s\n", ({ char *f(unsigned mask) { switch (mask) { case CBR_110: return "110"; case CBR_19200: return "19200"; case CBR_300: return "300"; case CBR_38400: return "38400"; case CBR_600: return "600"; case CBR_56000: return "56000"; case CBR_1200: return "1200"; case CBR_57600: return "57600"; case CBR_2400: return "2400"; case CBR_115200: return "115200"; case CBR_4800: return "4800"; case CBR_128000: return "128000"; case CBR_9600: return "9600"; case CBR_256000: return "256000"; case CBR_14400: return "14400"; default: return "unknown"; } }; f(dcb.BaudRate); }) ); printf("Data bits:\t%u\n", (unsigned)dcb.ByteSize); printf("Parity: \t%s\n", ({ char *parity[] = {"none", "odd", "even", "mark", "space"}; dcb.Parity<5 ? parity[dcb.Parity] : "unknown"; }) ); printf("Stop bits:\t%s\n", dcb.StopBits == 0 ? "1" : dcb.StopBits == 1 ? "1.5" : dcb.StopBits == 2 ? "2" : "unknown" ); }

{ DWORD mask; GetCommMask(fd, &mask); mask |= EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RXCHAR; SetCommMask(fd, mask);

COMMTIMEOUTS ts; GetCommTimeouts(fd, &ts); ts.ReadIntervalTimeout=MAXDWORD; ts.ReadTotalTimeoutMultiplier=0; ts.ReadTotalTimeoutConstant=0; SetCommTimeouts(fd, &ts); }

unsigned c_break=0, c_cts=0, c_dsr=0, c_err=0, c_ring=0, c_rxchar=0; char last_c = 0;

while (1) { printf ("BRK:%5u CTS:%5u DSR:%5u ERR:%5u RNG:%5u RXC:%5u (%c)\r", c_break, c_cts, c_dsr, c_err, c_ring, c_rxchar, isprint(last_c) ? last_c : '?' );

DWORD mask; mask = 0; if (! WaitCommEvent( fd, &mask, NULL )) { char *msg; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msg, 0, NULL ); fprintf(stderr, "WaitCommEvent fails: %s\n", msg), exit(1); }

if (mask&EV_BREAK) c_break++; if (mask&EV_CTS) c_cts++; if (mask&EV_DSR) c_dsr++; if (mask&EV_ERR) c_err++; if (mask&EV_RING) c_ring++; if (mask&EV_RXCHAR) c_rxchar++;

while (1) { char buf[256]; DWORD r; if (! ReadFile(fd, buf, sizeof(buf), &r, NULL)) { char *msg; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msg, 0, NULL ); fprintf(stderr, "ReadFile fails: %s\n", msg), exit(1); }

if (0 == r) break;

last_c=buf[r-1]; } /* endless loop */ }

return 0; }

=== end of test.c ===

Это исключительно в рамках windows платформы. Для posix интерфейса аналогичных функций не предусмотрено.

Уже миллион раз совершались подобные ошибки. Когда кто-то считал, что в мире один единственный часовой пояс (разумеется UTC-7), когда кто-то считал, что в сутках 12 часов, что все телефонные номера и адреса -- исключительно московские), что единственный язык на планете -- русский, и что кодировка может быть -- исключительно CP866... На самом деле списол очень большой и продолжать его можно долго...

См. с начала письма.

Зато более универсальный.

Чем он собственно и удобен. Когда нужен способ сигнализации не затрагивающий поток данных. И когда DTR/DSR отсутствует.

Видать неспроста "недоработал"...

Жду примера, как именно это можно сделать.

У меня нет ни сил, ни времени копаться в исходниках линуха. Что там бывает страшно я и так знаю.

Ага. LKML, LKHG...

Я не знаю вообще через какое место он используется. Если бы кто просветил -- был бы рад. В Documentation не посылать.

Какая разница. Сам факт -- не работает. И видимо, никого это не волнет так сильно, что оно давно ещё не исправлено. И не будет работать ещё в миллионе других мест.

"Слив защитан." (C)

Hello Kirill.

Thu Aug 03 2006 00:17, Kirill Frolov wrote to me:

KF> "óÌÉ× ÚÁÝÉÔÁÎ." (C)

÷ÉÚÉÔÎÁÑ ËÁÒÔÏÞËÁ ÐÒÅÄßÑ×ÌÅÎÁ, ËÁÔÅÇÏÒÉÑ ÏÐÒÅÄÅÌÅÎÁ: ÌÀÂÉÔÅÌÉ ÂÏÄÁÔØÓÑ. ÷ÁÓ ÎÅ ÉÎÔÅÒÅÓÕÅÔ ÓÕÔØ ÄÅÌÁ, ×ÏÚÍÏÖÎÏÓÔØ ÞÔÏ-ÔÏ ÕÚÎÁÔØ, ÐÏÄÅÌÉÔØÓÑ ÏÐÙÔÏÍ. úÄÅÛÎÅÅ ÏÂÝÅÎÉÅ ÄÌÑ ×ÁÓ - ÓÏÒÅ×ÎÏ×ÁÎÉÅ (ÂÏÌÅÅ ÉÌÉ ÍÅÎÅÅ ÞÅÓÔÎÏÅ, ÚÁ×ÉÓÉÔ ÏÔ ÜËÚÅÍÐÌÑÒÁ), ×ÁÍ ÎÁÄÏ ÐÏËÁÚÁÔØ, ÞÔÏ ×Ù "ËÒÕÞÅ" ÓÏÂÅÓÅÄÎÉËÁ.

Dimmy.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required