Bootloader for ATMega

Reply to
Dimmy Timchenko
Loading thread data ...
Reply to
Sergei Podstrigailo
Reply to
Dimmy Timchenko
Reply to
Vladislav Baliasov

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

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

Reply to
Kirill Frolov
Reply to
Sergei Podstrigailo
Reply to
Vasiliy Andreev

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.

Reply to
Dimmy Timchenko
èÁÊÌØ çÉÔÌÅ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ÔÏÞÎÀÓØ.

íÁÊËÌ
Reply to
Michael Mamaev
íÅÄÂ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ÏË ËÏÄÁ.

íÁÊËÌ
Reply to
Michael Mamaev
Reply to
Dimmy Timchenko

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

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

Reply to
Kirill Frolov
Reply to
Dimmy Timchenko

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

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

C168H/PCI 8 port multiport board

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

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

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

Reply to
Kirill Frolov

По факту возникновения *состояния* 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 -- сразу не полностью?

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

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

Reply to
Kirill Frolov
Reply to
Dimmy Timchenko
Reply to
Dimmy Timchenko

Ты упорно не различаешь событие (сигнал) и состояние. Согласно приведённому определению (в моём прошлом письме) 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 не посылать.

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

Reply to
Kirill Frolov

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

Reply to
Kirill Frolov
Reply to
Dimmy Timchenko

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.