rf_pcb
Jun 30 2015, 12:05
Прошу дать совет и прокоментировать мои рассуждения.
Пишу ПО по для приема данных от МК на скорости 115200 по интерфейсу RS-232.
В качестве простейшего теста ставлю на ПК перемычку между Rx и Tx.
1 байт, 1 стоп, без четности и всего остального.
Если я правильно понимаю я должен увидеть скорость приема близкую к 7200 байт/с (115200/8/2).
Пишу ПО в Билдере, использую стандартный API функции, но скорость вижу от 200 до 400 байт /с.
Пробовал с выводом на график и с записью в фаил и просто из памяти в фаил, но больше чем 400 байт /с не получил.
Заметил особенность что на XP и 7ке разные скорости.
Подскажиет как быть?
Получу я свои 7200? ну хоть 5000 байт/с?
Цитата(rf_pcb @ Jun 30 2015, 18:05)
Если я правильно понимаю я должен увидеть скорость приема близкую к 7200 байт/с (115200/8/2).
Нет.
Если правильно напишете, то получите скорость = 115200/10 Б/с
rf_pcb
Jun 30 2015, 12:24
115200/9/2=6400
Скорость приема. Скорее такой параметр мне нужен. Поэтому делю на 2.
Подскажите как правильно написать?
Цитата(rf_pcb @ Jun 30 2015, 16:05)
Прошу дать совет
Получу я свои 7200? ну хоть 5000 байт/с?
>>я должен увидеть скорость приема близкую к 7200 байт/с (115200/8/2).
Неправда. 115200/10=11,52 килобайт\сек. Это в идеале. Десять битов на посланный байт.
>>Пишу ПО в Билдере, использую стандартный API функции
Прочтите мой ответ "по буквам". А затем "слитно". Как быстрее? А почему? Правильно выбирайте функции.
Непременно получите. Удачи.
rf_pcb
Jun 30 2015, 17:42
Подскажите пожалуйста какие функции Вы используете? Может есть пример?
rf_pcb
Jun 30 2015, 20:23
В программе использую поток - выставляю максимальный приоритет (в данном случае получаю приоритет - 15).
В XP получаю скорость данных в 1 сек. около 800 циклов обращений (1 цикл = 1 символ передачи и 1 символ приёма).
В W7 и в W8 циклов меньше в разы.
Начинаю отключать процессы в виндах - количество циклов возрастает, но не значительно...
Кроме того, в настройках таймаутах порта при потоке ставлю 0 для макс. скорости.
Возможно, что проблема в виндах. Какие процессы отключить, чтобы добиться требуемой теоретической скорости?
Сергей Борщ
Jul 1 2015, 05:54
Отсылайте сразу килограмм символов, после чего принимайте этот килограмм обратно. Увеличение скорости затмит солнце.
kolobok0
Jul 1 2015, 06:25
Цитата(rf_pcb @ Jun 30 2015, 23:23)
...(1 цикл = 1 символ передачи и 1 символ приёма).В W7 и в W8 циклов меньше в разы....
Вы как-то быстро принимаете!!! Надо нододрыгом, софтверно и по-битно
Но если серьёзно - Вам уже основные вектора сказали -
отдавать работу по приёму на нижний уровень. Чем больше - тем лучше. Если говорить применительно к форточкам - Вы забываете такие вещи как
переключение потоков и межпроцессную передачу данных и управления. Ведь порты обслуживают драйвера - а это не пользовательское кольцо
привилегий. Вот Вам и накладные расходы. Если Вы посимвольно - то Вы как минимум всё суммируете по одному разу, а это тысячи и тысячи тактов.
Как принимать пачки - тут либо по времени резать(тайминг ожидания), либо строго длину пачки ожидать(но необходимо обязательно
предусмотреть самовыравнивание), либо опираться на управляющие доп. сигналы.
где-то так
Прошу меня услышать.
Я спросил, как мне передавая и принимая один байт, добиться скорости 115200 кб/с.
Для снятия всех вопросов с железом я установил перемычку на COM порт. Так можно? Можно.
Значит раз есть такая скорость, должны быть способы ее достижения.
Вопрос и звучит, как мн её добитьсься.
В решаемой задаче побайтный прием и передача. От этого и отталкиваюсь. Служебыне сигналы не использую.
QUOTE (rf_pcb @ Jul 1 2015, 10:23)
В решаемой задаче побайтный прием и передача.
Меняйте условия задачи. Из приложения, да еще и на билдере, побайтно, да еще и через USB-COM (угадал?) добится 115200 нереально.
Так-что бросайте фантазии о такой скорости - собирайте пакеты ( по любому задержки получаете при проходе через операционку, API и драйвера ) и передавайте.
В таком случае ограничение 800 байт в секунду станет ограничением 800 пакетов в секунду и практически перестанет влиять.
может и угадали))
Сейчас я тестирую с перемычкой на com порту. Результат 200-400 байт /с. Вы считаете это нормально?
В моем представлении - есть интерфейс - есть заявленная скорость. Значит должны быть способы реализации.
Откуда это информация про пакеты? про задержки в операционке?! Тактовая частота процессора 3 ГГц!
Цитата(rf_pcb @ Jul 1 2015, 17:30)
Откуда это информация про пакеты? про задержки в операционке?! Тактовая частота процессора 3 ГГц!
... поциент безнадёжен. в морг
soldat_shveyk
Jul 1 2015, 19:08
Уважаемый rf_pcb, Вы попробуйте проделать один простой эксперимент: подключите осциллограф на сигнал порта, по которому бегут отправляемые вами данные. Увидите много чего интересного.
Вы наверное, предполагаете, что порт работающий на скорости 115200 будет отправлять 10- битные комбинации вплотную одна к другой, без пауз между ними? Придется разочароваться- между отправляемыми вами байтами будет пауза намного превышающая время передачи одного байта в формате 8N1. Из-за нее вы и не получаете желаемой скорости. После этого можно подумать, откуда берутся эти задержки и как влияет частота пироцессора на скорость передачи по com-порту. Правильный ответ - никак не влияет.
Возможно, что время на открыть и закрыть порт уходит в разы больше чем на передачу байта.
Что делать вам уже сказали : открыть порт, передать килограмм байт, закрыть порт.
QUOTE (jcxz @ Jul 1 2015, 19:41)
... поциент безнадёжен. в морг
Ну не факт. Просто первое столкновение паскалевского-виндозного программиста с реальным миром железа о котором он до сих пор знал только про гигагерцы процессора. Постепенно, при желании, сможет осознать, что такое операционная система, что такое операционная система реального времени и почему WIN ей не является, что такое шедулер и как он задачи переключает, что его супер-пупер программа только одна из задач запускаемая периодически, что потом еще в системе куча кода, который распределяет доступ к аппаратным ресурсам типа того-же USB, что USB это ни разу ни байтовый интерфейс, что потом в конце есть еще драйвера. Хотя про драйвера он явно слышал, хотя явно только в контексте типа "скачать свежие"
.
Цитата(rf_pcb @ Jul 1 2015, 14:30)
может и угадали))
Сейчас я тестирую с перемычкой на com порту. Результат 200-400 байт /с. Вы считаете это нормально?
В моем представлении - есть интерфейс - есть заявленная скорость. Значит должны быть способы реализации.
Откуда это информация про пакеты? про задержки в операционке?! Тактовая частота процессора 3 ГГц!
Скорость 115200 бит в сек., показывает что время передачи одного бита будет равно 1/115200 = 8,7 мкс и только.
Чтобы передать все 115200 бит (или 11520 байт 8N1) за одну секунду нужно чтобы между стоп и старт битами каждого передаваемого байте не было вообще промежутков.
Для компьютера это не реально, абсолютно.
Даже если сформировать массив из 11520 байт и одной посылкой отправить с СОМ-порт, то все равно между передаваемыми байтами будут некоторые временные интервалы.
редактор
Jul 3 2015, 06:43
Цитата
Даже если сформировать массив из 11520 байт и одной посылкой отправить с СОМ-порт, то все равно между передаваемыми байтами будут некоторые временные интервалы.
В зависимости от железа может составлять от 1 до 4-х битовых интервалов, без учета прочих временных задержек.
Цитата(Abrams @ Jul 3 2015, 12:38)
Даже если сформировать массив из 11520 байт и одной посылкой отправить с СОМ-порт, то все равно между передаваемыми байтами будут некоторые временные интервалы.
Ню-ню... с чего бы это? Сказки рассказываете.
Интересно почему это у меня тогда получается между моим виндовым приложением и устройством получать 11520 б/сек?
Осциллограф развеет Ваши заблуждения.
Цитата(редактор @ Jul 3 2015, 12:43)
В зависимости от железа может составлять от 1 до 4-х битовых интервалов, без учета прочих временных задержек.
А ещё - в зависимости от фаз луны. А скорее - кривости рук кодера.
Жаль что никто не может внятно ответить кто виноват и как быть.
Какая же все таки скорость возможна при описанных условиях? 400 байт/с это же явно очень мало.
QUOTE (rf_pcb @ Jul 5 2015, 16:56)
Жаль что никто не может внятно ответить...
Вообще-то, на самом деле, это "кто-то" совершенно не хочет НИЧЕГО понимать из более чем внятных объяснений и рекомендаций
Zltio, ну вот вы скажите, сколько реально получить скорость при описанной ситуации?
Ruslan1
Jul 5 2015, 15:06
Цитата(rf_pcb @ Jul 5 2015, 17:27)
Zltio, ну вот вы скажите, сколько реально получить скорость при описанной ситуации?
Неизвестны условия работы, так что неизвестен результат.
Если пользоваться на незагруженной машине и компилировать с помощью граммотно написанных примочек (напроимер, для C++Билдера встроенные либы не годятся, нужно внешние подключать) - то
при передаче пакета увидете 115200. Да и то, все может упереться в размер аппаратного буфера порта.
При передаче отдельных байт- скорее всего, увиденные Вами 200-400 байт в секунду и будут пределом, зависит от сотни причин.
Ситуация понятна.
Изначально я ориентировался на опубликованные скорости, считая, что могу получить через порт требуемое количество ОБРАЩЕНИЙ (запись-чтение) за секунду с помощью программы, скомпилированной в Builder C++. Задача именно в этом и состоит - получить максимально возможное количество ОБРАЩЕНИЙ за секунду через порт посредством программных средств верхнего уровня.
Понятно, что драйвера и система Windows съели ресурс времени, потому я получаю с помощью своей программы совершенно смешное количество обращений через порт.
Я не такой специалист по железу, как некоторые местные гуру-пупки, программирую в Builder, потому не знаю многих тонкостей железа.
Ясно одно - реально расчёт количества ОБРАЩЕНИЙ за секунду через порт нельзя вести по стандартной формуле, которая дана в популярной литературе.
И для достижения заявленных характеристик порта для программы из Builder требуется "чистый", не загруженный Windows, и ещё чёрт знает чего...
Интересно, а в Линуксе такая же песня, как и в Windows, по моей задаче?
Цитата(Ruslan1 @ Jul 5 2015, 21:06)
передаче пакета[/b] увидете 115200. Да и то, все может упереться в размер аппаратного буфера порта.
Никуда не упрётся. Поднимаете хоть до 921600 бод - при
грамотной работе через WinAPI без всяких левых библиотек запросто получается скорость 92160 б/сек.
Обмен с функциями WinAPI конечно в отдельном треде (даже - 3-х отдельных тредах: отдельный для RX, для TX и для обработки событий порта WaitCommEvent()), а не в main-треде приложения.
Цитата(rf_pcb @ Jul 6 2015, 00:30)
Я не такой специалист по железу, как некоторые местные гуру-пупки, программирую в Builder, потому не знаю многих тонкостей железа.
Вы
неспециалист не по железу, а
неспециалист в программировании под винду.
Тут уже раз сто популярно разжевали.
Цитата(rf_pcb @ Jul 6 2015, 00:30)
Интересно, а в Линуксе такая же песня, как и в Windows, по моей задаче?
И в линухе и где угодно у Вас будут те же самые проблемы
редактор
Jul 6 2015, 08:01
Цитата
И в линухе и где угодно у Вас будут те же самые проблемы
В DOS возможно их не будет, если через прерывание и FIFO работать.
Цитата(jcxz @ Jul 6 2015, 09:07)
Вы неспециалист не по железу, а неспециалист в программировании под винду.
Тут уже раз сто популярно разжевали.
Что посоветуете, как специалисты, почитать из книг по виндам относительно моей задачи?
редактор
Jul 7 2015, 06:19
Цитата
Задача именно в этом и состоит - получить максимально возможное количество ОБРАЩЕНИЙ за секунду
Почитайте про мультимедиа таймеры - разрешение до 1 мс обеспечивают. Если этого мало - Thread и PerformanceCounter может быть выжмут больше
Цитата(rf_pcb @ Jul 6 2015, 23:38)
Что посоветуете, как специалисты, почитать из книг по виндам относительно моей задачи?
Вы своей конечной задачи так и не описали. Судя по всему, она не состоит в передаче данных, т.к. про то, что нужно сделать для нормальной передачи и приема вплоть до 900 кбит/с, вам уже рассказали . Для какой задачи нужно считать число обращений к порту за секунду? Просто по максимуму загрузить проц? Просто учебная задача без внятного смысла?
mantech
Aug 16 2015, 16:15
Цитата(rf_pcb @ Jul 6 2015, 16:38)
Что посоветуете, как специалисты, почитать из книг по виндам относительно моей задачи?
Тут уже и намекали и впрямую советовали обратить внимание что пишите
под виндой, а драйверы винды созданы с учетом пакетной работы устройств ввода-вывода, к коим относится и ком-порт, вы же пытаетесь размер пакета ужать до 1 символа, соотв. крайне нерационально используете данные вам методы. Если так уж прижало обмениваться по 1 байту, что считаю полным бредом, пишите свой драйвер под DDK или под досом, тогда получите прямой доступ к УАРТу и получите свои заветные скорости, даже на 1 байте...
Данный вопрос так же не актуален при программировании на микроконтроллерах...
Дмитрий_Б
Nov 22 2016, 17:05
Цитата(jcxz @ Jul 6 2015, 09:07)
Обмен с функциями WinAPI конечно в отдельном треде (даже - 3-х отдельных тредах: отдельный для RX, для TX и для обработки событий порта WaitCommEvent()), а не в main-треде приложения.
Интересно, почему простой синхронный обмен в потоке основной программы не годится?
Если нет необходимости выполнять какие-либо операции в процессе ожидания получения данных, то какой смысл создавать новый поток? Почему просто не подождать, пока ReadFile не вернет управление основной программе?
zltigo
Nov 22 2016, 17:25
QUOTE (Дмитрий_Б @ Nov 22 2016, 19:05)
Почему просто не подождать, пока ReadFile не вернет управление основной программе?
Если у Вас одна единственная программа во всем компьютере, то можете и ждать
и не пущать никого пока не отберут время силой. Ну а по хорошему надо отдавать ненужное время добровольно.
Дмитрий_Б
Nov 22 2016, 20:19
Цитата(zltigo @ Nov 22 2016, 21:25)
Если у Вас одна единственная программа во всем компьютере, то можете и ждать
и не пущать никого пока не отберут время силой. Ну а по хорошему надо отдавать ненужное время добровольно.
Если верить Microsoft, то это как раз не так. ReadFile в не-overlapped (синхронном) режиме приостанавливает вызвавший ее поток на время получения данных. Во время ожидания другие потоки получают возможность работать.
zltigo
Nov 23 2016, 09:14
QUOTE (Дмитрий_Б @ Nov 22 2016, 22:19)
Если верить Microsoft, то это как раз не так. ReadFile в не-overlapped (синхронном) режиме приостанавливает вызвавший ее поток на время получения данных. Во время ожидания другие потоки получают возможность работать.
Вы же как раз не хотите иметь другие потоки в задаче.
Дмитрий_Б
Nov 23 2016, 15:31
Цитата(zltigo @ Nov 23 2016, 13:14)
Вы же как раз не хотите иметь другие потоки в задаче.
Не совсем так. Мне интересно обоснование идеи запускать чтение в отдельном потоке. Выше говорилось, что это "конечно" нужно делать.
Дмитрий_Б
Nov 25 2016, 15:30
Могу только подтвердить, что чтение в отдельном потоке позволяет надежно принимать быстрый поток данных в большом объеме.
Почему нельзя достичь того же в одном потоке - вопрос открыт.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.