- Vote on answer
- posted
17 years ago
Bootloader for ATMega
- Vote on answer
- posted
17 years ago
- Vote on answer
- posted
17 years ago
- Vote on answer
- posted
17 years ago
- Vote on answer
- posted
17 years ago
А вот у меня VMWare, тварь, не передаёт! :-(
:-O Сам бы никогда не додумался. :-)
- Vote on answer
- posted
17 years ago
- Vote on answer
- posted
17 years ago
- Vote on answer
- posted
17 years ago
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.
- Vote on answer
- posted
17 years ago
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ÔÏÞÎÀÓØ.
íÁÊËÌ- Vote on answer
- posted
17 years ago
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ÏË ËÏÄÁ.
íÁÊËÌ- Vote on answer
- posted
17 years ago
- Vote on answer
- posted
17 years ago
Вот на "получаем mark" хотелось бы остановиться подробнее. Как можно получить mark средствами современных ОС? (Как я думаю -- никак).
Равно как и послать break любой длительности не всегда возможно. Вот MOXA не даёт (т.е. она может и даёт, но драйвер -- нет).
- Vote on answer
- posted
17 years ago
- Vote on answer
- posted
17 years ago
Откуда ты узнаешь, что break кончился? (тебе break сигнализируется как /событие/, *не состояние*. Речь разумеется о программном интерфейсе со стороны ОС (win32, *nix). Осциллографом на ножке ты конечно mark увидишь, не спорю.
Ага. Я только пытаюсь понять, как оно (не) будет работать.
C168H/PCI 8 port multiport board
Мы говорим о 16550A и совместимых или API соответствующей ОС?
В твоём алгоритме я придираюсь не к тому моменту где оно устанавливается (хотя и тут работать не будет -- по той же самой причине), а к тому месту, где определяется что уже вот mark наступил. Вот оно статически только в виде сигналов на проводах присутствует. Но толку-то от этого?
Т.е. он с какой-то вероятностью просто работать не будет. Ибо выставить статический BREAK можно не везде. Как в виндах не знаю (там, вроде, другого и не предусмотрено -- не знаю как эта MOXA себя поведёт), в линуксах/BSD разных версий приключения тебе гарантированы. А как mark поймать я не знаю безотносительно ОС вообще...
- Vote on answer
- posted
17 years ago
По факту возникновения *состояния* 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 -- сразу не полностью?
Что подтверждать? У меня вот не работает. Именно мультипортовка эта.
Я не вижу путей, как это сделать. И мне думается -- это невозможно.
- Vote on answer
- posted
17 years ago
- Vote on answer
- posted
17 years ago
- Vote on answer
- posted
17 years ago
Ты упорно не различаешь событие (сигнал) и состояние. Согласно приведённому определению (в моём прошлом письме) 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 не посылать.
Какая разница. Сам факт -- не работает. И видимо, никого это не волнет так сильно, что оно давно ещё не исправлено. И не будет работать ещё в миллионе других мест.
- Vote on answer
- posted
17 years ago
"Слив защитан." (C)
- Vote on answer
- posted
17 years ago