Чип для протокола обмена чипами по SPI

Я пытаюсь создать эффективный протокол связи между микроконтроллером с одной стороны и ARM-процессором на многоядерном чипе TI с другой стороны через SPI.

Требования для необходимого протокола:

1 - Многосеансовый с поддержкой очередей, поскольку у меня есть несколько потоков отправки/получения, поэтому это протокол будет иметь более одного приложения, и мне нужен протокол для обработки очередей этих запросов (я буду держать буфер если передача является очередью, но мне нужен протокол для управления планированием очередей).

2 - Работает с SPI в качестве базового протокола.

3 - Простая проверка ошибок.

В этом потоке: Простой последовательный протокол связи точка-точка", PPP был рекомендованным вариантом, однако я вижу, что PPP выполняет только часть задания.

Я также нашел проект Lightweight IP (LwIP) с PPP через последовательный порт (который я предполагаю, что я могу использовать его через SPI), поэтому я подумал о возможности использования любых протоколов верхнего уровня, таких как TCP/UDP, чтобы сделать остальные требуемые рабочие места. К счастью, я нашел TI, включая LwIP, как часть своего Ethernet-коммутатора в пакете стартеров, который, как я полагаю, облегчает портирование по крайней мере на стороне чипа TI.

Итак, мои вопросы:

1 - Действительно ли использовать LwIP для этой схемы связи? Разве это не приведет к большим накладным расходам из-за заголовков IP-адресов, которые не нужны для связи по точкам (на уровне чипа) и убьют пропускную способность?

2 - Будет ли TCP или любой аналогичный протокол, находящийся в LwIP, обрабатывать очередь запросов на передачу, например, если я запрашиваю передачу через сокет, в то время как канал связи занят передачей/получением запроса для другого сокета (сеанса) другого потока, будет ли это управляться стек протоколов? Если да, то какой уровень протокола управляет им?

3 - Является ли их более эффективным стек протоколов, чем LwIP, который соответствует вышеуказанным требованиям?

Обновление 1: Больше точек для рассмотрения

1 - SPI - единственный доступный параметр, я использую его с доступными GPIO, чтобы указывать ведущему, когда подчиненный имеет данные для отправки.

2 - Текущий реализованный (нестандартный) протокол использует DMA с SPI и формат сообщения "STX_MsgID_length_payload_ETX" с фиксированной длиной фрагментов сообщения, однако основным недостатком текущей схемы является то, что мастер ждет ответа на сообщение (а не фрагмент) перед отправкой другого, что убивает пропускную способность и не использует полный дуплексный характер SPI.

3. Улучшение этой точки заключалось в использовании своего рода почтового ящика для приема фрагментов, поэтому длинное сообщение может быть прервано более высоким приоритетом, так что фрагменты одного сообщения могут поступать не последовательно, но проблема в том, что этот дизайн приводит к усложнению ситуации, особенно, что у меня нет большого количества ресурсов для многих буферов для использования подхода почтового ящика на стороне контроллера (мастера). Поэтому я подумал, что это похоже на то, что я изобретаю колесо, создавая стек протоколов для простой ссылки на точку, которая может быть неэффективной.

4 Какие протоколы более высокого уровня обычно можно использовать над SPI для установления нескольких сеансов и решения очереди/планирования сообщений?

Обновление 2: Еще один полезный поток Хороший протокол/стек последовательной связи для встроенных устройств?

Обновление 3:. Я просмотрел протокол Modbus, он, как представляется, задает прикладной уровень, а затем уровень канала передачи данных для последовательной связи по линии, что позволяет пропустить ненужные служебные данные сетевых протоколов слои.

Считаете ли вы, что это будет лучший вариант, чем LwIP по назначению? Кроме того, существует широко используемая реализация с открытым исходным кодом, такая как LwIP, но для Modbus?

Ответ 1

Я думаю, что, возможно, вы ожидаете слишком много скромного SPI.

Ссылка SPI - это немного больше пара регистров сдвига по одному в каждом node. Мастер выбирает один node для подключения к его регистру сдвига SPI. Когда он сдвигает свои данные, подчиненный одновременно сдвигает данные. Данные не обмениваются, если мастер явно не отключает данные. Эффективные протоколы SPI включают в себя ведомое устройство, имеющее что-то полезное для вывода в то время как главные входы. Это может быть сложно устроить, поэтому вам обычно необходимо указать нулевые данные.

PPP полезен при установлении соединения между двумя произвольными конечными точками, когда конечные точки фиксированы и известны априори, PPP не будет служить никакой цели, кроме как осложнять вещи без необходимости.

SPI не является очень сложным и гибким интерфейсом и, вероятно, не подходит для супертяжелых протоколов общего назначения, таких как TCP/IP. Поскольку "адресация" в SPI выполняется путем выбора физического чипа, адресация, присущая таким протоколам, не имеет смысла.

Управление потоком также является проблемой с SPI. Мастер не может определить, что ведомое устройство скопировало данные из SPI в регистр сдвига, прежде чем нажимать больше данных. Если ваш подчиненный SPI поддерживает DMA, вам было бы разумно его использовать.

В любом случае я предлагаю вам разработать что-то конкретное для вашей цели. Поскольку SPI не является сетью как таковой, вам нужно только средство для адресации по выбранному node. Это может быть так же просто, как STX<thread ID><length><payload>ETX.

Добавлено 27 сентября 2013 года в ответ на комментарии Как правило, SPI, как следует из их названий, используется для подключения к периферийным устройствам, и в этом контексте протокол определяется периферийным устройством. Например, EEPROMS обычно используют общий или по меньшей мере совместимый командный интерфейс между поставщиками, а интерфейс SPI SD/MMC-карты использует стандартизованный командный тест и протокол.

Между двумя микроконтроллерами я бы предположил, что большинство реализаций являются проприетарными и специфичными для приложений. Открытые протоколы предназначены для общей совместимости, и для достижения этого могут возникнуть значительные ненужные накладные расходы для закрытой системы, если, возможно, узлы не запускали систему, в которой уже был встроен сетевой стек.

Я бы предположил, что если вы хотите использовать общий сетевой стек, который вам следует абстрагировать SPI с драйверами устройств на каждом конце, которые дают SPI стандартный интерфейс потока ввода-вывода (open(), close(), read(), write() и т.д.), то вы можете использовать протоколы PPP более высокого уровня и TCP/IP (хотя PPP, вероятно, можно избежать, поскольку соединение является постоянным). Однако это было бы привлекательно только в том случае, если оба узла уже поддерживали эти протоколы (например, под Linux), иначе это будет значительным усилием и кодом для небольшой выгоды и, безусловно, не будет "эффективным".

Ответ 2

Я предполагаю, что вы действительно не хотите или имеете место для полного пакета ip (lwip) на микроконтроллере? Это просто звучит как много перебор. Почему бы просто не свернуть собственную структуру пакетов, чтобы переместить элементы данных, которые вам нужно переместить. В зависимости от того, как spi поддерживается с обеих сторон, вы можете или не сможете использовать его для определения фрейма для своих данных, если не простой шаблон запуска, длина и контрольная контрольная сумма и, возможно, хвостовой шаблон достаточны для нахождения границ пакетов в поток (не отличается от решения serial/uart). Вы даже можете использовать решение PPP для этого с шаблоном запуска, и я думаю, что конечный шаблон с полезной нагрузкой с использованием двухбайтового шаблона всякий раз, когда появляется шаблон запуска в данных. Я не помню все детали сейчас.

Каким бы ни был ваш фрейм, добавьте тип пакета и ваши рукопожатия, или если данные будут просто микроконтроллером, чтобы держать руку, вам даже не нужно это делать.

Чтобы вернуться к вашему прямому вопросу. Да, я думаю, что стек ip (lwip или другой) внесет много накладных расходов. как пропускная способность, так и более важная сумма кода, необходимого для поддержки этого стека, будет разминать rom/ram с обеих сторон. Если вам в конечном итоге нужно представить эти данные в формате ip (веб-сайт, размещенный встроенной системой), то где-то на пути вам понадобится ip-стек и т.д.

Я не могу себе представить, что Lwip управляет вашими очередями для вас. Я предполагаю, что вам нужно это сделать самому. различные очереди могут захотеть поговорить с одним драйвером, который имеет дело с единственной шиной spi (при условии, что имеется одна шина spi с несколькими выборами микросхем). Это также зависит от того, как вы используете интерфейс spi, если вы разрешаете руке разговаривать с несколькими микроконтроллерами, а пакеты данных немного расходятся с этим контроллером от этого контроллера, так что никто не должен ждать задолго до того, как они получат еще несколько байтов данных. Или полный кадр должен перейти от одного микроконтроллера, прежде чем перейти к следующему прерыванию gpio, чтобы вытащить данные ребята? Долгий и короткий из них я предполагаю, что вам нужно управлять общим ресурсом, как и в любой другой ситуации, когда у вас есть несколько пользователей общего ресурса (rtos, полнофункциональная операционная система и т.д.). Я вообще не помню lwip, но с полнофункциональным интерфейсом приложений сокетов berkeley пользователь мог писать отдельные приложения, в которых каждое приложение заботилось только об одном TCP или UDP-порту, а библиотеки и драйверы управляли разделением этих пакетов на каждое приложение, а также все правила для стека IP.

Если вы еще не экспериментируете с перемещением данных по интерфейсам spi, я сначала начну с простых экспериментов, чтобы понять, насколько это хорошо или не будет работать, размеры передач, которые вы можете сделать надежно на прямую трансмиссию и т.д. Ваше решение может, естественно, просто выпасть из этих экспериментов.