Перейти к содержанию
    

Есть ли какой-нибудь стандартный утилитарный протокол поверх CAN?

8 hours ago, jcxz said:

Нет. Мастер сканирует сеть и раздаёт динамически ID. Сканирование идёт с использование механизма арбитража CAN. Каждое устройство должно иметь уникальный серийный номер (64-битный). При сканировании каждому такому длинному номеру назначается короткий, который потом используется для обмена по CAN. Мастер - динамический. Им становится то устройство, к которому пользователь подключился клиентской программой. Остальные устройства CAN-сети - слэйвы.

Поищите, года ~3 назад описывал здесь.

Не совсем так, но не принципиально. Всё равно смысла в этой дискуссии нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 hours ago, jcxz said:

Нет. Мастер сканирует сеть и раздаёт динамически ID. Сканирование идёт с использование механизма арбитража CAN. Каждое устройство должно иметь уникальный серийный номер (64-битный). При сканировании каждому такому длинному номеру назначается короткий, который потом используется для обмена по CAN. Мастер - динамический. Им становится то устройство, к которому пользователь подключился клиентской программой. Остальные устройства CAN-сети - слэйвы.

Поищите, года ~3 назад описывал здесь.

Поищу!
Тоесть, если из сети пропадает тот мастер, который назначает всем ID, вся система получается не рабочая? А если в сети два таких мастера?
По идее вся прелесть CAN заключается в том, что все слушают всех, каждое устройство более менее автономно. 
Хотя это всё впринципе относительно. Можно, конечно, и так. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, girts сказал:

Тоесть, если из сети пропадает тот мастер, который назначает всем ID, вся система получается не рабочая? А если в сети два таких мастера?

Почему нерабочая? Этот протокол относится к обмену между мастером (к которому подключена клиентская программа пользователя) и слэйвами. Мастер пропадает в тот момент, когда эта программа отключается. С кем тогда обмениваться?

Случай подключения двух мастеров - недопустимый. На этот случай в протоколе предусмотрен механизм блокировки работы - не будет работать ни один из мастеров, пока одного не отсоединят.

Вся остальная работа по CAN никак не зависит от этого протокола. Он только для связи между клиентской программой конфигурирования и управления и одним из слэйвов. О чём как раз эта тема.

1 час назад, girts сказал:

По идее вся прелесть CAN заключается в том, что все слушают всех, каждое устройство более менее автономно.

Так и есть. Мой протокол этому не противоречит и никак не мешает остальной работе сети.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Описал протокол и реализовал на парочке разных девайсов - удобства есть. Кому интересно, можете полистать.

Спецификация базового сервисного протокола CAN.pdf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Arlleex сказал:

Описал протокол и реализовал на парочке разных девайсов - удобства есть. Кому интересно, можете полистать.

Спецификация базового сервисного протокола CAN.pdf 717.73 кБ · 7 загрузок

Т.е. - CAN_ID_RX_TOP_ROOT и CAN_ID_TX_TOP_ROOT - эти 8-битные идентификаторы должны быть сконфигурены на узлах?

Цитата

Длина строкового имени ограничивается 1536 ASCII-символами, включая завершающий признак конца строки '\0'.

А почему не Unicode?  :unknw:  Вдруг экспортировать куда-нить захотите...

Я у себя задаваемый пользователем идентификатор узла делал в UTF-8.

 

PS: А вообще конечно - труд эпический! :good:  Всё это самостоятельно писали?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Предпочёл бы вместо явной работы с этой древовидной структурой решать задачу пробросом интерфейсов. У себя например сделал вход в CLI удалённого узла, а если тот имеет доступ к каким-то slave-ам (по другоим интерфейсам или через другую сеть CAN) то можно зайти в их CLI. Матрёшка из транспортных протоколов, а интерфейс через сеть получается такой же как если устройство подключено локально по USB или UART.

Сам "network discovery" у меня сильно похож на то, что описывал jcxz, и работа остальных протоколов так же происходит независимо. Есть некоторые особенности как именно новые устройства должны отвечать на запрос энумерации, у которых ещё не назначены короткие идентификаторы позволяющие задействовать арбитраж.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

37 минут назад, jcxz сказал:

Т.е. - CAN_ID_RX_TOP_ROOT и CAN_ID_TX_TOP_ROOT - эти 8-битные идентификаторы должны быть сконфигурены на узлах?

Это 11-битные идентификаторы в диапазоне 0x2...0xFF. Каждый девайс имеет свою пару Rx/Tx (т.е. он "слушает" только свои кадры по Rx, и передает по Tx). На шине может быть одновременно до 127 устройств включительно. Как только хост "познакомился" с этими ID, он может начинать более досконально узнавать, кто есть кто, с какими ID девайс генерирует кадры, какие ID у него заточены для приема (для работы с любыми другими протоколами для транзакции данными). Каждый девайс внутри себя заранее описывает свою структуру во флеш, например.

Цитата

А почему не Unicode?  :unknw:  Вдруг экспортировать куда-нить захотите...

Посчитал, что ASCII - самый базовый набор символов, который поддерживается на любом тапке🙂 В юникод уж пусть ведущий сам преобразует при желании. Минус - разве что, на кириллице нельзя задавать имена, но это не проблема.

Цитата

PS: А вообще конечно - труд эпический! :good:  Всё это самостоятельно писали?

Ага🙂 Периодически отвлекаясь на очередную серию "Игры престолов"🤣

P.S. Вот так, например, выглядит описание (дескриптор) одного из девайсов

static sIntfNode const CPUCtrlRxNode = {
  .info     = &(sNodeInfo){},
  .name     = NODE_NAME("CPU control"),
  .idQnt    = 1,
  .isIDWeak = 1
};

static sIntfNode const CPUCtrlTxNode = {
  .info     = &(sNodeInfo){},
  .name     = NODE_NAME("CPU control"),
  .idQnt    = 1,
  .isIDWeak = 0
};

static sIntfNode const BootCtrlRxNode = {
  .info     = &(sNodeInfo){},
  .name     = NODE_NAME("Bootloader control"),
  .idQnt    = 1,
  .isIDWeak = 1
};

static sIntfNode const BootCtrlTxNode = {
  .info     = &(sNodeInfo){},
  .name     = NODE_NAME("Bootloader control"),
  .idQnt    = 1,
  .isIDWeak = 0
};

static sIntfNode const BootDataRxNode = {
  .info     = &(sNodeInfo){},
  .name     = NODE_NAME("Bootloader data"),
  .idQnt    = 1,
  .isIDWeak = 1
};

static sIntfNode const BootDataTxNode = {
  .info     = &(sNodeInfo){},
  .name     = NODE_NAME("Bootloader data"),
  .idQnt    = 1,
  .isIDWeak = 0
};

static sRootNode const TopRootNode = {
  .rxInfo     = &(sNodeInfo){},
  .txInfo     = &(sNodeInfo){},
  .name       = NODE_NAME("Keypad"),
  .nodeQnt    = 6,
  .isRxIDWeak = 0,
  .isTxIDWeak = 0,
  .nodeNum    = &(u32){0xFFFFFFFF},
  .nodeList = {
    &CPUCtrlRxNode.info,
    &CPUCtrlTxNode.info,
    &BootCtrlRxNode.info,
    &BootCtrlTxNode.info,
    &BootDataRxNode.info,
    &BootDataTxNode.info
  }
};


В данном случае, у девайса есть "стандартный" протокол общего управления CPU (всякие там запросы версий, сброс, время наработки и т.д.), который задействует одну пару Rx/Tx CAN-ID, и еще один "стандартный" протокол бутлоадера. Конкретно тут эти рабочие ID генерируются на основе страп-пинов, но это уже не важно. Хосту теперь можно пройтись по всему дереву и он получит эти самые ID, благодаря чему не нужно помнить, у кого какие ID и для чего они))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

59 минут назад, amaora сказал:

Предпочёл бы вместо явной работы с этой древовидной структурой решать задачу пробросом интерфейсов. У себя например сделал вход в CLI удалённого узла, а если тот имеет доступ к каким-то slave-ам (по другоим интерфейсам или через другую сеть CAN) то можно зайти в их CLI. Матрёшка из транспортных протоколов, а интерфейс через сеть получается такой же как если устройство подключено локально по USB или UART.

Все это так или иначе будет использовать какое-то количество CAN-кадров, исходящих и входящих по отношению к девайсу. Это уже реализуется конкретным транспортным протоколом, коим этот мой CANTree не является. Протокол, описанный мною, позволяет обнаружить все девайсы на локальной физической CAN-шине, зарегистрировать все их рабочие ID и их предназначение.

Как пример: я воткнулся анализатором в CAN-шину, на которой потенциально сидит пара десятков моих девайсов. Их сконфигурировали на заводе - и я понятия не имею, как. Я жмакаю кнопку "поиск устройств" и программа показывает, кто есть кто. Вот я вижу, например, что висит 10 одинаковых устройств. Мне их нужно перешить - по-одному не интересно: CANTree позволяет (если в девайсе это поддержано) налету "сменить" любые ID. Удобно настроить во всех этих девайсах единый принимающий прошивку CAN-ID. Дальше просто скармливаю прошивку по заранее разработанному протоколу (как будто одному девайсу). Т.е. получил некий аналог бродкаста. Этим же бродкастом дал команду системного сброса - все девайсы разом сбросились. Удобно? Удобно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Arlleex сказал:

Как пример: я воткнулся анализатором в CAN-шину, на которой потенциально сидит пара десятков моих девайсов. Их сконфигурировали на заводе - и я понятия не имею, как. Я жмакаю кнопку "поиск устройств" и программа показывает, кто есть кто.

Так если они сконфигурены на заводе не понятно как, то тогда вероятны конфликты по полям CAN_ID_RX_TOP_ROOT и CAN_ID_TX_TOP_ROOT (почему я про них и спрашивал). А значит в общем случае - не всегда будет возможно опросить. Уникальными вообще (глобально) они быть не могут, поскольку малоразрядные.

Или возможно - я чего-то не понял из вашего протокола... (читал мельком - нету времени).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

38 минут назад, jcxz сказал:

Так если они сконфигурены на заводе не понятно как, то тогда вероятны конфликты по полям CAN_ID_RX_TOP_ROOT и CAN_ID_TX_TOP_ROOT (почему я про них и спрашивал). А значит в общем случае - не всегда будет возможно опросить. Уникальными вообще (глобально) они быть не могут, поскольку малоразрядные.

Или возможно - я чего-то не понял из вашего протокола... (читал мельком - нету времени).

Мы, конечно, заранее знаем, какой состав оборудования должен быть на конкретной шине. Изделия на заводе прошиваются с дефолтными настройками, в том числе их идентификаторами. Потом девайсы поступают на индивидуальную настройку - там прописываются уже их конкретные CAN-ID (как правило, мы присылаем файлик, в котором уже все как нужно расставлено, или программа-настройщик автоматом назначает CAN-ID в соответствии с неким правилом) - и после этого их можно втыкать в штатное место на шине. Т.е. конечно, после настройки не будет девайсов, работающих с одними и теми же CAN-ID, если это не сделано намеренно с пониманием, что так можно и нужно разработчику. Я отталкивался от того, что на одной физической шине CAN не может быть больше 127 устройств (приемо-передатчики банально не гарантируют стабильную работу в своих паспортах). А значит, все девайсы будут иметь уникальные ID в пределах до 127 штук. По этим CAN-ID как раз работает первоначальное обнаружение.

Я как разработчик могу вовсе заложить в девайсы логику, которая должна будет дождаться динамической раздачи всех рабочих CAN-ID от ведущего, и только после этого начинать работать - здесь свобода действий.

Как пример: есть два абсолютно одинаковых по прошивке девайса (клавиатуры), которые подключаются к CAN и выдают состояние кнопок. Вот только у одного комплект рабочих CAN-ID отличается от таковых в другой клаве, потому что они будут подключены к разным CAN-сетям, а там диапазоны отведенных CAN-ID уже давно поделены и утверждены организациями. Хосту не нужно держать рядом файл со всеми возможными CAN-ID этой клавиатуры - он просто сканирует сеть, находит клавиатуру, и берет ее рабочие CAN-ID. Теперь он знает, с каким CAN-ID она выдает состояние кнопок. Все то же самое относится к любым сервисным функциям - например, интерфейсу загрузчика, интерфейсу записи настроек, интерфейсу примитивного управления CPU (всякие программные сбросы, запросы статистики и т.д.).

Та же программа-прошивальщик нового ПО: мне не нужно держать перед глазами файл с CAN-ID работы с загрузчиком, потому что в зависимости от конкретных применений этот CAN-ID может быть любым, заданным когда-то при конфиге. Я жму кнопку "Поиск", мне программа выводит список найденных девайсов. Я мышкой перетаскиваю нужный мне найденный девайс в список обновления и жму кнопку "обновить ПО". Нигде CAN-ID в явном виде не фигурирует, не надо ничего вводить.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 часов назад, Arlleex сказал:

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

Ясно в целом. У вас получается несколько другая цель протокола. И соответственно - сделан упор на реализацию другой его части, чем у меня.

 

Вот ещё вопрос: Раз цель - чтобы "сторонний разработчик не вдавался в детали", то почему нет компонента, выдающего прогнозируемую загрузку шины? Например: Настройщик (или кто там настраивает конфигурацию CAN-ID на шине) так как он не хочет "вдаваться в детали", то может выставить такой конфиг, при котором будет невозможна работа шины из-за недостаточной пропускной способности на данной скорости.

У меня, в части настройки адресов (CAN-ID), с которых будет осуществляться периодическая отправка сообщений (телеметрии), конфигурационная программа показывает настройщику примерную прогнозируемую загрузку шины (конечно - для случая идеальной, безпомеховой связи). И выдаёт предупреждение, когда эта загрузка приближается к 100% (точнее 100% - заданный_порог_резерва).

Имхо: При такой идеологии (расчёт на недумающий персонал) такой компонент был бы весьма полезен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, jcxz said:

Имхо: При такой идеологии (расчёт на недумающий персонал) такой компонент был бы весьма полезен.

Если периодичность посылок известна, достаточно просто ограничить сеть количеством устройств.
А если всё устроено по принципу диалога, сиё не имеет смысла.
А если параметры коммуникации назначаются мастером, то пускай оно и мониторит сиё по надобности и принимает меры - ну, скажем, чтоб не раз в 20 мс передавало, а раз в 200 мс.

А так... много букв! Если документ содержит больше одной страницы, все юзеры обычно читают только первую. 

Хз, я бы делал так - все неинициированные устройства представляются на одном конкретном ID. В даннх - серийник, тип, да вообщем что то уникалоьное. Дальше - мастер назначает ему параметры коммуникации.

Если мастер видит что опять в сети появилось это ID - или появилось новое устройство или отвалилось что нибудь - принимает меры.
А периферия, при обнаружении что ещё что то вещает на выделенном ей ID (типа что то неправильно срослось) может просто отваливатся обратно в неинициализированном состоянии.


Благо, хоть всё на CAN может вещать на одном ID без проблем.  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

39 минут назад, girts сказал:

Если периодичность посылок известна, достаточно просто ограничить сеть количеством устройств.

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

39 минут назад, girts сказал:

Хз, я бы делал так - все неинициированные устройства представляются на одном конкретном ID. В даннх - серийник, тип, да вообщем что то уникалоьное. Дальше - мастер назначает ему параметры коммуникации.

Тоже плохой способ. Забываете про коллизии. Будете получать мусор или ошибки CRC на шине при штатной работе без воздействия каких-либо помех.

39 минут назад, girts сказал:

Благо, хоть всё на CAN может вещать на одном ID без проблем.  

Смысл этой фразы неясен... :wacko2:

Передачи различающихся данных от разных узлов CAN "на одном ID" чреваты неразрешаемыми коллизиями в данных. Только абсолютно идентичные данные так можно передавать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) ну для того как бы и есть софтварь для конфигурации, чтоб задать параметры правильно и чтобы не перегружать шину данными, нее?  

2) и что? Если правильно помню, арбитраж работает не только на ID, но и на весь пакет. Если девайс раз в 5 секунд орёт в шину чем то низкоприоритетным что ему треба конфиг имхо ничего страшного нет. Ну ОК, допустим, пакет испортился - и что? через рандомное время повторная попытка, делов то.... Сообщать раз в 10мс что появился новый девайс - смысла не особо. 
И даже если про тот аппаратный вариант, что посылка в слоте пытается повторно попасть в шину до полного успеха и ACK, так это тоже отключаемо и можно (и может и нужно) софтварно это всё обработать. 

3) исходит из второго.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

58 минут назад, girts сказал:

Если правильно помню, арбитраж работает не только на ID, но и на весь пакет.

У вас неправильные сведения со всеми вытекающими. Для понимания, почему сделано так, а не этак, понимать, как работает CAN, жизненно важно.

Очень плохо, что возникающие коллизии в шине для Вас норма. Благо бош заложил счетчики ошибок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...