Прошу помочь решить вопрос, уже дважды писал решение этого вопроса, оба раза убивал несколько часов чтобы написать рабочий код, который мог бы достаточно быстро отрабатывать, но к сожалению каждый раз случайно убивал исходники и вот опять хочу вернуться к этому вопросу, но убивать несколько часов очень не хочется, может кто сталкивался с этим вопросом, гугление дает лишь примерные решения, каждое из которых либо не работает, либо глючит жутко при больших объемах либо очень медленно работает. Задача следующая, нужно передать с контролем целостности данных массив 32x4 элементов типа byte, при чем это нужно делать минимум 10 раз в секунду или чаще, при этому нужно учитывать что микроконтроллер будет занят обработкой полученных данных пересылая весь этот массив по SPI. Выглядит это не очень реалистично, т.к. объем работы жалкой ардуинке большой, но как я говорил раньше я уже 2 раза умудрялся заставить ее выполнять то что описал и она на ура справлялась с задачей, но вспомнить как я это сделал не получается:( А повторные попытки написать заканчиваются часами работы и глюков:(
И в чем беда? Если по UART передача идет, просто со стороны компьютера делаем write, на дурине принимаем, вычисляем CRC и отправляем обратно, на компьютере сравниваем CRC и выполняем определенные действия.
Это - от силы десяток строк кода. Ну, на "сидиезе", возможно, побольше.
Кстати, лучше на нормальном С делать подобные низкоуровневые вещи: чем выше абстракция, тем меньше шансов, что все будет работать как надо. Особенно в случае "сидиеза", который как был мелкомягкой поделкой, непонятно зачем придуманной, так ею и остается!
Проблема тут не в C#, он отправляет нормально и может отправлять в десятки раз быстрее, проблема это поймать понять и прожевать на стороне дуйни, простой Serial.Read тут не поможет по многим причинам, на счет нормального C тут вопрос спорный, если на относительно высокоуровневом wires все глючит, то написать подобное на низкоуровневом мне не светит:) Не привык я к низким абстракциям после C#, который все контролирует сам. То что код с десяток строк на 100% согласен, проблема в том что я не могу вспомнить каких именно строк:) Но их и правда было мало)
Neuroware: А что там может быть проблематичным? Пишем в кольцевой буфер, в основном цикле постоянно проверяем на наличие данных, если данные есть, обрабатываем. Везде так работает. И никаких проблем.
Ну и, понятное дело, писать нужно хоть и не на ассемблере, но хотя бы на сях, а не мышкой в каком-то ынтырфейсе тыкать. Мышкой вы ничего путного не натыкаете.
тяжело, наверное, вспомнить то, что не знал ;)
Eddy_Em: вот тут в фразе "кольцевой буфер" проблема:) Т.к. соединение с дуинкой идет по 2 проводам, соединение которых не на 100 % идеальное и часть данных может посередине потеряться, и получается ждали 3 байт из массива а на самом деле 15 байт пропустили и читаем уже 16й, а когда дошли до N ждем байт, которые не придут:) И тому подобных ситуаций много, поэтому нормально код не так просто в данном случае сделать. +SPI, он тоже любит "отвлекать" от чтения данных, в итоге потеря и опять не ясно как такую ситуацию обрабатывать. В том то и проблема что 2 раза уже делал:) Оба раза часами сидел мудрил, потом забивал на это дело по той или иной причине, когда вспоминал не мог найти исходники, вот и сейчас дуйня работает со старым кодом, а прошить ее, чтобы подправить код нечем:)
Eddy_Em: по поводу интерфейса и мышки, wiring пишется на C\C++ ("The Wiring IDE comes with a C/C++ library called "Wiring") Фактически это C\С++ с плюшками вроде заготовленных функций для работы с периферией, так что оно не особо отличается от низкоуровневого программирования:) Потому и часами мучился чтобы заставить это работать:)
Neuroware: C++ для микроконтроллеров - это дичайшая дикость! Там вообще обычно 0 оптимизации!
Скажем, если STM32 программировать на С, но с использованием SPL, у вас будут вылезать "непонятные баги", а также кое-какие вещи (скажем, оптимизированное скоростное выполнение задач, работа с шустрыми интерфейсами, да и просто оптимизация по размеру кода - не у всех на борту 10МБ флеша) вы выполнить вообще не сможете!
Neuroware: насчет интерфейсов ничего мудрить не надо. Все там элементарно: если буфер переполнился, выкидываем нафиг все содержимое буфера и не паримся! Все равно битые пакеты нам не нужны.
Но если правильно выбран микроконтроллер, то ничего там переполняться не будет!
Прием-передачу по SPI вообще проще реализовать через DMA, и ни на что отвлекаться не надо будет!
Да и в принципе, везде, где только это возможно, следует использовать DMA.
Eddy_Em: Тут вопрос не в том что переполнился, а в том как определить что данные которые уже должны были прийти не пришли, тупо сделать таймаут ожидания не подходит, т.к. нельзя точно определить сколько именно данных придет, потому как та самая матрица полностью не пересылается, пересылаются только изменения в ней. Как тут поможет прямой доступ к памяти если с одной стороны у меня только uart с другой SPI
Neuroware: элементарно сделать: обрабатывать только строками. Т.е. все данные до символа \n (либо до символа \0) накапливаются в буфере, а как только получаем этот символ, устанавливаем флаг готовности.
Ну и по таймауту можно буфер опустошать, если есть желание. Только я не понимаю, как может что-то "потеряться", если прием-передача сделаны правильно, а не через одно место.
Можно, кстати, и линейным буфером обойтись: заполнять буфер посредством DMA, а в прерывании DMA проверять, что за байт пришел. И если нужный, то генерировать флаг и отрубать DMA (чтобы не забить буфер, пока он не обработан).
А можно и действительно таймаутами. У меня, например, буфер приема обрабатывается посимвольно, но конечными автоматами. И если нужно ждать какие-то данные, фиксируется текущее время, а в цикле периодически проверяется, сколько уже прошло. Если больше, скажем, 10с, то считается, что данные "куда-то исчезли" (куда?) и операция обрывается - конечный автомат переводится в изначальное состояние.
Eddy_Em: Про прерывания при приеме данных я как то забыл, действительно я раньше их использовал, попробую еще поэкспериментировать, на этот раз выложу исходники в сеть чтобы не искать потом:)