Поделки итальянцев, available() и flush()
- Войдите на сайт для отправки комментариев
Ни когда не пользовался этими функциями, хотя наверное не правда. Не пользовался этими функциями в ардуино. Работая в другой среде разработки на голом C столкнулся с отсутствием таковых. Почитал про них и написал свои как понял. Теперь решил использовать их в ардуино. И тут началось..... available() вроде как работает, но как только попытался отсечь функцией flush() хвост буфера UART получил вывод полного содержимого, облом. Поковырявшись в интернете понял что эти функции уже давно являются граблями пользователей IDE Arduino, Изучая глубже их работу ппонял следующие, available() не ждет конца передачи последнего символа, а фиксирует конец приема очередного байта, т.е. на лицо побайтовая передача данных. Тогда и вторая функция становится обсолютно бесполезной. Вот такие мысли в слух. То что было написано самостоятельно работает корректнее. Принимает фрейм, а потом его обрабатывает, думаю при таком режиме работы экономиятся драгоценные микросекунды, которых иногда так не хватает итак не быстрому AVR.
ппонял следующие, available() не ждет конца передачи последнего символа, а фиксирует конец приема очередного байта, т.е. на лицо побайтовая передача данных
ээ... шта?
ок. а, сколько байт, по мнению ТС, занимает один символ?
подсказка для жрущих попкорн, ТС не читать:
Да, для людей привыкших с детства собирать все из кубиков, понять сложно. А перевод available = имеем в нвличии. Т.е данная функция должна по определению возвращать количество принятых байт. Причем такая конструкция при высоком быстродействии контроллера должна успевать контролировать количество принятых байт, сохранять их в буффере с учетом обработанных из тогоже буффера данных. Так что Клап, сплюнь попкорн. Эту функцию в том виде в котором она есть, в топку. Ну и flush туда же до кучи.
По вашему эта функция не возвращает колличество принятых байт? Сомневаюсь конечно, но вы учли что буфер всего на 64 байта? А flush ваще не по теме, она ждет передачи исходящих данных и к входящим никакого отношения не имеет.
Ничего не понял из первого поста ТС, прошу ваш исходник супер-available в студию. На чтение вот этот код никогда меня не подводил:
А Serial.flush(), в общем-то, ожидает окончания отправки исходящего буфера, и ко входящему никакого отношения не имеет.
Наверное, если два человека даже высказались одинаковыми словами независимо друг от друга, это что-то да означает :)))
Не вопрос, только он для C и ни кокого отношения к AVR не имеет.
Э-э, к AVR отношения не имеет, вижу, gpio, не имеет. Попробую ещё раз телепат моде он, вы написали свой обработчик usart для стороннего мк, потом решили для чего-то использовать атмегу/arduino ide, и ужаснулись тому факту, что функция available "является граблями", а функция flush абсолютно бесполезна, затем решили, что ваш код для другого мк работает круче, чем встроенный в ардуину, и в конце решили поведать об этом нам всем в разделе программирование? :)
Если вы внимательно читали описание функции на сайте производителя, то должны знать, что в средах старше 1.0.х функция flush() используется для ожидания конца передачи вместо очистки буфера принятых значений. А то что сделано работает не круче, а правильно исходя из логики названия функций.
Делалось это все для адаптации готового приложеия записи внешней flash, только вот все заработало кроме контроля суммы переданного байта, потому как в программе использовался один способ расчета, а в мк обсалютно друго и потому идея умерла, так как разработчик открестился от редактировани, но библиотека честно лежит на оффсайте.
Ура, вот теперь я познал дзен! Вы возмущены тем, что в среде ардуино функция flush() работает с исходящим, а не входящим буфером! Вот здесь https://github.com/arduino/Arduino/issues вы можете предложить итальянцам исправить эту вопиющую ситуацию, ну а мы пока тихо понегодуэм вместе с вами.
Да какое негодование, они понимают только судебные разбирательства, знаю из практи общения с производителями из европы, можно было просто создать новые функции и было бы всем счастье. Да и с первой функцией все плохо, Ни когого буффера она не создает, а просто фиксирует событие приема байта, после Serial.read() значение available() сбрасывается в ноль, проверено в режиме дебага.
Счастье будет тогда, когда хомяки перестанут использовать ардуину ИДЕ. От слов совсем и навсегда.
Нибудет. Как показано выше тупить можна и на чистом С. ТС приводит код "только он для C и ни кокого отношения к AVR не имеет." с невестькакой лабой и собственным
uint8_t available(
void
).
Это как демонстрацию нерабочего итальянскогоSerial
.available()
. Оригинально однако ))) Как показывает хрустальный шар, ТС завязался на некую либу, по ходу обнаружил в ней отсутствие available или чего подходящего, попробовалSerial
.available()
которая разумеется при приеме через другую либу вообще не пре делах о чем нам и поведал.По существу.
Serial
.available()
работает абсолютно корректно, возвращает кол-во байт в буфере приема реально принятых и доступных для получения программой методами Serial. Разумеется никакого буфера не создает, ибо и не должно. Можно извлеч не все данные сразу,Serial
.available()
это тоже отследит. Корректность Serial.flush() проверить сложней, но проблем замечено не было.Да, для людей привыкших с детства собирать все из кубиков, понять сложно. А перевод available = имеем в нвличии. Т.е данная функция должна по определению возвращать количество принятых байт. Причем такая конструкция при высоком быстродействии контроллера должна успевать контролировать количество принятых байт, сохранять их в буффере с учетом обработанных из тогоже буффера данных. Так что Клап, сплюнь попкорн. Эту функцию в том виде в котором она есть, в топку. Ну и flush туда же до кучи.
не - ты мне объясни, чем байт в твоём утверждении отличается от символа?
и, что у тебя за проблема с передачей символов? - у тебя символы длиннее одного байта?
Ничего не понял из первого поста ТС, прошу ваш исходник супер-available в студию. На чтение вот этот код никогда меня не подводил:
Позволите немного оффтопа?
Как в вашем коде проверить факт превышения лимита на длинну строки?
прошу разяснить тему на счет буфера т.к. из тутошнего описания
http://arduino.ru/Reference/Serial/Available
"Serial.available()
Функция получает количество байт(символов) доступных для чтения из последовательного интерфейса связи. Это те байты которые уже поступили и записаны в буфер последовательного порта. Буфер может хранить до 64 байт."
следует, что некий буфер уже имеется по умолчанию.
что вроде как противоречит
Ни когого буффера она не создает, а просто фиксирует событие приема байта, после Serial.read() значение available() сбрасывается в ноль, проверено в режиме дебага.
прошу разяснить тему на счет буфера т.к. из тутошнего описания
http://arduino.ru/Reference/Serial/Available
"Serial.available()
Функция получает количество байт(символов) доступных для чтения из последовательного интерфейса связи. Это те байты которые уже поступили и записаны в буфер последовательного порта. Буфер может хранить до 64 байт."
следует, что некий буфер уже имеется по умолчанию.
что вроде как противоречит
Ни когого буффера она не создает, а просто фиксирует событие приема байта, после Serial.read() значение available() сбрасывается в ноль, проверено в режиме дебага.
diger67 просто ошибается.
available() показывает, сколько байт есть в буфере. Просто микроконтроллер может выдергивать данные из буфера, гораздо быстрее, чем они туда будут поступать из порта. Поэтому у diger67
после Serial.read() значение available() сбрасывается в ноль, проверено в режиме дебага.
Если бы он подождал наполения буфера, или хотя бы сделал паузу между Serial.read() - никакого сброса небыло бы, просто было бы уменьшение значений, отдаваемых available()
плин. я утерял суть проблемы ТС...
плин. я утерял суть проблемы ТС...
Проблема в том, что с появлением Ардуино, никто не ценит, что он умеет работать на "чистом Си". Пардон - на "голом Си".
Проблема в том, что с появлением Ардуино, никто не ценит, что он умеет работать на "чистом Си". Пардон - на "голом Си".
ну, ок. а, available() на каком Си написан? - на чистом или грязном?
Проблема в том, что с появлением Ардуино, никто не ценит, что он умеет работать на "чистом Си". Пардон - на "голом Си".
ну, ок. а, available() на каком Си написан? - на чистом или грязном?
Согласен - тут есть какая-то интрига. ТС - уже как минимум третий человек на этом форуме, который противопоставляет Ардуино "чистому Си".
Как в вашем коде проверить факт превышения лимита на длину строки?
разумеется никак, как и многое другое :)
Да нет ни кокого противопоставления. Думаю ни кто не будет спорить что программа написанная на asm будет работать быстрее и оптимальнее. На C++ реализуется объектно ориентированное програмирование. Т.е. можно создавать обект и при необходимости передавать его свойства дочерним объектам. но вот вопрос, какую цену мы платим за эту няшку. Относительная простота построение програмы, а объем кода и его быстродействие оставляет желать лучшего. По поводу available() и всего связанного с ней, функция действительно не контролирует состояние буфера и при привышении 64 байт начнет благополучно затирать все что лежит за верхним пределом выделенной под буффер области памяти. Хорошо если там просто данные, а если стек переходов, привет пишите писма программа не рабочая и искать ошибку будите до нового пришествия, удачного дня програмулькины....
По поводу available() и всего связанного с ней, функция действительно не контролирует состояние буфера и при привышении 64 байт начнет благополучно затирать все что лежит за верхним пределом выделенной под буффер области памяти. Хорошо если там просто данные, а если стек переходов, привет пишите писма программа не рабочая и искать ошибку будите до нового пришествия, удачного дня програмулькины....
ок. а, как всё происходит в правильной available(), которая контроллирует состояние буфера?
пример: буфер забит в ноль и, что? available() должна возвратить "караул!, я сейчас взорвусь нафиг!", или что будет делать, что бы не потерялись данные?
*почему кто-то будет долго искать ошибку, если очевидно, что данные теряются во время передачи по сериалу?
начнет благополучно затирать все что лежит за верхним пределом выделенной под буффер области памяти.
там кольцевой буфер, затирать начнет с нуля сам буфер а не за верним пределом.
начнет благополучно затирать все что лежит за верхним пределом выделенной под буффер области памяти.
там кольцевой буфер, затирать начнет с нуля сам буфер а не за верним пределом.
да, ладно! - а, как же области памяти? это же прекрасно - придумывать несуществующие сущности и рассказывать, как они плохо работают.
Да нет ни кокого противопоставления. Думаю ни кто не будет спорить что программа написанная на asm будет работать быстрее и оптимальнее.
Я буду спорить. Средний програмер как правило напишет на асме хуже чем онже на С. И чем крупней проект, тем ярче будет заметно. На асме есть возможность написать лучше, но это сложней и дольше будет.
Я буду спорить. Средний програмер как правило напишет на асме хуже чем онже на С. И чем крупней проект, тем ярче будет заметно. На асме есть возможность написать лучше, но это сложней и дольше будет.
на чистом Си? - это важно.
По поводу available() и всего связанного с ней,
Вы банально ошибаетесь. И вместо того, чтобы выдумывать ересь - просто разберитесь. А то я начинаю теряться в ваших утверждениях.
Думаю ни кто не будет спорить что программа написанная на asm будет работать быстрее и оптимальнее.
Я буду спорить.
Условия определены? Речь о моргалке светодиодом или текстовом редакторе, уровня Word?
или текстовом редакторе, уровня Word?
я хочу ворд на асме.
Gippopotam, а вы что имеете какое то отношение к написанию Word? А на asm можно написать что угодно, главное понимать что делаешь и не повторять как попугай чужие ошибки.
Да нет ни кокого противопоставления. Думаю ни кто не будет спорить что программа написанная на asm будет работать быстрее и оптимальнее.
Я буду спорить. Средний програмер как правило напишет на асме хуже чем онже на С. И чем крупней проект, тем ярче будет заметно. На асме есть возможность написать лучше, но это сложней и дольше будет.
Это если программер нубас и не знает архитектуры процессора, при этом еще и не понимает логику перефирийного устройства. Тупо берет чужой гавнокод и с удовольствием размазывает по всему мозгу.
начнет благополучно затирать все что лежит за верхним пределом выделенной под буффер области памяти.
там кольцевой буфер, затирать начнет с нуля сам буфер а не за верним пределом.
Это кто вам такую глупость сказал?
начнет благополучно затирать все что лежит за верхним пределом выделенной под буффер области памяти.
там кольцевой буфер, затирать начнет с нуля сам буфер а не за верним пределом.
Это кто вам такую глупость сказал?
да?! кто это сказал, встань!
*diger67, расскажи нам про верхние пределы области памяти.
Gippopotam, а вы что имеете какое то отношение к написанию Word? А на asm можно написать что угодно, главное понимать что делаешь и не повторять как попугай чужие ошибки.
Вы шутите?
Если мне дадут миллион денег и скажут - "Напиши на ассемблере аналог Ворда", я сначала напишу на ассемблере кучу макросов, потом, используяэти эти макросы напису себе компилятор Си, потом на Си попытаюсь написать Ворд.
Если мне дадут миллион денег и скажут - "Напиши на ассемблере аналог Ворда", я сначала напишу на ассемблере кучу макросов, потом, используяэти эти макросы напису себе компилятор Си, потом на Си попытаюсь написать Ворд.
читер.
Это кто вам такую глупость сказал?
Находите сишный файл библиотеки и открываете. Если для вас это такая сложность, то нахер спорить? Вы не видите, что в этой теме вы выглядите лохом, ни черта не понимающем ни в МК, ни в программировании? Я, если честно, то уже бы слился с позором.
Это кто вам такую глупость сказал?
Находите сишный файл библиотеки и открываете. Если для вас это такая сложность, то нахер спорить? Вы не видите, что в этой теме вы выглядите лохом, ни черта не понимающем ни в МК, ни в программировании? Я, если честно, то уже бы слился с позором.
стоять!
лохом здесь я выгляжу, потому как взял и проверил, что происходит с буфером забитым в ноль при попытке записать что-то ещё.
ответ: с буфером, забитым в ноль не происходит ничего - ни затирания чего-то там в каких-то пределах какой-то памяти, ни карусели с кольцом перезаписи.
и это правильно.
стоять!
лохом здесь я выгляжу, потому как взял и проверил, что происходит с буфером забитым в ноль при попытке записать что-то ещё.
ответ: с буфером, забитым в ноль не происходит ничего - ни затирания чего-то там в каких-то пределах какой-то памяти, ни карусели с кольцом перезаписи.
и это правильно.
Что и требовалось доказать, принимая байт следующий за 63 он пишет его в следующую ячейку памяти контроллера, и если по этому адресу находится область размещения стэка то произойдет то. что я описал выше, програма начнет глючить или ребутиться или виснуть. Клап, если бы вы могли видеть как продолжается запись в ОЗУ mega, то пронаблюдали бы как данные продолжают записываться.
Это кто вам такую глупость сказал?
Находите сишный файл библиотеки и открываете. Если для вас это такая сложность, то нахер спорить? Вы не видите, что в этой теме вы выглядите лохом, ни черта не понимающем ни в МК, ни в программировании? Я, если честно, то уже бы слился с позором.
Так в чем дело, сливайся.... :-))
Что и требовалось доказать, принимая байт следующий за 63 он пишет его в следующую ячейку памяти контроллера, и если по этому адресу находится область размещения стэка то произойдет то. что я описал выше, програма начнет глючить или ребутиться или виснуть.
давай это смоделируем в коде - так понимаю, что если сбросить в буфер пару мегабайт, то случится ужасное?
или у нас обоих недостаточно квалификации, что бы повредить область размещения стэка тупой стрельбой в буфер сериала?
Так в чем дело, сливайся.... :-))
стоять! - только после повреждения чего-то там такой матери области памяти.
Както находил библтотеку содержащую available(), сейчас ни как. Но если исходить из описания на сайте. то эта функция возврвщает только количество принятых байт, имеет значение int. Значит два байта, максимальное значение 0xFFFF, а это 65535. Вот столько, если не контролировать количество принятых байт она будет толкать в буфе, т.е. в память. И если переменных много, и буфер будет находится на границе памяти содержащей переменные и памяти выделенной под стэк, то будет так как я описал. Все это обусловлено тем что память данных и стэк размещены физически в одной памяти.
имеет значение int. Значит два байта, максимальное значение 0xFFFF, а это 65535.
Садитесь, два. Тип - знаковый, дальше рассказывать?
Вот столько, если не контролировать количество принятых байт она будет толкать в буфе, т.е. в память. И если переменных много, и буфер будет находится на границе памяти содержащей переменные и памяти выделенной под стэк, то будет так как я описал. Все это обусловлено тем что память данных и стэк размещены физически в одной памяти.
ты зубы не заговаривай - как программно реализовать, описываемый тобой ужос с переходом границы памяти и бесславной гибелью за пределами.
Даже если и половина, то значение лежит в диапазоне -32768 до 32767 - это размер памяти mega328.
Даже если и половина, то значение лежит в диапазоне -32768 до 32767 - это размер памяти mega328.
давай код - будем переполнять области памяти
Вот столько, если не контролировать количество принятых байт она будет толкать в буфе, т.е. в память. И если переменных много, и буфер будет находится на границе памяти содержащей переменные и памяти выделенной под стэк, то будет так как я описал. Все это обусловлено тем что память данных и стэк размещены физически в одной памяти.
ты зубы не заговаривай - как программно реализовать, описываемый тобой ужос с переходом границы памяти и бесславной гибелью за пределами.
да просто как два пальца
Код писать ненадо, создай макрос для любой терминалки, не ардуиновской и отправь по UART в контроллер.
Что и требовалось доказать, принимая байт следующий за 63 он пишет его в следующую ячейку памяти контроллера, и если по этому адресу находится область размещения стэка то произойдет то. что я описал выше
Кто пишет? Зачем именно туда, на каком основании?
Что за бред?
Блин, да о чём вы... hardwareSerial.cpp
возвращаемое никогда не превысит SERIAL_RX_BUF_SIZE, то есть 64 для uno