-Tумблер- 0 24 мая, 2005 Опубликовано 24 мая, 2005 · Жалоба А я что-то не соображу, почему из 2-х разных потоков одновременно читать/писать неполучится И я тоже не рад этой особенности XP. :( Еще раз подтверждаю (опять "влетел") - дело не в разных потоках. Если в программе возможно обращение к порту ОДНОВРЕМЕННОЕ из разых потоков, под XP аппликэйшн зависнет насмерть. А для WIN98 нет проблем. :excl: Это касается всех функций использующих idComDev ( где idComDev это : HANDLE idComDev = ::CreateFile.......) В том числе и ::GetCommModemStatus ::GetCommMask ::EscapeCommFunction ::SetCommState(idComDev, &dcb).. И видимо вообще для всех. В случае применения синхронизации для использования этих функций из разных потоков никаких проблем не обнаружено. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yuriyc 0 25 мая, 2005 Опубликовано 25 мая, 2005 · Жалоба Так REALTIME_PRIORITY_CLASS это вроде и есть приоритет процесса :) Скажу больше - для приоритета есть еще и динамический диапазон определяемый относительно базового. :blink: Правда для такого REALTIME приоритета процесса, поток все равно получился 15. Не знаю почему. Глубоко не ковырялся. <{POST_SNAPBACK}> Обратимся к книге Джеффри Рихтера "Windows Создание эфективных win-32 приложений". " -Концепция класса приоритета вводит некоторых в заблуждение. Они делают отсюда вывод, будто процессы учавствуют в распределении процессорного времени. Так вот, процессы никогда не получают прцессорное время - оно выделяется лишь потокам. Класс приоритета процесса - сугубо абстрактная концепция, введенная Microsoft с единственной целью: скрыть от разработчика внутреннее устройство планировщика". Приоритет потока всегда относителен к классу приоритета его процесса. Изменение приоритета процесса не влияет на относительный приоритет потока, но сказывается на их уровне приоритета в системе. Клас приоритета потока Относительный приоритет Idle Bellow Normal Above High Real-time потока Normal Normal Time-Critical 15 15 15 15 15 31 Highest 6 8 10 12 15 26 Above Normal 5 7 9 11 14 25 Normal 4 6 8 10 13 24 Bellow Normal 3 5 7 9 12 23 Lowest 2 4 6 8 11 22 Idle 1 1 1 1 1 16 Уровень 0 зарезервирован. Кроме того, уровни 17-21 и 27-30 в обычном приложении тоже не доступны.Вы можете пользоваться ими, только если пишите драйвер устройства, работающего в режиме ядра. И еще одно: уровень приоритета потока в процессе с классом real time не может опускаться ниже 16. а потока с любым другим классом поднималься выше 15. И еше : 1. Планировщик не документирован полностью 2 Microsoft не разрешает в полной мере использовать особенности планировщика 3. Microsoft предупреждает, что алгоритмп ланировщика постоянно меняется, и не рекомендует писать программы в расчете на текущий алгоритм. Вот так обстаят дела :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lukomor 0 22 июня, 2005 Опубликовано 22 июня, 2005 · Жалоба Обратимся к книге Джеффри Рихтера "Windows Создание эфективных win-32 приложений". " -Концепция класса приоритета вводит некоторых в заблуждение. Они делают отсюда вывод, будто процессы учавствуют в распределении процессорного времени. Так вот, процессы никогда не получают прцессорное время - оно выделяется лишь потокам. Класс приоритета процесса - сугубо абстрактная концепция, введенная Microsoft с единственной целью: скрыть от разработчика внутреннее устройство планировщика". ... Уровень 0 зарезервирован. Кроме того, уровни 17-21 и 27-30 в обычном приложении тоже не доступны.Вы можете пользоваться ими, только если пишите драйвер устройства, работающего в режиме ядра. И еще одно: уровень приоритета потока в процессе с классом real time не может опускаться ниже 16. а потока с любым другим классом поднималься выше 15. <{POST_SNAPBACK}> 2yuriyc: Спасибо за информацию. Я пользовался в основном "Windows 98. Руководство разработчика. Бен Эззель, Джим Блейни". Правда _измеренный_ приоритет потока THREAD_PRIORITY_TIME_CRITICAL в REALTIME_PRIORITY_CLASS не поднимался выше 15. Но я проверил опытным путем. Запустил бесконечный цикл с этим приоритетом, в результате повесилась даже мышка :). 2all: Кто нибудь знает, каким образом можно точно переключить RTS после передачи слова? Автоматический вариант не подходит :( Происходит или большая задержка между концом слова и переключением или RTS переключается раньше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yuriyc 0 28 июня, 2005 Опубликовано 28 июня, 2005 · Жалоба <{POST_SNAPBACK}> 2all: Кто нибудь знает, каким образом можно точно переключить RTS после передачи слова? Автоматический вариант не подходит :( Происходит или большая задержка между концом слова и переключением или RTS переключается раньше.<{POST_SNAPBACK}> Как вариант: можно отследить событие/прерывание возникающее по окончанию передачи байта. И ручками выставить RTS. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vm1 0 28 июня, 2005 Опубликовано 28 июня, 2005 · Жалоба Мне кажется из под Win управлять RTS дело безнадежное. Вы видимо подключаетесь к RS485 и вам понадобится преобразователь интерфейса. Обычно он автоматом управляет активностью передатчика ориентируясь на заданную для него скорость. Работает как одновибратор на время передоваемого слова, стартует от стартового бита. RTS от PC при этом не используется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lukomor 0 29 июня, 2005 Опубликовано 29 июня, 2005 · Жалоба Как вариант: можно отследить событие/прерывание возникающее по окончанию передачи байта. И ручками выставить RTS. <{POST_SNAPBACK}> Отлов прерываний WIN32? Это если только на уровне драйвера. Других способов не знаю. Событие - возврат из функции записи в порт. При этом если сразу выставить RTS, а потом посмотреть на осциллограф то получится что RTS выставляется в СЕРЕДИНЕ передаваемого слова, то есть надо вводить программную задержку, при этом она (задержка) должна определяться для каждой машины отдельно. RTS выставляю EscapeCommFunction(...). 2vm1: Вы правы, но к сожалению преобразователь интерфейса уже есть и изменить его нельзя, поэтому управлять RTS могу только с машины. Причем добавлять какое-либо оборудование тоже нельзя - все задокументировано и согласовано :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vm1 0 4 июля, 2005 Опубликовано 4 июля, 2005 · Жалоба а есть возможность передавайть последний байт транзакции тогда когда вы достоверно контролируете возможную задержку по снятию RTS? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Krom 0 7 июля, 2005 Опубликовано 7 июля, 2005 · Жалоба Вот примерчик для Borland C++ Builder из моей тестовой программки. hCOM, dcb, и sTO обьявлены глобально ( HANDLE hCOM, DCB dcb, COMMTIMEOUTS sTO), в классе MainForm, cbBaudRate - комбо-бокс на главной форме с выбором скорости обмена. int __fastcall TMainForm::InitComm(int portno) ///////////////////////////////////////////////////////////////////////////// // // Инициализация COM-порта с номером portno. Если инициализация прошла // успешно, то функция возвращает 0, в противном случае один из следующих // кодов: // -1 не удалось получить доступ к COM-порту // -2 не удалось получить доступ к блоку dcb // -3 не удалость перенастроить порт // -4 ошибка при настройке тайм-аутов // ///////////////////////////////////////////////////////////////////////////// { char portname[8]; int result; DWORD val; sprintf(portname,"COM%d",portno); // hCOM = CreateFile( portname, // GENERIC_READ|GENERIC_WRITE, // Пробуем получить доступ 0, // к COM-порту NULL, // OPEN_EXISTING, // FILE_ATTRIBUTE_NORMAL, // NULL // ); if( hCOM != INVALID_HANDLE_VALUE ) {//*1*----------------------------------------------------------------- // Настройка параметров порта //-------------------------------------------------------------------- if( GetCommState(hCOM,&dcb) ) {//*2* switch( cbBaudRate->ItemIndex ) { case 0: { dcb.BaudRate=CBR_4800; break; } case 1: { dcb.BaudRate=CBR_9600; break; } case 2: { dcb.BaudRate=CBR_19200; break; } case 3: { dcb.BaudRate=CBR_38400; break; } case 4: { dcb.BaudRate=CBR_57600; break; } case 5: { dcb.BaudRate=CBR_115200; break; } default: dcb.BaudRate=CBR_9600; }// end of switch (cbxBaudRate) dcb.ByteSize = 8; // в байте 8 битов dcb.fBinary = True; // альтернативы как бы нет dcb.fNull = False; // dcb.fOutxCtsFlow = False; // disable TS output flow control dcb.fOutxDsrFlow = False; // disable DSR output flow control dcb.fErrorChar = False; // disable error replacement dcb.fAbortOnError = True; // abort reads/writes on error dcb.fDtrControl = DTR_CONTROL_DISABLE; // DTR flow control disable dcb.fRtsControl = RTS_CONTROL_DISABLE; // RTS flow control dcb.fDsrSensitivity = False; // DSR sensitivity disable dcb.fOutX = False; // disable XON/XOFF out flow control dcb.fInX = False; // disable XON/XOFF in flow control dcb.XonLim = 256; // transmit XON threshold dcb.XoffLim = 2048; // transmit XOFF threshold dcb.XonChar = 0x7F; // Tx and Rx XON character dcb.XoffChar = 0x7F; // Tx and Rx XOFF character dcb.EvtChar = 0x02; // received event character dcb.ErrorChar = 0x00; // error replacement character dcb.EofChar = 0x03; // end of input character dcb.fTXContinueOnXoff = False; // XOFF continues Tx (????) if( !SetCommState(hCOM, &dcb) ) { CloseHandle(hCOM); hCOM = INVALID_HANDLE_VALUE; return( -3); } } else { CloseHandle(hCOM); hCOM = INVALID_HANDLE_VALUE; return( -2); }//*2* }//*1* else return( -1); //--------------------------------------------------------------------- // Настройка тайм-аутов //--------------------------------------------------------------------- if( GetCommTimeouts(hCOM, &sTO) ) { sTO.ReadTotalTimeoutConstant = 250; sTO.ReadTotalTimeoutMultiplier = 3; sTO.ReadIntervalTimeout = 2; sTO.WriteTotalTimeoutConstant = 100; sTO.WriteTotalTimeoutMultiplier = 5; if( !SetCommTimeouts( hCOM, &sTO ) ) { CloseHandle( hCOM ); hCOM = INVALID_HANDLE_VALUE; return( -4); } } else { CloseHandle(hCOM); hCOM = INVALID_HANDLE_VALUE; return( -4); } PurgeComm(hCOM,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); ClearCommError(hCOM,&val,NULL); return( 0 ); }//<<< End of InitComm() >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Ну а дальше через функции ReadFile и WriteFile. 1. Передача: len = 5; fSucs = WriteFile( hCOM, &txbuf[0], len, &len, NULL ); if( !fSucs ) { Errors = CE_BREAK|CE_FRAME|CE_IOE|CE_MODE|CE_OVERRUN|CE_RXOVER|CE_RXPARITY|CE_TXFULL; ClearCommError(hCOM, &Errors, NULL); } 2. Прием: len = 5; fSucs = ReadFile( hCOM, &rxbuf[0], len, &len, NULL ); if( fSucs && (len==5) ) { принято } else { сбросить ошибки как при передаче} Количество принятых байт проверять желательно, так как иногда функция возвращает вроде все ОК, хотя считано 0 байтов. Что это за глюк не разбирался. По переключению RTS. Автоматический вариант проходит - сам когда-то писал утилитку для заливки в кассу базы товаров по 485 интерфейсу. Долго мучался, но в конце-концов разобрался - хитрость там какая-то с настройками com-порта, давно это было, попрбую найти в архивах примерчик. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fluent 0 2 апреля, 2007 Опубликовано 2 апреля, 2007 · Жалоба Помогите плиз. Взялся за курсовик.Для начала надо написать прогу для работы с мобилой через com порт. Я в этом совсем не ничего не понимаю.Объясните новичку Скиньте кто что может.Буду очень благодарен Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 2 апреля, 2007 Опубликовано 2 апреля, 2007 · Жалоба Помогите плиз. Взялся за курсовик.Для начала надо написать прогу для работы с мобилой через com порт. Я в этом совсем не ничего не понимаю.Объясните новичку Скиньте кто что может.Буду очень благодарен :bb-offtopic: Меня вот удивляет, зачем учиться, если ничего не понимаешь? Просто уже наприятно видеть на форуме сообщения типа "в электронике не шарю, но хочу сделать устройство на микроконтроллере". Сори за оффтоп. По теме: в интернете, да и на этом форуме полно материала. Поиск спасет Вас. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Djimmy 0 23 июня, 2007 Опубликовано 23 июня, 2007 · Жалоба Запоздало, но тем не менее.. Serial.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaxBMSTU 0 1 июля, 2007 Опубликовано 1 июля, 2007 · Жалоба Я делал так в Visual Studio 2005: Инициализация: SerialPort system_port; system_port = new SerialPort(); system_port.PortName = "COM1"; system_port.BaudRate = 115200; system_port.DtrEnable = true; system_port.ReadBufferSize = 100000; system_port.DataReceived += new SerialDataReceivedEventHandler(system_port_DataReceived); system_port.Open(); system_port.DiscardOutBuffer(); system_port.DiscardInBuffer(); А далее по событию, которое вызывается, когда приходит байт в буфер COM-порта (объемом 100000 байт) пишете свою процедуру обработки принятых данных: void system_port_DataReceived(object sender, SerialDataReceivedEventArgs e) { byte newbyte; while (system_port.BytesToRead >=3) // К примеру, если пришло более трех байт { newbyte=(byte)system_port.ReadByte(); ...... // Тут пишем свою часть обработки принятых данных } } Передавать данные также просто: записываем в выходной буфер - и всё. Вот пример передачи 7-байтного пакета с хэшем data = new byte[7]; data[0] = 183; data[1] = 5; data[2] = 0xA0; data[3] = 0x01; data[4] = 0x01; data[5] = 0x00; data[6] = (byte)(data[1] ^ data[2] ^ data[3] ^ data[4]); system_port.Write(data, 0, data.Length); Всё общение использует только класс SerialPort. Преимущества такого решения в следующем: 1. Поддержка с Win98 (только dotNet 2.0 поставить надо) по WinXP и даже Vista. 2. Программа не занимает ресурсов ПК для постоянного опроса COM-порта. Пришел байт - сработало событие. Не пришел - можете выполнять любые другие действия. 3. Как следствие из пункта 2 программа может быть легко использована в многозадачном приложении. 4. Никаких драйверов писать не надо. Код максимально простой. Читаем MSDN как использовать SerialPort и всё. 5. Есть возможность устанавливать таймер на ожидание прихода данных, просто в данном примере он не использован. Недостаток - Windows не операционная система реального времени, а поэтому НЕТ четкого временного интервала, в течение которого будет передан байт в линию из выходного буфера COM-порта. Но на практике, я общался со скоростью 115200 и реальной информационной ёмкостью 72000 как в сторону ПК, так и в сторону железа - проблем не было, хотя параллельно работал Emule. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MMP 0 8 августа, 2007 Опубликовано 8 августа, 2007 · Жалоба Подскажите как cport310 прицепить к Borland Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
badik 0 28 августа, 2007 Опубликовано 28 августа, 2007 · Жалоба Судя по Вашей переписке - лето было боевое. Есть очень простое решение COM - Delphi + компонент Async32. http://www.tmssoftware.com/ http://www.tmssoftware.com/ta32.htm Downloads Asynchronous serial communications made easy for your Delphi & C++Builder applications Вообще не нужно знать. Задать нужную скорость (константа) - максимум усилий. Работает везде, есть рабочий пример, если ваш контроллер выдаёт символы - их сразу увидите. На Delphi (если не пробывали) писать намного удобней чем на С (мне так кажется). Я правда из-за Async32 остался на Delphi 3 (кто-то ухмыльнётся), когда-то для более старших не получилось и руки не дошли, на сайте то есть, сейчас время жалко. Главное хочется уйти на USB, вот для этого нужен компонент. К стати компонент Delphi 3 есть сам исходный текст - я раз заглянул и мне хватило навсегда. Понял мне в калашный ряд не стоит... Такие вещи будут жить и потом. Иногда приходиться иметь дело с самоделками, хороши до времени. Пример с Win XP. С уважением badik Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 31 августа, 2009 Опубликовано 31 августа, 2009 · Жалоба Запоздало, но тем не менее.. Спасибо классный класс. Давно искал что-то подобное. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться