Меню

Шина canopen что это такое

Введение в CANopen

CANopen — это открытая промышленная сеть созданная на основе Controller Area Network (CAN). Стандарт CAN (ISO 11898) описывает два нижних уровня эталонной модели ISO/OSI, CANopen описывает остальные пять. Документ The CANopen Application Layer and Communication Profile (CiA DS 301) определяет каким образом устройства обмениваются данными и описывает интерфейс к нижележащим уровням сети.

Основная область применения СANopen — встроенные роспределенные системы управления реального времени (embedded networks). СANopen фактически является стандартом и наиболее широко применяемым протоколом при создании современных систем управления в машиностроении (обрабатывающие станки различного назначения, термпопласт-автоматы, полиграфическое оборудование), железнодорожном транспорте (DIN 25002-2), специальном транспорте, сложном медицинском оборудовании, лифтах. CANopen не применяется в АСУТП.

Общая схема связи устройств в CANopen

Протокол CANopen определяет несколько методов передачи сообщений по сети CAN. Эти сообщения называются объектами связи (communication objects). CANopen поддерживает синхронизованную передачу сообщений, которая обеспечивается объектами Sync и Time Stamp. Асинхронные сообщения (или события) могут пересылаться в любой момент времени. В целом CANopen определяет четыре типа сообщений (communication objects):

  • сообщения управления сетью, например Layer Management (LMT) и Network Management (NMT) сообщения
  • так называемые Service Data Objects (SDO)
  • так называемые Process Data Objects (PDO)
  • Предопределенные сообщения (Sync Object, Time Stamp Object, Emergency Object)

Инициализация и управление сетью

Сервис управления сетью используется для контроля состояния устройств в сети CANopen. В рамках сервиса управления сетью доступны следущие функции:

  • динамическое или статическое распределние идентификаторов CAN для SDO/PDO соединений и сервиса обработки ошибок,
  • управление состоянием работы устройств и котроль режимов соединений в устройствах
  • периодический опрос устройств для определения сбоев в устройствах
  • вместо опроса каждое устройство может периодически посылать сообщение о том, что оно функционирует нормально

Механизм передачи данных

CANopen определяет два совершенно разных механизма передачи данных.

Service Data Object (SDO) механизм обычно используется для конфигурирования устройств низкой приоритетности. Отдельные параметры устройства адресуются при помощи 16 битного адреса и 8 битного подадреса. С помощью SDO можно передавать данные длиной больше восьми байт используя механизм фрагментации. Функциональность SDO:

  • передача данных любого размера,
  • чтение и запись любых данных с подтверждением,
  • быстрая передача данных длиной до 4 байт,
  • обрыв соединения с любого конца с передачей ошибки через сеть.

Все параметры устройства объеденены в object dictionary (словрь объектов), и все объекты в object dictionary могут быть прочитаны или изменены удаленно при помощи SDO.

Process Data Object (PDO) механизм используется для предачи с высокой скоростью высокоприоритетных данных, так как PDO сообщения не содержат никаких дополнительных протокольных данных. При помощи PDO можно передавать только данные длина которых меньше 8 байт. Формат данных PDO может быть фиксированным или может быть сконфигурирован при помощи SDO. PDO сообщения могут быть переданы одним узлом сразу нескольким другим узлам одновременно.

События

CANopen поддерживает несколько способов передачи данных реального времени.

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

Возможен синхронный режим передачи данных. В этом режиме устройства синхронизируют передачу данных в сеть с часами Master устройства. Этот режим особенно полезен когда контуры управления замыкаются через сеть (так называемые сетевые системы управления).

Кроме перечисленных выше способов передачи данных, можно использовать передачу по запросу (polling). В любой момент можно использовать PDO сообщение для инициации передачи данных устройством. Эта схема использует RTR бит CAN кадра.

Источник

CAN + CANOpen + CANfestival + STM32. Часть первая


Вы когда-нибудь участвовали в форумных склоках на тему «Что лучше — написать свое или взять готовое?». Лично я обожаю подобные вещи, причем я больше предпочитаю наблюдать, нежели участвовать. Ведь это так весело, сначала обсуждаются технические детали, потом постепенно переходят на личности, потом кого-то банят… Вы скажете, что я второсортное быдло, которому нравятся такие же второсортные развлечения? Знаете, а зачем это отрицать, зачем заниматься самообманом? Лучше принять себя таким, какой я есть, и гордо нести это как знамя: «Да, я — быдло!». Поэтому вместо самоотрицания я попытаюсь «набросить», и если мне повезет, то там, в комментариях разгорится такой спор переходящий от технический деталей к личным оскорблениям.
Так что может послужить предпосылкой такого спора? Ну вот, например, такая тема. Есть у вас в микроконтроллере замечательная штука — интерфейс CAN, помощью которого можно сделать массу замечательных вещей: шину для связи между модулями в умном доме, между узлами в собственном роботе, между модулями в ПЛК, между электроникой в автомобиле и т.д. и т.п. Но что пустить «поверх» CAN: свой самодельный протокол или взять готовый. А если готовой протокол, то что лучше свой самописный стек или готовый? Займу пожалуй одну из крайних позиций — все готовое, и протокол и стек к нему, а именно CANOpen и CANFestival.

Читайте также:  Can шина альмера классик 2006

Совсем без теории, к сожалению, не получится. Поэтому вкратце вот о чем:

  1. Пару слов о самом CAN
  2. О самом CANOpen
  3. И немного о CANfestival

Коротко о CAN

Почему именно CAN и чем он лучше, например, UART+RS485? На мой взгляд основное преимущество CAN состоит в побитовом арбитраже, который позволят «говорить» одновременно двум узлам на шине. Разумеется одновременно они говорить не будут, но благодаря этому механизму узлы «договорятся», кто скажет первый, а кто второй. Это происходит на уровне контроллера CAN и разработчику совершенно не нужно за этим следить. Это открывает возможность отправлять данные в шину асинхронно, если узлы хотят что-то передать, то «пусть говорят», когда хотят.

Минимальная единица передачи данных — фрейм. Если из фрейма выкинуть служебные составляющие, то доступные для использования разработчиком это 11-битный идентификатор, поле длинны и от 0 до 8 байт данных. По CAN’у этим ограничусь, если мало, то вот, например, хороший источник.

А вот с протоколом CANOpen двумя словами не отделаться.

Объектный словарь (Object dictionary) и что с ним делать

Представьте себе целую сеть из устройств, объединенных шиной CAN. Для того, чтобы однозначно различать эти устройства друг от друга, CANOpen вводит такое понятие, как Node Id (идентификатор узла). Этот Node Id во избежании недоразумений должен быть уникальным для каждого устройства на шине. Если кто-то знаком с протоколом Modbus, то он вероятно знает, что такое адрес ведомого устройства (Slave Address). Именно с этим адресом и можно провести аналогию для Node Id.
Источником данных в сети CANOpen служат объектные словари (object dictionary) узлов. Этот термин, как впрочем и все остальные, крайне редко встречается в различного рода литературе в переведенном на русский язык виде. Гораздо чаще приходится иметь дело именно с Object dictionary, а еще чаще с его аббревиатурой OD. Так вот OD это, что-то вроде двухуровневого списка или, может быть правильней, таблицы. Первый уровень пронумерован индексами от 0 до 65535. Второй уровень списка (или таблицы) пронумерован субиндексами от 0 до 255. В пунктах этого списка (или ячейках таблицы) и находятся данные, которыми обмениваются узлы в сети CANOpen. Таким образом, чтобы индексировать данные нужно два параметра индекс и субиндекс. Часто можно встретит запись в таком формате XXXXsubYY, где XXXX индекс в шестнадцатеричном формате, а YY то шестнадцатеричный субиндекс, например 1028sub03. Если продолжить строить аналогию с модбасом, то в модбасе есть карта регистров, а CANOpen есть объектный словарь OD. Вот только OD в отличии от карты регистров имеет более сложную структуру и имеет гораздо больше типов данных. Что за данные в нем лежат? Да что угодно — текущие значения аналоговых или дискретных входов, управляющие значения для выходных сигналов, настройки, сведения об устройстве и производителе и т.д. и т.п.

Для записи и чтения данных в/из OD, CANOpen предоставляет следующие сообщения:

  • SDO (service data object) — чтение и запись данных в OD по запросу.
  • PDO (process data object) — сообщения для отправки данных асинхронно (хотя не обязательно). Как правильно через эти сообщения передаются текущие измерения и управляющие сигналы
Читайте также:  Выпуски шин пирелли по годам пирелли

Читать и писать в объектный словарь может ведущий в сети CANOpen или, как его часто называют, «мастер» (master). Как правило, когда мастер настраивает какой-либо узел, он при помощи SDO записывает в OD интересующие его параметры. Формат сообщения с запросом на чтение или запиись зависит от типа SDO — короткое однофреймовое (expedited) или длинное многофреймовое (segmented). Expedited-формат предназначен для обмена небольшим объемом данных — до 4-ех байт, для всего что больше нужен формат segmented.

Однофреймовый expedited-запрос формируется следующим образом (см. картинку ниже):

  • 11-битный идентификатор = 0x600 + Node Id
  • Длинна = 8 байт
  • 0-ой байт данных — спецификатор команды, подробнее о нем ниже
  • 1-2 байты данных — соответственно младший и старший байты интересующего индекса OD
  • 3 байт — субиндекс OD
  • 4-7 байты — данные, если это запись


В нулевом байте css равен 2, если это команда на запись, 4, если запрос на чтение. Значение n немного не очевидное — это количество байт в сообщении, в которых НЕТ ДАННЫХ.

Ответ на такой запрос выглядит следующим образом:

  • 11-битный идентификатор = 0x580 + Node Id
  • Длинна = 8 байт
  • 0-ой байт данных — спецификатор команды
  • 1-2 байты данных — соответственно младший и старший байты интересующего индекса OD
  • 3 байт — субиндекс OD
  • 4-7 байты — данные, если это ответ на читающий запрос

Если запрос успешно выполнен то css будет равен 4, в случае же ошибки — 8. Всё остальное имеет тот же смысл, что и в запросе.
Для ясности приведу пример. Предположим, что нужно записать 4-ёх байтное число 0x12345678 в объектный словарь некоторого узла с Node Id равным 1 по индексу 0x2000 субиндексу 2. Фрейм с запросом будет выглядеть следующим образом:

ID = 0x601, len = 8, data = 0x23 0x00 0x20 0x02 0x78 0x56 0x34 0x12

Ответ в случае успеха будет выглядеть так:

ID = 0x581, len = 8, data = 0x60 0x00 0x20 0x02 0x00 0x00 0x00 0x00

Обращаю внимание, что данные во фрейме располагаются в порядке от младшего байта к старшему. Поэтому поле данных индекс представлен как 0x00 0x20, а данные идут байт за байтом 0x78 0x56 0x34 0x12.

Еще пример — запись 2-ух байт в индекс 0x2002 субиндекс 0x03:
Запрос
ID = 0x601, len = 8, data = 0x2B 0x02 0x20 0x03 0x34 0x12 0x00 0x00
Ответ
ID = 0x581, len = 8, data = 0x60 0x02 0x20 0x03 0x00 0x00 0x00 0x00

И еще пример — 1 байт в индекс 0x2003 субиндекс 0x04:
Запрос
ID = 0x601, len = 8, data = 0x2F 0x03 0x20 0x04 0x12 0x00 0x00 0x00
Ответ
ID = 0x581, len = 8, data = 0x60 0x03 0x20 0x04 0x00 0x00 0x00 0x00

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

txPDO0: + Node ID, Len = 8, Data = [8 байт данных]
txPDO1: + Node ID, Len = 8, Data = [8 байт данных]
txPDO2: + Node ID, Len = 8, Data = [8 байт данных]
txPDO3: + Node ID, Len = 8, Data = [8 байт данных]

rxPDO0: + Node ID, Len = 8, Data = [8 байт данных]
rxPDO1: + Node ID, Len = 8, Data = [8 байт данных]
rxPDO2: + Node ID, Len = 8, Data = [8 байт данных]
rxPDO3: + Node ID, Len = 8, Data = [8 байт данных]

Таким образом каждый узел, может в совершенно любой момент времени отправлять до 32 байт и столько же принимать. Делать он это может по собственному желанию, никто его спрашивать не будет. Очень удобно, например, для измерений — свежие данные будут отправлены, когда будет закончено измерение, а не когда их запросят.
Источником данных для PDO служит объектный словарь, точнее некоторые его ячейки. Эти ячейки настраиваются, после чего стек CANOpen должен отправлять их содержимое в PDO каждый раз, когда они изменятся или периодически, или по команде в зависимости от опций.
Аналогично на приемной стороне настраиваются ячейки OD, куда будут попадать входящие PDO.

Читайте также:  Секционированной или несекционированной системой шин не имеющей обходной системы шин

Network Management (NMT)

Каждый узел в сети CANOpen может находится в одном из многочисленных состояний:

  • Initialization — состояние сразу подачи питания;
  • PreOperational — «предбоевое» состояние. В это режиме узел уже шлет Heartbeat’ы (о них ниже), но еще не шлет и не принимает PDO;
  • Operational — «боевой» режим, в котором узел шлет и принимает PDO;
  • Stopped — режим полной остановки, узел будет недоступен даже по SDO. Предполагается, что в этот режим будут загонять устройство перед выключением.

Управление этими режимами осуществляется с помощью специальных сообщений имя которым NMT. Их формат следующий:

ID = 0x00, Len = 2, data = [cmd (1 байт)] [nodeId (1 байт)]

cmd принимает значения 1 — для перевода в режим Operational, 2 — Stopped, 0x80 — PreOperational; nodeId — это Node Id узла, режим которого хотят изменить.

Heartbeat’ы и Node Guarding

Вот в Modbus’е в некотором смысле все просто, если на узел отправили запрос, а он не ответил, то можно считать что он (узел) «помер». Но CANOpen запросы SDO используются только, чтобы настроить устройство, а в «боевом» режиме ведомое устройство может только «слушать» входящие PDO, если это какой-то модуль вывода сигналов, при этом совершенно ничего не отправляя в ответ. Как же понять, что подобный узел вообще в данный момент присутствует на шине? Для этого в CANOpen есть два механизма Heartbeat и Node Guarding. Как правило применяется один из двух, технически конечно можно зарядить и тот и другой, но я такого ни разу не видел.
Механизм Heartbeat’ов достаточно простой: каждый узел в сети с определенным периодом отправляет CAN фреймы следующего содержания:

ID = 0x700 + Node, ID Len = 1, data = [Mode (1 байт)]

Mode принимает значения 0x7F, если узел в режиме PreOperational, 0x05 — Operational, 0x00 — BootUp, 0x04 — Stopped. Значение BootUp отправляется самый первый раз, когда узел появляется на шине. Если от узла перестали приходить Heartbeat’ы, то можно диагностировать потерю связи.

Механизм Node Guarding исповедует прямо противоположный подход. Мастер периодически опрашивает при помощи NMT ведомые устройства на предмет их текущего режима. Нет ответа — нет узла.

Emergency

Если Вы терпеливо дочитали всё до этого места, то я практически уверен, что Вы не страдаете модным нынче недугом «Дефицитом внимания», с чем я Вас искренне поздравляю. Но это так, в качестве лирического отступления.
Возвращаясь к сути, обращу Ваше лишенное дефицита внимание вот на что: в распределенной сети могут происходит всякие неприятности вроде аварий, отказов, превышение уставок и т.д. и т.п. Для того, что бы экстренно об этом оповестить в CANOpen есть специальные сообщения Emergency, которые формируются вот так:

ID = 0x80 + Node Id, Len = 4..8, data = [Error Code(2 байта)] [Error Register(2 байта)] [Manufacturer Specific Error Field(0..4 байт)]

Error Code — это код ошибки, это коды частично стандартизованы протоколом, Error Register — об этом не в этот раз, Manufacturer Specific Error — код ошибки, который разработчики могут определять по своему усмотрению.

CANFestival

Есть такой замечательный человек — Эдуард Тиссерант (Edouard Tisserant). Он вместе с единомышленниками в свое время реализовал стек, который реализует всё вышеописанное и даже больше. Имя этому стеку CANFestival. Кстати говоря это далеко не единственное достижение Эдуарда, с его именем тесно связан проект Beremiz, с которым познакомил наше сообщество коллега Антон Мидюковantohami .

Ну так вот, в официальном репозитарии CANFestival помимо портов под Linux можно найти порты и под микроконтроллеры AVR. Подробно о том что в этом репозитарии, как портировать и создавать объектные словари и обособленные проекты расскажу во второй части, ибо силы писать эту статью уже кончились.

Источник

Adblock
detector