Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Программирование под Unix/Linux > С++ в Linux и RS485 работа с протоколом |
Автор: hente 20.3.2009, 13:05 | ||
Добрый день уважаемые... Проблема в следующем: не могу записать на порт RS-485 под Linux пишу прогу:
Под виндой смотрю данные из программы Terminal. так вот write работает нармально сообщения уходят, а вот read ну никак не хочет:((( даже не знаю чо делать.... По идее надо переключить режим чтение запись а как это сделать? Гугля ничего путевого не дала.... а сам не знаю куда смотреть... За ранее благодарен ![]() |
Автор: GrayCardinal 20.3.2009, 14:53 | ||||
Извини, но лично я не врубаюсь, как оно должно "работать" ![]() Добавлено через 2 минуты и 36 секунд
меня убило ![]() |
Автор: hente 20.3.2009, 15:31 | ||
Сорри брал не из исходника по этому синт. ошибки ...
|
Автор: GrayCardinal 20.3.2009, 15:32 |
hente, После read воткни perror и скажи результат... |
Автор: hente 20.3.2009, 15:37 |
На Read просто останавливается и никаких ошибок нет... Я так понял идет ожидание появления данных порте или как... Если поставить в опен Open флаг O_NOCTTY тогда Read возвращает 0 |
Автор: kurtis 20.3.2009, 15:49 |
А как у Вас происходит переключение режима Прием/Передача (направление передачи) ? Обычно схематически RS-485 представляет собой 2 линии связи и 3-я линия для управления потоком передачи. Возможно для переключения режима нужно "дергать" пин DTS ком-порта. А как это делается в драйвере Linux это уже читайте документацию вроде Serial HOW-TO или что-то подобное. |
Автор: hente 20.3.2009, 15:55 |
Да вот в том то и проблема что никак... В документациях в примерах никакого переключателя я так и не нашел.. Да и сам пример откуда брал там тож ничего такого нет, просто подряд идут write и read. Щас еще раз попробую прогуглить мож чо полуиться.... но если есть варианты решения проблемы то буду очень рад, да и так спс ![]() Добавлено через 59 секунд к стате как я понял то у RS485 всего 2 канала а не 3 |
Автор: kurtis 20.3.2009, 16:48 | ||
Ну как бы интерфейс считается 2-х проводным, но по факту обычно еще требуется иметь общие земляные потенциалы между абонентами, так что земля может считаться 3-м проводом, но это на важно, я говорил немного не про это. В RS-485 ключевым моментом является переключения направление передачи. В RS485 все устройства делятся на master и slave. Соответственно мастер передает, а слейв слушает и если его спросят, он отвечает. Для избежания мусора на линии используется переключение направление передачи, т.к. мастер изначально становиться на передачу, слейвы становятся на прием и слушают свой адрес для ответа, когда мастер заканчивает передачу, он становиться на прием и начинает слушать кто и что ответит. Слейв который услышал свой адрес, становиться на передачу и отвечает, после ответа он снова становиться на прием, а мастер становиться на передачу. Управление направлением передачи осуществляется программно. Как вы работаете с RS-485 ? Через КОМ-порт (RS-232) или у вас какая-то плата расширения (USB, PCI) ? Что такое /dev/ttyS1 ? Покажите вывод "setserial -a /det/ttyS1" |
Автор: hente 21.3.2009, 07:24 | ||||||
на одноплатной ЭВМ (на физическом уровне)джемперами COM2 выставил на RS485 принцип работы то я понял а вот как программно работать хз. к стате если воспользоваться утилиткой cat, то ситация такая: при вводе
то на другом конце RS485 (под виндой) данные приходят без проблем все в норме если ввести
то на другом конце RS485 (под виндой) данные отсылая под Linux ничего не приходит... в документациях никак не могу найти переключение режима чтения записи
к стате под виндой я уже говорил использую Terminal прогу и там соединение идет через переходник USB->RS485 (+дрова там всяки) /dev/ttyS1 - это устройство |
Автор: hente 21.3.2009, 12:24 |
![]() Тут подкинули идею: отслеживать прерывания ну и читать определенные регистры... А вот как отловить эти прервания, бог его знает... Хотя всяко данная проблема решается очень легко а вот по какому пути идти.... ![]() |
Автор: xvr 23.3.2009, 17:31 | ||||
Марку этой 'одноплатной ЭВМ' - в студию!
![]() |
Автор: hente 24.3.2009, 06:31 | ||||
PCE-5120G2
terminal автоматом стоит на приеме...т.е. надо разобраться только с линуксом... К стате многомерными пробами и ошибками нашел такую чтуку как RTS (под линуксом) вроде данные начали отправляться и приниматься вот тока не полностью... ![]() |
Автор: xvr 24.3.2009, 09:12 | ||||||||||||||
Хм, действительно не описанно, как переключать направление
![]()
Второй вариант - переключение ногой в интерфейсе RS232 (RTS в вашем случае). Недостаток - надо ловить окончание передачи (физическое) байтов из RS232 и только потом переключаться на прием. Дело усложняется тем, что передаваемые данные буферизуются в железе (FIFO). Дело еще более усложняется тем, что у чипа RS232 нет прерывания по опустошению передающего регистра (IMHO) (есть только по готовности принять следующий байт для передачи, что не одно и тоже). Так что для отлова момента переключения RTS надо непрерывно читать регистр состояния передатчика ![]()
Кстати, последствия полудуплекса RS485 - одновременный прием и передача невозможны, только по очереди. |
Автор: hente 24.3.2009, 11:57 | ||
xvr - на конце у меня собственно не rs232 а переходник USB->RS485 (все эт под win) а что такое CRS? переключать то я научился а вот read все равно колом встает при отправке не зависимо в каком положении RTS cстоит не подскажете в чем дело? |
Автор: xvr 24.3.2009, 12:28 | ||||||||
Это не имеет значения - там такой же автосвитчер для переключения направления (ну может чуть поумнее и делать паузы после отправки ему не надо)
|
Автор: hente 25.3.2009, 08:16 | ||
PC в том то и дело передает осцилограф уже подключал...а вотREAD не читает не важно скока ему передаю байтов на чтение 1,2,3... из под Win запустил на постоянную отпраку... а под Linux'ом шляпа реад висит и ничего не читает |
Автор: xvr 25.3.2009, 08:34 | ||||
А там случайно hardware flow control не включен? |
Автор: hente 25.3.2009, 13:30 | ||
Что эт такое и с чем его едят? |
Автор: xvr 25.3.2009, 14:30 | ||||
Аппаратное управление потоком передачи с помощью сигналов RTS CTS DTR (и еще кто то - не помню ![]() |
Автор: hente 26.3.2009, 12:26 |
так ну я нашел переключение IXON/IXOFF вроде по док-ии эт оно ...но вот реад все равно не читает.... Пробую другой вариант функцией outsb() - вывести на порт работает нармально на др. конце прием в норме insb() - пытаюст считать данные считывает полный бред какойто.... select'oм пробовал отловить момент прихода данных все равно хрень какаято.... время ожидания кончается и все. |
Автор: hente 28.3.2009, 12:23 |
Люди добрые спустя кучу времени опять прошу помощи.... Научился отлавливать прерывания от клавиатуры(irq 1), теперь надо переделать под отлавливаний прерыванйи от UART тупая подстановка (irq 3) ни к чему не приводит может кто делал? По мимо номера прерывания соответственно меняю третий параметр в функции request_irq(ном прерывания, имя функции, флаг прерывания) при работе с клавиатурой использую SA_SHIRQ а при работе с уартом SA_INTERRUPT Может я еще что-то не делаю...посоветуйте ![]() А вообще идея в том чтобы по прерываниям считывать/записывать данные в COM порт |
Автор: Oligarch 7.4.2009, 15:26 |
Доброе время суток. Подскажите пожалуста! почему то при чтении из последовательного порта символ 0x0D (или просто "cr") принимается как 0x0A, причем порт настроен на неканонический ввод. И еще вопрос: как можно организовать задержки в Linux, что то типа delay()??? не нашел я там такой функции. Заранее спасибо) |
Автор: hente 8.4.2009, 06:31 |
sleep() -задержка в секундах unsleep() -в милисекундах |
Автор: Oligarch 8.4.2009, 14:43 |
помогите плиз. Недавно сел за Linux. Создаю файл new.cpp следующего содержания: //************************ #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <termios.h> int main(void) { int fd; fd=open("/dev/ttyS0",O_RDWR); return 1; } //************************ компилятор выдает следующее: linux-m28h:/work # gcc new.cpp -o new /tmp/ccGJsdKt.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0' collect2: ld returned 1 exit status При этом если закоментировать вызов open(), то всё компилится. может надо прикрепить какие нибудь библиотеки? openSUSE у меня) |
Автор: xvr 8.4.2009, 16:21 | ||
C++ файлы компилировать и собирать нужно с помощью g++ |
Автор: hente 9.4.2009, 05:13 |
g++ new.cpp -o new ибудет тебе счастье ![]() |
Автор: Oligarch 9.4.2009, 06:19 |
спасибо за помощь) |
Автор: hente 9.4.2009, 07:37 |
А как ты переключаешь режим приема/передачи....просто я так и не добился этого от драйвера....???может у тебя решение есть? |
Автор: hente 9.4.2009, 12:56 |
![]() ![]() ![]() щас код по умней напишу потом выложу может еще кому нибуть понадобится.... |
Автор: Oligarch 11.4.2009, 08:02 | ||
У меня стоит MOXA CP-132, она сама занимается переключением приема и передачи. Помогите пожалуста. Почему то при чтении из порта при помощи команды read(), читается не больше 14 символов, сколько бы я не указывал читать в последнем параметре read(). Вот код конфигурации порта и чтения из него:
|
Автор: xvr 11.4.2009, 09:24 | ||
На эти грабли уже наступали в соседней ветке (в другом разделе, правда). 14 байт - размер аппаратного FIFO у порта. Остальные байты просто еще не успели прийти. Читайте read'ом в цикле, пока не наберется сколько надо. Еще можно настроить timeout'ы приема символов (не знаю, где это настраивается в Linux, ищите) |
Автор: Oligarch 11.4.2009, 11:03 |
спасибо. |
Автор: Oligarch 11.4.2009, 11:28 |
v cikle eto ponyatno. Prosto mne ydobnee kogda potok, v kotorom budet vipolnyat'sya etot kod, budet gdat' priema vsego paketa, kotoryi ochen' dlinnui. A v to vremya poka on gdet, drygie potoki bydyt vipolnyat'sya. Ya ychitivay eto, potomy chto proga dolgna rabotat' na controllere ARM9 (200MHz), poetomy kipeshy za bistrodeistvie i proizvoditel'nos't. Ya ge vistavil time-out: termios_struct.c_cc[VMIN]=0; termios_struct.c_cc[VTIME]=1; eto oznachaet, chto read() budet otschitivat' 100ms dlya kagdogo vhodyashego simvola, i kak tol'ko dlya kakogo nibud' simvola time_out isteket, to read() vozvratit prochitannie simvoli. Eto tak ved'? moget vse taki kak to mogno bez cikla i bez vremennoi zadergki megdy zapis'y i chteniem oboitis'? |
Автор: xvr 11.4.2009, 20:25 | ||||
Нет
|
Автор: Oligarch 27.4.2009, 21:52 |
Как там дела с переключением приема/передачи RS-485 под линуксом? Не решил еще? Если решил, вышли код. у меня отладочная плата с микроконтроллером AT91SAM9260 (линукс вшит во флэш), её UASRT'ы могут работать в режиме RS-485. Переключение в этот режим происходит выставлением определенного бита в управляющем регистре порта. В этом режиме контроллер автоматически дёргает ногой RTS, которая запаяна на управляющий вход управления приемом/передачей схемы RS-485 интерфейса. И всё бы хорошо, но как из под линукса достучаться до этого управляющего регистра и выставить порт в режим RS-485. Либо можно как то программно дёргать этой ногой RST? опять же будет неизвестно все ли данные отосланы перед выставлением интерфейса на прием.... |
Автор: hente 30.4.2009, 10:54 |
Для начала чтобы из ком порта сделать RS485 необходимо выставить джампера на плате(в соответствии с документацией на плату) Далее 2 пути: 1) Программный, тогда тебе надо будет удостовериться что стоят драйвера(либо при необходимости поставить их), и используешь стандартные функции Read/write (я делал именно так) 2)Аппаратный тут либо ты используешь функцию ioctl либо явно через регистры выставляешь то что те надо ща поищу доку к регистрам ... |
Автор: demon051 20.12.2019, 12:51 | ||
для примера
|