ЗАО «ЗЭО»
Техническая поддержка пользователей => Тион-Про28, Орион28 => Тема начата: SU от 17 Апреля, 2013, 15:55:35
-
При попытке передаче из ttySP2 было установлено, что на выходном разъеме сигнал отсутствует.
Начал смотреть осциллографом и обнаружил, что на входе передатчика (конт. 4 микросхем DA10 и DA12) сигнал есть. Сигнал PORT2_RS485_OFF находится постоянно в высоком уровне, соответственно на входе разрешения передатчика (конт. 3) – низкий уровень, который запирает передатчик. Поэтому на выходе ничего не может быть.
Пошивка Linux – та, которая была при поставке. Из лога загрузки:
Linux version 2.6.35.3-571-gcca29a0 (danila@debian) (gcc version 4.4.4 (4.4.4_09
.06.2010) ) #1 Wed Aug 22 04:26:44 MSK 2012
Пробовал зашивать образы с сайта tion-pro28_linux_svn2127.zip и tion-pro28_linux_svn2203.zip. Результат – тот же.
Сроки сдачи системы подпирают. Пока аппаратно переключил этот порт в режим RS-232 и работаю через преобразователь RS-232 / RS-485. Но это годится только для отладки, перед поставкой надо сделать по-нормальному.
-
Проверьте осциллографом сигнал на ножке 2 микросхемы DD12. Должен меняться. А также, все ли в порядке с резистором R76.
-
На ножке 2 микросхемы DD12 - это сигнал PORT2_RS485_OFF, про который я написал, что
он постоянно в высоком уровне. Резистор R76 - исправный. Все это проверял на двух экземплярах
платы.
-
В образе от 2012/12/10 управление сигналом PORT2_RS485_OFF реализовано.
При выполнении команды "echo Hello > /dev/ttySP2" сигнал меняется.
Возможно у Вас аппаратная проблема, но на 2-х платах - маловероятно.
Это не последняя версия, обновите ее:
Linux version 2.6.35.3-571-gcca29a0 (danila@debian) (gcc version 4.4.4 (4.4.4_09.06.2010) ) #1 Wed Aug 22 04:26:44 MSK 2012
-
Зашил образ от 2012/12/10.
Ваш пример с команды с терминала работает, сигнал PORT2_RS485_OFF переключается,
сигнал проходит на выходной разъем.
Запустил свою программу, переключения нет. Работа с последовательным портом простейшая,
убрал все наcтройки termios остались две строчки:
fd2 = open ("/dev/ttySP2", O_RDWR | O_NOCTTY | O_NDELAY );
write (fd2, cmd, dwToWrite2);
На Тионе-Про2 все работало без проблем.
Завершаю свою программу, посылаю команду с терминала - сигнал переключается.
Пытаюсь разобраться в чем отличие, но пока ничего не получается.
-
Тоже начал разбираться с RS-485, работает как то странно. если посылать до 16 символов, то шлется какая фигня, если больше 16 тогда получаем следующее (первая колонка что посылаем, вторая что приходит):
0FEDCBA9876543210 876543210
10FEDCBA9876543210 9876543210
210FEDCBA9876543210 A9876543210
3210FEDCBA9876543210 BA9876543210
43210FEDCBA9876543210 CBA9876543210
543210FEDCBA9876543210 DCBA9876543210
6543210FEDCBA9876543210 EDCBA9876543210
76543210FEDCBA9876543210 FEDCBA9876543210
876543210FEDCBA9876543210 876543210
9876543210FEDCBA9876543210 9876543210
A9876543210FEDCBA9876543210 A9876543210
BA9876543210FEDCBA9876543210 BA9876543210
CBA9876543210FEDCBA9876543210 CBA9876543210
DCBA9876543210FEDCBA9876543210 DCBA9876543210
EDCBA9876543210FEDCBA9876543210 EDCBA9876543210
FEDCBA9876543210FEDCBA9876543210 FEDCBA9876543210
Посылаю просто через терминал например: echo CBA9876543210FEDCBA9876543210 > /dev/ttySP2
Так же при посылке до 16 символов получаю в терминале ошибку "mxs-auart mxs-auart.2: Unhandled status 520080"
Например для посылки A9876543210 получаю PNœ“SÓ&¦LL… в Hex: 50 4E 9C 93 53 13 D3 26 A6 4C 4C 85
Что я делаю не так?
-
Написал маленькую тестовую программку и начал экспериментировать.
Дошел до следующего. Сделал бесконечный цикл, в котором:
1. Открывается ttySP2 без флага O_NDELAY;
2. Выводится несколько байт (с ожиданием конца вывода);
3. Закрывается ttySP2.
В таком варианте переключение заработало, на разъеме - правильные данные.
Однако практической пользы от такого режима не вижу. Не понятно, как
принимать ответные данные с этого порта, да еще с учетом того, что присутствует
эхо от передаваемых данных.
-
Будем разбираться.
О результатах сообщим.
-
Добрый день!
Есть ли какие-нибудь сдвиги?
Уже в производство почти запустили, а тут вылезла это проблема...
-
Написал маленькую тестовую программку и начал экспериментировать.
Дошел до следующего. Сделал бесконечный цикл, в котором:
1. Открывается ttySP2 без флага O_NDELAY;
2. Выводится несколько байт (с ожиданием конца вывода);
3. Закрывается ttySP2.
В таком варианте переключение заработало, на разъеме - правильные данные.
Однако практической пользы от такого режима не вижу. Не понятно, как
принимать ответные данные с этого порта, да еще с учетом того, что присутствует
эхо от передаваемых данных.
Не совсем понятно зачем циклически открывать порт и закрывать его? это же не сокет.
Если у вас приложение однопоточное, то один раз открыли и в конце программы закрыли.
Сколько работаем нет проблем с 485 интерфейсом.
-
можно кусок кода, где выработаете с портом? открытие, чтения, запись.
Я столкнулся с проблемой описанной выше
echo "Hello" > /dev/ttySP2
работает, а из программы нет.
-
<=========== ОТКРЫТИЕ ПОРТА ======================>
port = ::open(sPort, O_RDWR | O_NOCTTY | O_NDELAY);
if(port == -1)
{
prn_error("невозможно открыть");
return 1;
}
.......
if(error==-1)
{
::close(port);
prn_error("невозможно изменить настройки ");
return1;
}
new_port_settings.c_cflag = baudr | CS8 | CLOCAL | CREAD;
new_port_settings.c_iflag = IGNPAR;
new_port_settings.c_oflag = 0;
new_port_settings.c_lflag = 0;
new_port_settings.c_cc[VMIN] = 0;
new_port_settings.c_cc[VTIME] = 0;
error = tcsetattr(port, TCSANOW, &new_port_settings);
if(error==-1)
{
close(port);
prn_error("невозможно применить параметры ");
return 1;
}
if(ioctl(port, TIOCMGET, &status) == -1)
{
perror("невозможно получить статус порта");
return 1;
}
......
if(ioctl(port, TIOCMSET, &status) == -1)
{
.........
return 1;
}
<======= чтение из порта ==========>
int n = ::read(port, buf, size);
<======= запись в порт ==========>
int = ::write(port, &bytes, size);
-
не работает.
Если просто сделать write и после этого завершить программу, то данные пошлются, а если
после write, программа продолжает работать, то ни чего не шлется.
-
не работает.
Если просто сделать write и после этого завершить программу, то данные пошлются, а если
после write, программа продолжает работать, то ни чего не шлется.
можно посмотреть на Ваш конечный код окрытия порта, приёма и отправки, надеюсь, что он не в бесконечном цикле?
И, кстати, у Вас правильно настроены флаги DTR, RTS?
-
https://gist.github.com/aborilov/5703954
а почему в бесконечном цикле не должно работать?
-
потому что при этом ты загружаешь процессор на 100% и ему уже не до общения с переферией. в каждом бесконечном цикле нужно ставить sleep хотябы на 5 миллисекунд.
-
sleep в секундах задается.
и у меня стоит 1 секунда, за это время все должно отправиться
-
пример, что я написал у вас работает?
-
Не работает.
-
Даже вот так не работает
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#define BAUDRATE B9600
#define DEVICE "/dev/ttySP2"
main(){
printf("hello");
int fd;
struct termios opt;
fd = open(DEVICE, O_RDWR | O_NOCTTY | O_NDELAY);
if ( fd < 0 ){
perror(DEVICE);
}
unsigned char data[200] = "Hellodkslnkfndkslakdjaskldjaskldjasasdasdasd";
opt.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
opt.c_iflag = IGNPAR;
opt.c_lflag = 0;
opt.c_oflag = 0;
opt.c_cc[VMIN] = 0; //Minimum bytes available
opt.c_cc[VTIME] = 0;
tcflush(fd, TCIFLUSH);
tcsetattr (fd, TCSANOW, &opt);
// while(1){
printf("Sending\n");
int sended = write(fd, &data, 20);
tcflush(fd, TCIOFLUSH);
sleep(5);
// }
}
программа завершается через 5 секунд.
Если убрать sleep, что бы программа завершалась сразу после записи в линию, то данные в линию уходят.
-
Приведенные примеры программы написаны правильно, должны работать.
Более того на Тионе-Про2 у меня аналогичные программы работали без проблем.
А на Тионе-28 это не работает, потому что драйвер LINUX для Тиона-28 написан некорректно.
Похоже, что при вызове WRITE данные переписываются во внутренний буфер драйвера, а
фактический вывод осуществляется только по команде закрытия файла (либо из текста программы,
либо по закрытии программы).
Функция SLEEP на вывод никак влиять не может, потому что драйвер работает по аппаратным прерываниям на высоком уровне приоритета. И чем в это время в фоновом режиме загружен процессор
- пользовательской программой или передал управление операционной системе, на его работу не влияет.
Разработчик системы Danila обещал разобраться, но пока еще не приступал к задаче.
-
Сделал некоторые изменения в драйвере, теперь могу управлять в ручную переключение-приемом передачей, но проблема осталась так, больше 16 байт не передает, обрезает пакет и все.
-
бью пакеты которые надо послать по 16 байт :)
так работает
-
Функция SLEEP на вывод никак влиять не может, потому что драйвер работает по аппаратным прерываниям на высоком уровне приоритета. И чем в это время в фоновом режиме загружен процессор
- пользовательской программой или передал управление операционной системе, на его работу не влияет.
это не совсем так: уберите sleep и поставте скорость 1200 бод в секунду, уберите функцию flush и посмотрите что в итоге получится.
процессор всего 1, буфер 485 порта тоже 1, плюс Ваша запущенная задача работает не в RT режиме..
-
Так всегда и делаю. Причем функцию open вызываю с ключом O_NDELAY,
чтобы управление сразу возвращалось программе для обслуживания ввода и
вывода на дисплей.
-
Проблемой занялся, на этой неделе постараюсь исправить.
-
Добавил новый образ, RS-485 должен работать нормально.
Вот пример, который у меня работает:
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#define BAUDRATE B9600
#define DEVICE "/dev/ttySP2"
#define M_SIZE 90
main(){
printf("Start\r\n");
int fd;
struct termios opt;
fd = open(DEVICE, O_RDWR | O_NOCTTY | O_NDELAY);
if ( fd < 0 ){
perror(DEVICE);
}
unsigned char data[100] = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
opt.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
opt.c_iflag = IGNPAR;
opt.c_lflag = 0;
opt.c_oflag = 0;
opt.c_cc[VMIN] = 0; //Minimum bytes available
opt.c_cc[VTIME] = 0;
tcflush(fd, TCIFLUSH);
tcsetattr (fd, TCSANOW, &opt);
while(1){
printf("Sending %d bytes\n", M_SIZE);
int sended = write(fd, &data, M_SIZE);
sleep(1);
}
}
-
Сделал некоторые изменения в драйвере, теперь могу управлять в ручную переключение-приемом передачей, но проблема осталась так, больше 16 байт не передает, обрезает пакет и все.
Уберите "tcflush(fd, TCIOFLUSH);" Этой командой Вы же очищаете выходную очередь. Или используйте с флагом TCIFLUSH.
В новом образе эхо отключено, можно не использовать эту команду.
-
Добавил новый образ, RS-485 должен работать нормально.
а можно патч для ядра, что конкретно в драйвере поменялось?
-
и в том варианте что у меня сейчас, я вижу эхо на линии
-
На линии? Осциллографом? Аппаратное эхо отключено, на линии не должно быть.
Патч добавил.
-
Попробовал новый патч.
Эхо нету, данные шлются, но попрежнему только не больше 16 байт.
-
tcflush(fd, TCIOFLUSH) убрали?
-
убрал, теперь все работает.
Большое спасибо.
-
для того чтобы заработала сеть пришлось убрать из последного патча измения сделанные в fec драйвере