CAN Error Detection and Confinement
One of the most important and useful features of CAN is its high reliability, even in extremely noisy environments. CAN provides a variety of mechanisms to detect errors in frames. This error detection is used to retransmit the frame until it is received successfully. CAN also provides an error confinement mechanism used to remove a malfunctioning device from the CAN network when a high percentage of its frames result in errors. This error confinement prevents malfunctioning devices from disturbing the overall network traffic.
Error Detection
Whenever any CAN device detects an error in a frame, that device transmits a special sequence of bits called an error flag. This error flag is normally detected by the device transmitting the invalid frame, which then retransmits to correct the error. The retransmission starts over from the start of frame, and thus arbitration with other devices can occur again.
CAN devices detect the following errors, which are described in the following sections:
- Bit error
- Stuff error
- CRC error
- Form error
- Acknowledgment error
Bit Error
During frame transmissions, a CAN device monitors the bus on a bit-by-bit basis. If the bit level monitored is different from the transmitted bit, a bit error is detected. This bit error check applies only to the Data Length Code, Data Bytes, and Cyclic Redundancy Check fields of the transmitted frame.
Stuff Error
Whenever a transmitting device detects five consecutive bits of equal value, it automatically inserts a complemented bit into the transmitted bit stream. This stuff bit is automatically removed by all receiving devices. The bit stuffing scheme is used to guarantee enough edges in the bit stream to maintain synchronization within a frame.
A stuff error occurs whenever six consecutive bits of equal value are detected on the bus.
CRC Error
A CRC error is detected by a receiving device whenever the calculated CRC differs from the actual CRC in the frame.
Form Error
A form error occurs when a violation of the fundamental CAN frame encoding is detected. For example, if a CAN device begins transmitting the Start Of Frame bit for a new frame before the End Of Frame sequence completes for a previous frame (does not wait for bus idle), a form error is detected.
Acknowledgment Error
An acknowledgment error is detected by a transmitting device whenever it does not detect a dominant Acknowledgment Bit (ACK).
Error Confinement
To provide for error confinement, each CAN device must implement a transmit error counter and a receive error counter. The transmit error counter is incremented when errors are detected for transmitted frames, and decremented when a frame is transmitted successfully. The receive error counter is used for received frames in much the same way. The error counters are increased more for errors than they are decreased for successful reception/transmission. This ensures that the error counters will generally increase when a certain ratio of frames (roughly 1/8) encounter errors. By maintaining the error counters in this manner, the CAN protocol can generally distinguish temporary errors (such as those caused by external noise) from permanent failures (such as a broken cable). For complete information on the rules used to increment/decrement the error counters, refer to the CAN specification (ISO 11898).
With regard to error confinement, each CAN device may be in one of three states: error active, error passive, and bus off.
Error Active State
When a CAN device is powered on, it begins in the error active state. A device in error active state can normally take part in communication, and transmits an active error flag when an error is detected. This active error flag (sequence of dominant 0 bits) causes the current frame transmission to abort, resulting in a subsequent retransmission. A CAN device remains in the error active state as long as the transmit and receive error counters are both below 128. In a normally functioning network of CAN devices, all devices are in the error active state.
Error Passive State
If either the transmit error counter or the receive error counter increments above 127, the CAN device transitions into the error passive state. A device in error passive state can still take part in communication, but transmits a passive error flag when an error is detected. This passive error flag (sequence of recessive 1 bits) generally does not abort frames transmitted by other devices. Since passive error flags cannot prevail over any activity on the bus line, they are noticed only when the error passive device is transmitting a frame. Thus, if an error passive device detects a receive error on a frame which is received successfully by other devices, the frame is not retransmitted.
One special rule to keep in mind: When an error passive device detects an acknowledgment error, it does not increment its transmit error counter. Thus, if a CAN network consists of only one device (for example, if you do not connect a cable to the National Instruments CAN interface), and that device attempts to transmit a frame, it retransmits continuously but never goes into bus off state (although it eventually reaches error passive state).
Bus Off State
If the transmit error counter increments above 255, the CAN device transitions into the bus off state. A device in the bus off state does not transmit or receive any frames, and thus cannot have any influence on the bus. The bus off state is used to disable a malfunctioning CAN device which frequently transmits invalid frames, so that the device does not adversely affect other devices on the network. When a CAN device transitions to bus off, it can be placed back into error active state (with both counters reset to zero) only by manual intervention. For sensor/actuator types of devices, this often involves powering the device off then on. For NI-CAN network interfaces, communication can be started again using an API function.
Промышленная сеть реального времени CAN представляет собой сеть с общей средой передачи данных. Это означает, что все узлы сети одновременно принимают сигналы передаваемые по шине. Невозможно послать сообщение какому-либо конкретному узлу. Все узлы сети принимают весь трафик передаваемый по шине. Однако, CAN-контроллеры предоставляют аппаратную возможность фильтрации CAN-сообщений.
Каждый узел состоит из двух составляющих. Это собственно CAN контроллер, который обеспечивает взаимодействие с сетью и реализует протокол, и микропроцессор (CPU).
Рис. 1. Топология сети CAN.
CAN контроллеры соединяются с помощью дифференциальной шины, которая имеет две линии — CAN_H (can-high) и CAN_L (can-low), по которым передаются сигналы. Логический ноль регистрируется, когда на линии CAN_H сигнал выше, чем на линии CAN_L. Логическая единица — в случае когда сигналы CAN_H и CAN_L одинаковы (отличаются менее чем на 0.5 В). Использование такой дифференциальной схемы передачи делает возможным работу CAN сети в очень сложных внешних условиях. Логический ноль — называется доминантным битом, а логическая единица — рецессивным. Эти названия отражают приоритет логической единицы и нуля на шине CAN. При одновременной передаче в шину лог. нуля и единицы, на шине будет зарегестрирован только логический ноль (доминантный сигнал), а логическая единица будет подавлена (рецессивный сигнал).
Типы сообщений сети CAN.
Данные в CAN передаются короткими сообщениями-кадрами стандартного формата. В CAN существуют четыре типа сообщений:
- Data Frame
- Remote Frame
- Error Frame
- Overload Frame
Data Frame — это наиболее часто используемый тип сообщения. Он состоит из следующих основных частей:
- поле арбитража (arbitration field) определяет приоритет сообщения в случае, когда два или более узлов одновременно пытаются передать данные в сеть. Поле арбитража состоит в свою очередь из:
- для стандарта CAN-2.0A, 11-битного идентификатора + 1 бит RTR (retransmit)
- для стандарта CAN-2.0B, 29-битного идентификатора + 1 бит RTR (retransmit)
Следует отметить, что поле идентификатора, несмотря на свое название никак не идентифицирует само по себе ни узел в сети, ни содержимое поля данных. Для Data кадра бит RTR всегда выставлен в логический ноль (доминантный сигнал).
- поле данных (data field) содержит от 0 до 8 байт данных
- поле CRC (CRC field) содержит 15-битную контрольную сумму сообщения, которая используется для обнаружения ошибок
- слот подтверждения (Acknowledgement Slot) (1 бит), каждый CAN-контроллер, который правильно принял сообщение посылает бит подтверждения в сеть. Узел, который послал сообщение слушает этот бит, и в случае если подтверждение не пришло, повторяет передачу. В случае приема слота подтверждения передающий узел может быть уверен лишь в том, что хотя бы один из узлов в сети правльно принял его сообщение.
Рис. 2. Data frame стандарта CAN 2.0A.
Remote Frame — это Data Frame без поля данных и с выставленным битом RTR (1 — рецессивные бит). Основное предназначение Remote кадра — это инициация одним из узлов сети передачи в сеть данных другим узлом. Такая схема позволяет уменьшить суммарный трафик сети. Однако, на практике Remote Frame сейчас используется редко (например, в DeviceNet Remote Frame вовсе не используется).
Error Frame — это сообщение которое явно нарушает формат солобщения CAN. Передача такого сообщения приводит к тому, что все узлы сети регистрируют ошибку формата CAN-кадра, и в свою очередь автоматически передают в сеть Error Frame. Результатом этого процесса является автоматическая повторная передача данных в сеть передающим узлом. Error Frame состоит из поля Error Flag, которое состоит из 6 бит одинакового значения (и таким образом Error frame нарушает проверку Bit Stuffing, см. ниже), и поля Error Delimiter, состоящее из 8 рецессивных битов. Error Delimiter дает возможность другим узлам сети обнаружив Error Frame послать в сеть свой Error Flag.
Overload Frame — повторяет структуру и логику работы Error кадра, с той разницей, что он используется перегруженным узлом, который в данный момент не может обработать поступающее сообщение, и поэтому просит при помощи Overload-кадра о повторной передаче данных. В настоящее время Overload-кадр практически не используется.
Контроль доступа к среде передачи (побитовый арбитраж).
Поле арбитража CAN-кадра используется в CAN для разрешения коллизий доступа к шине методом не деструктивного арбитража. Суть метода не деструктивного арбитража заключается в следующем. В случае, когда несколько контроллеров начинают одновременную передачу CAN кадра в сеть, каждый из них сравнивает, бит, который собирается передать на шину с битом, который пытается передать на шину конкурирующий контроллер. Если значения этих битов равны, оба контроллера передают следующий бит. И так происходит до тех пор, пока значения передаваемых битов не окажутся различными. Теперь контроллер, который передавал логический ноль (более приоритетный сигнал) будет продолжать передачу, а другой (другие) контроллер прервёт свою передачу до того времени, пока шина вновь не освободится. Конечно, если шина в данный момент занята, то контроллер не начнет передачу до момента её освобождения.
Рис. 3. Побитовый арбитраж на шине CAN.
Методы обнаружения ошибок.
CAN протокол определяет пять способов обнаружения ошибок в сети:
- Bit monitoring
- Bit stuffing
- Frame check
- ACKnowledgement Check
- CRC Check
Bit monitoring — каждый узел во время передачи битов в сеть сравнивает значение передаваемого им бита со значением бита которое появляется на шине. Если эти значения не совпадают, то узел генерирует ошибку Bit Error. Естественно, что во время арбитража на шине (передача поля арбитража в шину) этот механизм проверки ошибок отключается.
Bit stuffing — когда узел передает последовательно в шину 5 бит с одинаковым значением, то он добавляет шестой бит с противоположным значением. Принимающие узлы этот дополнительный бит удаляют. Если узел обнаруживает на шине больше 5 последовательных бит с одинаковым значением, то он генерирует ошибку Stuff Error.
Frame Check — некоторые части CAN-сообщения имеют одинаковое значение во всех типах сообщений. Т.е. протокол CAN точно определяет какие уровни напряжения и когда должны появляться на шине. Если формат сообщений нарушается, то узлы генерируют ошибку Form Error.
ACKnowledgement Check — каждый узел получив правильное сообщение по сети посылает в сеть доминантный (0) бит. Если же этого не происходит, то передающий узел регистрирует ошибку Acknowledgement Error.
CRC Check — каждое сообщение CAN содержит CRC сумму, и каждый принимающий узел подсчитывает значение CRC для каждого полученного сообщения. Если подсчитанное значение CRC суммы, не совпадает со значением CRC в теле сообщения, принимающий узел генерирует ошибку CRC Error.
Механизм ограничения ошибок (Error confinement).
Каждый узел сети CAN, во время работы пытается обнаружить одну из пяти возможных ошибок. Если ошибка обнаружена, узел передает в сеть Error Frame, разрушая тем самым весь текущий трафик сети (передачу и прием текущего сообщения). Все остальные узлы обнаруживают Error Frame и принимают соответствующие действия (сбрасывают принятое сообщение). Кроме того, каждый узел ведет два счетчика ошибок: Transmit Error Counter (счетчик ошибок передачи) и Receive Error Counter (счетчик ошибок приема). Эти счетчики увеличиваются или уменьшаются в соответствие с несколькими правилами. Сами правила управления счетчиками ошибок достаточно сложны, но сводятся к простому принципу, ошибка передачи приводит к увеличению Transmit Error счетчика на 8, ошибка приема увеличивает счетчик Receive Error на 1, любая корректная передача/прием сообщения уменшают соответствующий счетчик на 1. Эти правила приводят к тому, что счетчик ошибок передачи передающего узла увеличивается быстрее, чем счетчик ошибок приема принимающих узлов. Это правило соответствует предположению о большой вероятности того, что источником ошибок является передающий узел.
Каждый узел CAN сети может находится в одном из трех состояний. Когда узел стартует он находится в состоянии Error Active. Когда, значение хотя бы одного из двух счетчиков ошибок превышает предел 127, узел переходит в состояние Error Passive. Когда значение хотя бы одного из двух счетчиков превышает предел 255, узел переходит в состояние Bus Off.
Узел находящийся в состоянии Error Active в случае обнаружения ошибки на шине передает в сеть Active Error Flags. Active Error Flags сотстоит из 6 доминантных бит, поэтому все узлы его регистрируют. Узел в состоянии Passive Error передает в сеть Passive Error Flags при обнаружении ошибки в сети. Passive Error Flags состоит из 6 рецессивных бит, поэтому остальные узлы сети его не замечают, и Passive Error Flags лишь приводит к увеличению Error счетчика узла. Узел в состоянии Bus Off ничего не передает в сеть (не только Error кадры, но вообще никакие другие).
Адресация и протоколы высокого уровня
В CAN не существует явной адресации сообщений и узлов. Протокол CAN нигде не указывает что поле арбитража (Identification field + RTR) должно использоваться как идентификатор сообщения или узла. Таким образом, идентификаторы сообщений и адреса узлов могут находится в любом поле сообщения (в поле арбитража или в поле данных, или присутствовать и там, и там). Точно также протокол не запрещает использовать поле арбитража для передачи данных.
Утилизация поля арбитража и поля данных, и распределение адресов узлов, идентификаторов сообщений и приоритетов в сети является предметом рассмотрений так называемых протоколов высокого уровня (HLP — Higher Layer Protocols). Название HLP отражает тот факт, что протокол CAN описывает только два нижних уровня эталонной сетевой модели ISO/OSI, а остальные уровни описываются протоколами HLP.
Рис. 4. Логическая структура протокола CAN.
Существует множество таких высокоуровневых протоколов. Наиболее распространенные из них это:
- DeviceNet
- CAL/CANopen
- SDS
- CanKingdom
Физичекий уровень протокола CAN
Физический уровень (Physical Layer) протокола CAN определяет сопротивление кабеля, уровень электрических сигналов в сети и т.п. Существует несколько физических уровней протокола CAN (ISO 11898, ISO 11519, SAE J2411).
В подавляющем большинстве случаев используется физический уровень CAN определенный в стандарте ISO 11898. ISO 11898 в качестве среды передачи определяет двухпроводную дифференциальную линию с импедансом (терминаторы) 120 Ом (допускается колебание импеданса в пределах от 108 Ом до 132 Ом. Физический уровень CAN реализован в специальных чипах — CAN приемо-передатчиках (transceivers), которые преобразуют обычные TTL уровни сигналов используемых CAN-контроллерами в уровни сигналов на шине CAN. Наиболее распространенный CAN приемо-передатчик — Phillips 82C250, который полностью соответствует стандарту ISO 11898.
Махимальная скорость сети CAN в соответствие с протоколом равна 1 Mbit/sec. При скорости в 1 Mbit/sec максимальная длина кабеля равна примерно 40 метрам. Ограничение на длину кабеля связано с конечной скоростью света и механизмом побитового арбитража (во время арбитража все узлы сети должны получать текущий бит передачи одновременно, те сигнал должен успеть распространится по всему кабелю за единичный отсчет времени в сети. Соотношение между скоростью передачи и максимальной длиной кабеля приведено в таблице:
скорость передачи | максимальная длина сети |
1000 Кбит/сек | 40 метров |
500 Кбит/сек | 100 метров |
250 Кбит/сек | 200 метров |
125 Кбит/сек | 500 метров |
10 Кбит/сек | 6 километров |
Разъемы для сети CAN до сих пор НЕ СТАНДАРТИЗОВАНЫ. Каждый протокол высокого уровня обычно определяет свой тип разъемов для CAN-сети.
Один из немаловажных аспектов работы CAN шины является обработка прерываний bxCan. Их не так уж и много, но при правильной их настройке и обработке мы сможем обеспечить максимальную работоспособность и высокую отказоустойчивость нашего устройства. Поэтому следует обратить наше внимание на то, как это сделать правильно — создать необходимый минимум.
Теория
Начнем опять с теории и обратимся к Reference Maanual от ST Microelectronics.
Для начала мы попытаемся разобраться с механизмом прерываний микроконтроллера STM32F103C6, затем пройдемся по регистрам контроллера и, затем, выстроим некий шаблон, который мы сможем использовать в своих проектах.
Прерывания
Для bxCan может быть назначено четыре прерывания. Каждый из источников прерываний может быть включен или выключен независимо друг от друга в регистре CAN_IER (CAN Interrupt Enable Register).
Вот схема отработки прерываний приведенная в мануале:
Рис. 1. Флаги событий и формирование прерываний
Как видим на рисунке 1, прерывания сгруппированы в четыре группы:
• Transmit interrupt (Прерывание при передаче сообщения) — может быть вызвано следующими событиями:
— Выполнена передача и освобожден mailbox 0. Бит RQCP0 в регистре CAN_TSR установлен;
— Выполнена передача и освобожден mailbox 1. Бит RQCP1 в регистре CAN_TSR установлен;
— Выполнена передача и освобожден mailbox 2. Бит RQCP2 в регистре CAN_TSR установлен.
• FIFO0 interrupt (Прерывание связанное с входящим буфером FIFO0) — вызывается по следующим событиям:
— Прием нового сообщения, биты FMP0 в регистре CAN_RF0R не равны «00». В принципе значение этого регистра говорит нем о том, сколько сообщений в буфере FIFO еще не обработано программой;
— Буфер FIFO0 заполнен. Бит FULL0 в регистре CAN_RF0R установлен — сообщает нам о том, что в буфере FIFO0 больше нет свободного места;
— Переполнение буфера FIFO0. Бит FOVR0 в регистре CAN_RF0R установлен — возникает в случае когда буфер FIFO0 заполнен и по шине принято еще одно сообщение. Что с этим сообщением произойдет, мы указываем в настройках инициализации CAN (параметр CAN_RFLM).
• FIFO1 interrupt (Прерывание связанное с входящим буфером FIFO1) — вызывается по следующим событиям:
— Прием нового сообщения, биты FMP1 в регистре CAN_RF1R не равны «00». В принципе значение этого регистра говорит нем о том, сколько сообщений в буфере FIFO еще не обработано программой;
— Буфер FIFO1 заполнен. Бит FULL1 в регистре CAN_RF0R установлен — сообщает нам о том, что в буфере FIFO1 больше нет свободного места;
— Переполнение буфера FIFO1. Бит FOVR1 в регистре CAN_RF0R установлен — возникает в случае когда буфер FIFO1 заполнен и по шине принято еще одно сообщение. Что с этим сообщением произойдет, мы указываем в настройках инициализации CAN (параметр CAN_RFLM).
• Error and Status change Interrupt (Прерывание по возникновению ошибок и изменению состояния bxCAN) — вызывается по следующим событиям:
— Возникновение ошибки. Информация об ошибке хранится в регистре CAN Error (CAN_ESR);
— «Просыпание» контроллера — выход из режима сна, когда на Rx появился сигнал CAN шины;
— Переход в спящий режим.
Четвертая группа отвечает за прерывания не только ошибок, но, как видно из названия, и за изменения статуса (режима) bxCan.
Регистры
Полное описание регистров bxCan я приведу в отдельной статье, здесь же мы коснемся лишь некоторых из них, которые непосредственно рассматриваются в рамках данной статьи.
Для того, чтобы мы смогли программно обработать прерывания bxCan, необходимо изучить регистры микроконтроллера, которые непосредственно связаны с этими прерываниями. Разработчики ST Microelectronix постарались для нас и большинство функционала для работы CAN шины возложили на аппаратную часть микроконтроллера, но все же нам придется выполнить некоторые действия самостоятельно.
За обработку ошибок, включение/выключение прерываний CAN шины, а также за информацию о текущем статусе шины и ошибок в bxCan отвечают шесть регистров, которые мы сейчас и изучим:
CAN master status register (CAN_MSR)
Один из основных регистров bxCAN. Он отображает текущее состояние CAN устройства и позволяет программному обеспечению контролировать более детально работу bxCan.
В большинстве случаев нет необходимости досконально контролировать аппаратную часть, сама bxCan превосходно с этим справляется, но в некоторых случаях будет полезно понимать предоставленные нам возможности и инструменты.
CAN Master Status Register предоставляет нам информацию о том, в каком состоянии находится bxCan и сообщает нам о прерываниях, если они установлены.
Рис. 2. CAN master status register.
Address offset: 0x04
Reset value: 0x0000 0C02
Биты | Название | Описание |
---|---|---|
31:12 | Зарезервировано | |
11 | RX — CAN Rx signal | CAN Rx сигнал. Контролирует фактическое состояние пина CAN_Rx |
10 | SAMP — Last sample point | Последнее принятое значение. Значение RX на последней точки выборки (фактически значение последнего принятого бита). |
9 | RXM — Receive mode | Режим передачи. Сообщает, что bxCan находится в режиме передачи сообщения. |
8 | TXM — Transmit mode | Режим приема. Сообщает, что bxCan находится в режиме приема сообщения. |
7:5 | Зарезервировано | |
4 | SLAKI — Sleep acknowledge interrupt | Бит прерывания при переходе в спящий режим. Когда SLKI = 1, то этот бит устанавливается аппаратно и сигнализирует о том, что bxCan вошел в режим «спячки». После установки этого бита генерируется прерывание по переходу в спящий режим (если установлен бит SLKIE в регистре CAN_IER). SLAKI может сбрасываться программно или аппаратно, когда сбрасывается бит SLAK. Примечание: когда бит SLKIE = 0, то нельзя выполнить опрос бита SLAKI. В этом случае необходимо читать значение бита SLAK. |
3 | WKUI — Wakeup interrupt | Бит прерывания при возврате из «спящего» режима. Этот бит аппаратно устанавливает сигнал о том, что бит SOF был обнаружен, в то время, как bxCan находился в спящем режиме. Установка этого бита генерирует изменение статуса прерывания, если бит WKUIE регистра CAN_IER был установлен. Сбрасывается этот бит с помощью программного обеспечения. |
2 | ERRI — Error interrupt | Бит прерывание по ошибке. Этот бит устанавливается аппаратно, когда бит в регистре CAN_ESR был установлен на обнаружение ошибок и при этом включено соответствующее прерывание в регистре CAN_IER. Установка этого бита генерирует прерывание, если установлен бит ERRIE в регистре CAN_IER. Очищается с помощью программного обеспечения. |
1 | SLAK — Sleep acknowledge | Режим сна. Этот бит устанавливается аппаратно и указывает на то, что bxCan находится в режиме сна. Этот бит подтверждает запрос о переходе в «спящий» режим из программного обеспечения (установка бита Sleep в регистре CAN_MCR). Сбрасывается аппаратно, когда bxCan переходит в спящий режим (для синхронизации по CAN — шине). Для синхронизации устройств на шине необходимо контролировать последовательность 11-ти рецессивных бит подряд на сигнале CAN_RX. Процесс выхода из сна запускается, когда сбрасывается бит SLEEP в регистре CAN_MCR. Автоматическое пробуждение из режима сна происходит при установке бита AWUM регистра CAN_MCR. |
0 | INAK — Initialization acknowledge | Режим инициализации. Этот бит устанавливается аппаратно и указывает программному обеспечению на то, что bxCan находится в режиме инициализации. Этот бит подтверждает запрос инициализации из программного обеспечения (установлен бит INRQ в регистре CAN_MCR). Бит INAK сбрасывается автоматически, когда bxCan выходит из режима инициализации. Для того чтобы синхронизировать устройства с шиной, необходимо контролировать последовательность 11 рецессивных бит подряд на CAN_RX. |
CAN transmit status register (CAN_TSR)
Этот регистр позволяет нам узнать текущее состояние передачи данных в шину. Из него мы можем получить информацию о количестве исходящих сообщений, заполненности почтовых ящиков, узнать о том, отправлено ли нами сообщение или произошла ошибка, а также позволяет нам прервать отправку пакета, если мы почему-то передумали это делать.
Рис. 3. CAN transmit status register.
Address offset: 0x08
Reset value: 0x1C00 0000
Биты | Название | Описание |
---|---|---|
31 | LOW2 — Lowest priority flag for mailbox 2 | Наименьший приоритет для почтового ящика №2. Этот бит устанавливается аппаратно, когда более чем один почтовый ящик находится в обработке, а сообщение в почтовом ящике №2 имеет наименьший приоритет. |
30 | LOW1 — Lowest priority flag for mailbox 1 | Наименьший приоритет для почтового ящика №1. Этот бит устанавливается аппаратно, когда более чем один почтовый ящик находится в обработке, а сообщение в почтовом ящике №1 имеет наименьший приоритет. |
29 | LOW0 — Lowest priority flag for mailbox 0 | Наименьший приоритет для почтового ящика №0. Этот бит устанавливается аппаратно, когда более чем один почтовый ящик находится в обработке, а сообщение в почтовом ящике №0 имеет наименьший приоритет. Примечание: Биты LOW[2:0] устанавливаются в ноль, когда только один почтовый ящик находится на обработке. |
28 | TME2 — Transmit mailbox 2 empty | Почтовый ящик №2 пуст. Этот бит устанавливается аппаратно, когда нет запроса на обработку почтового ящика №2. |
27 | TME1 — Transmit mailbox 1 empty | Почтовый ящик №1 пуст. Этот бит устанавливается аппаратно, когда нет запроса на обработку почтового ящика №1. |
26 | TME0 — Transmit mailbox 0 empty | Почтовый ящик №0 пуст. Этот бит устанавливается аппаратно, когда нет запроса на обработку почтового ящика №0. |
25:24 | CODE[1:0] — Mailbox code | Код почтового ящика. В случае, когда по меньшей мере освобождается один почтовый ящик, значение CODE содержит номер следующего почтового ящика в очереди с наименьшим приоритетом. |
23 | ABRQ2 — Abort request for mailbox 2 | Прервать запрос на обработку почтового ящика №2. Устанавливается программно с целью прервать передачу из почтового ящика №2. Сбрасывается автоматически после того, как bxCan очищает почтовый ящик. Установка этого бита не имеет никакого значения, если почтовый ящик не задерживается для передачи. |
22:20 | Зарезервировано | |
19 | TERR2 — Transmission error of mailbox 2 | Ошибка передачи для почтового ящика №2. Устанавливается, когда произошла ошибка при передаче сообщения из этого почтового ящика. |
18 | ALST2 — Arbitration lost for mailbox 2 | Потеря арбитража для почтового ящика №2. Бит устанавливается, если при передачи сообщения устройство проиграла арбитраж. |
17 | TXOK2 — Transmission OK of mailbox 2 | Завершение передачи для почтового ящика №2. bxCan обновляет этот бит после каждой попытки передачи из почтового ящика и устанавливает следующие значения: 0 — передача не удалась; 1 — передача была успешной. Этот бит устанавливается аппаратно, когда успешно завершен запрос передачи для почтового ящика №2. |
16 | RQCP2 — Request completed mailbox2 | Завершен запрос на передачу для почтового ящика №2. Устанавливается аппаратно, когда был выполнен последний запрос (передан или прерван). Очищается программно путем установки бита в «1» или аппаратно по факту завершения передачи (установка бита TXRQ2 в регистре CAN_TI2R). Очистка этого бита сбрасывает все виды состояния для почтового ящика №2 (TXOK2, ALST2 и TERR2). |
15 | ABRQ1 — Abort request for mailbox 1 | Прервать запрос на обработку почтового ящика №1. Устанавливается программно с целью прервать передачу из почтового ящика №1. Сбрасывается автоматически после того, как bxCan очищает почтовый ящик. Установка этого бита не имеет никакого значения, если почтовый ящик не задерживается для передачи. |
14:12 | Зарезервировано | |
11 | TERR1 — Transmission error of mailbox1 | Ошибка передачи для почтового ящика №2. Устанавливается, когда произошла ошибка при передаче сообщения из этого почтового ящика. |
10 | ALST1 — Arbitration lost for mailbox1 | Потеря арбитража для почтового ящика №1. Бит устанавливается, если при передачи сообщения устройство проиграла арбитраж. |
9 | TXOK1 — Transmission OK of mailbox1 | Завершение передачи для почтового ящика №1. bxCan обновляет этот бит после каждой попытки передачи из почтового ящика и устанавливает следующие значения: 0 — передача не удалась; 1 — передача была успешной. Этот бит устанавливается аппаратно, когда успешно завершен запрос передачи для почтового ящика №1. |
8 | RQCP1 — Request completed mailbox1 | Завершен запрос на передачу для почтового ящика №1. Устанавливается аппаратно, когда был выполнен последний запрос (передан или прерван). Очищается программно путем установки бита в «1» или аппаратно по факту завершения передачи (установка бита TXRQ1 в регистре CAN_TI1R). Очистка этого бита сбрасывает все виды состояния для почтового ящика №1 (TXOK1, ALST1 и TERR1). |
7 | ABRQ0 — Abort request for mailbox0 | Прервать запрос на обработку почтового ящика №0. Устанавливается программно с целью прервать передачу из почтового ящика №0. Сбрасывается программно после того, как bxCan очищает почтовый ящик. Установка этого бита не имеет никакого значения, если почтовый ящик не задерживается для передачи. |
6:4 | Зарезервировано | |
3 | TERR0 — Transmission error of mailbox0 | Ошибка передачи для почтового ящика №0. Устанавливается, когда произошла ошибка при передаче сообщения из этого почтового ящика. |
2 | ALST0 — Arbitration lost for mailbox0 | Потеря арбитража для почтового ящика №0. Бит устанавливается, если при передачи сообщения устройство проиграла арбитраж. |
1 | TXOK0 — Transmission OK of mailbox0 | Завершение передачи для почтового ящика №0. bxCan обновляет этот бит после каждой попытки передачи из почтового ящика и устанавливает следующие значения: 0 — передача не удалась; 1 — передача была успешной. Этот бит устанавливается аппаратно, когда успешно завершен запрос передачи для почтового ящика №0. |
0 | RQCP0 — Request completed mailbox0 | Завершен запрос на передачу для почтового ящика №0. Устанавливается аппаратно, когда был выполнен последний запрос (передан или прерван). Очищается программно путем установки бита в «1» или аппаратно по факту завершения передачи (установка бита TXRQ0 в регистре CAN_TI0R). Очистка этого бита сбрасывает все виды состояния для почтового ящика №0 (TXOK0, ALST0 и TERR0). |
Как правило необходимости напрямую обращаться к этому регистру у нас не будет — можно полностью доверится bxCan. Я вижу потребность в его чтении только в очень сложных проектах, где часть функционала ложится не только на аппаратную часть, но и на программную. Также может потребоваться в случаях, когда необходимо использовать парсер CAN-шины — необходимо более детальное изучение ошибок передачи данных, логирование всего и вся.
Для обработки прерываний передачи сообщений необходимо разрешить прерывание при отправке почтового сообщения (CAN_IT_TME) и, соответственно, добавить это обработчик этого прерывания в тело программы (USB_HP_CAN1_TX_IRQHandler()).
CAN receive FIFO 0 register (CAN_RF0R)
Первый из двух регистров, отвечающих за буфер входящих сообщений FIFO 0.
Из этого регистра мы можем узнать количество почтовых сообщений, а также текущее состояние буфера FIFO 0.
Рис. 4. CAN receive FIFO 0 register.
Address offset: 0x0C
Reset value: 0x0000 0000
Биты | Название | Описание |
---|---|---|
31:6 | Зарезервировано | |
5 | RFOM0 — Release FIFO 0 output mailbox | Буфер FIFO0 освобожден. Устанавливается программно, чтобы освободить (очистить) почтовые ящики буфера FIFO0. Выходной почтовый ящик буфера может быть освобожден только в том случае, если на обработке FIFO0 имеется хотя бы одно сообщение. Устанавливать этот бит, когда FIFO0 пуст — не имеет никакого смысла. Очищается автоматически с помощью аппаратных средств, когда обработаны все сообщения, находящиеся в почтовых ящиках буфера FIFO0. |
4 | FOVR0 — FIFO 0 overrun | Буфер FIFO0 переполнен. Этот бит устанавливается аппаратными средствами, когда получено новое сообщение, но буфер FIFO0 уже заполнен. Этот бит необходимо сбрасывать программно. |
3 | FULL0 — FIFO 0 full | Буфер FIFO0 заполнен. Устанавливается аппаратно, когда заполнены все три почтовых ящика буфера FIFO0 Этот бит необходимо сбрасывать программно. |
2 | Зарезервировано | |
1:0 | FMP0[1:0] — FIFO 0 message pending | Количество сообщений в буфере FIFO0. Эти биты указывают, сколько сообщений находится на обработке в буфере FIFO0. FMP увеличивается каждый раз, когда поступает новое сообщение и уменьшается, после обработки каждого сообщения буфера. |
Обработка прерываний для буфера FIFO 0 происходит в функции USB_LP_CAN1_RX0_IRQHandler(). В ней необходимо обработать получение почтовых сообщений, а также проверить состояние ошибок (заполнение или переполнение буфера FIFO 0). Естественно, необходимо включить эти прерывания при настройке bxCan.
Необходимо помнить, что биты FOVR0 и FULL0 сбрасываются вручную.
CAN receive FIFO 1 register (CAN_RF1R)
А это второй регистр, предназначенный для чтения состояния буфера входящих сообщений, но уже для FIFO 1.
Из него мы также можем почерпнуть информацию о том, сколько сообщений у нас хранится и текущий статус самого буфера FIFO 1.
Рис. 5. CAN receive FIFO 1 register.
Address offset: 0x10
Reset value: 0x0000 0000
Биты | Название | Описание |
---|---|---|
31:6 | Зарезервировано | |
5 | RFOM1 — Release FIFO 1 output mailbox | Буфер FIFO1 освобожден. Устанавливается программно, чтобы освободить (очистить) почтовые ящики буфера FIFO1. Выходной почтовый ящик буфера может быть освобожден только в том случае, если на обработке FIFO1 имеется хотя бы одно сообщение. Устанавливать этот бит, когда FIFO1 пуст — не имеет никакого смысла. Очищается автоматически с помощью аппаратных средств, когда обработаны все сообщения, находящиеся в почтовых ящиках буфера FIFO1. |
4 | FOVR1 — FIFO 1 overrun | Буфер FIFO1 переполнен. Этот бит устанавливается аппаратными средствами, когда получено новое сообщение, но буфер FIFO1 уже заполнен. Этот бит необходимо сбрасывать программно. |
3 | FULL1 — FIFO 1 full | Буфер FIFO1 заполнен. Устанавливается аппаратно, когда заполнены все три почтовых ящика буфера FIFO1 Этот бит необходимо сбрасывать программно. |
2 | Зарезервировано | |
1:0 | FMP1[1:0] — FIFO 1 message pending | Количество сообщений в буфере FIFO1. Эти биты указывают, сколько сообщений находится на обработке в буфере FIFO1. FMP увеличивается каждый раз, когда поступает новое сообщение и уменьшается, после обработки каждого сообщения буфера. |
Для обработки прерываний для буфера FIFO 1 необходимо включить обработку этих прерываний при настройке bxCan и вставить в модуль функцию CAN1_RX1_IRQHandler(). Также как и с буфером FIFO 0, мы можем в обработчике прерываний выполнить обработку получения почтового сообщения в буфер FIFO 1, а также проверить состояние ошибок буфера и сбросить их после обработки.
Также напомню о необходимости сбрасывать биты FOVR1 и FULL1 вручную.
CAN interrupt enable register (CAN_IER)
Мы добрались до регистра, который непосредственно отвечает за включение прерываний bxCAN. Установив необходимые нам биты, мы сможем выполнить обработку прерываний. Напомню, что включение прерываний само по себе недостаточно, необходимо еще и включить сами прерывания и добавить их обработчики в тело программы, иначе наша программа при возникновении прерывания перейдет в прерывание по умолчанию и просто «зависнет». Но об этом поговорим чуть ниже, где я приведу несколько примеров.
Итак, нам необходимо включить прерывания. Сделать это мы можем установив соответствующие биты в регистре CAN interrupt enable register (CAN_IER).
Рис. 6. CAN interrupt enable register.
Address offset: 0x14
Reset value: 0x0000 0000
Биты | Название | Описание |
---|---|---|
31:18 | Зарезервировано | |
17 | SLKIE — Sleep interrupt enable | Прерывание при переходе в спящий режим. Вызывается, когда bxCan переходит в «спящий» режим при установленном бите SLAKI регистра CAN_MSR. 0: Прерывание не генерируется 1: Прерывание генерируется |
16 | WKUIE — Wakeup interrupt enable | Прерывание при выходе из спящего режима. Вызывается, когда bxCan выходит из спящего режима при установленном бите WKUI регистра CAN_MSR. 0: Прерывание не генерируется 1: Прерывание генерируется |
15 | ERRIE — Error interrupt enable | Прерывание при возникновении ошибки. 0: Прерывание не генерируется 1: Генерируется прерывание когда есть описание ошибки в регистре CAN_ESR. |
14:12 | Зарезервировано | |
11 | LECIE — Last error code interrupt enable | Прерывание при возникновении ошибки приема-передачи. Вызывается, когда установлены биты LEC[2:0] (регистр CAN_ESR) аппаратной частью bxCan. 0: Бит ERRI не будет установлен 1: Бит ERRI будет установлен при обнаружении ошибки на шине. |
10 | BOFIE — Bus-off interrupt enable | Прерывание при переходе в режим Bus-Off. Вызывается при переходе bxCan в режим Bus-Off при установленном бите BOFF регистра CAN_ESR. 0: Бит ERRI не будет установлен 1: Бит ERRI будет установлен |
9 | EPVIE — Error passive interrupt enable | Прерывание при достижении пассивного уровня ошибок. Вызывается когда счетчики ошибок приема или передачи превышают значение 127 при установленном бите EPVF регистра CAN_ESR. 0: Бит ERRI не будет установлен 1: Бит ERRI будет установлен |
8 | EWGIE — Error warning interrupt enable | Прерывание при достижении предупреждающего уровня ошибок. Вызывается когда счетчики ошибок приема или передачи превышают либо равны значению 96 при установленном бите EWGF. 0: Бит ERRI не будет установлен 1: Бит ERRI будет установлен |
7 | Зарезервировано | |
6 | FOVIE1 — FIFO overrun interrupt enable | Прерывание при переполнении буфера FIFO1. Вызывается, когда буфер FIFO1 заполнен и получено еще один пакет данных при установленном бите FOVR регистра CAN_RF1R. 0: Прерывание не генерируется 1: Генерируется прерывание |
5 | FFIE1 — FIFO full interrupt enable | Прерывание при заполнении буфера FIFO1. Вызывается когда в буфере FIFO1 заполнены все три почтовых ящика при установленном бите FULL регистра CAN_RF1R. 0: Прерывание не генерируется 1: Генерируется прерывание |
4 | FMPIE1 — FIFO message pending interrupt enable | Прерывание при получении пакета из шины. Вызывается когда в буфер FIFO1 получено очередное сообщение (при значении бита FMP[1:0] регистра CAN_RF1R не равном 00b). 0: Прерывание не генерируется 1: Генерируется прерывание |
3 | FOVIE0 — FIFO overrun interrupt enable | Прерывание при переполнении буфера FIFO0. Вызывается, когда буфер FIFO0 заполнен и получено еще один пакет данных при установленном бите FOVR регистра CAN_RF0R. 0: Прерывание не генерируется 1: Генерируется прерывание |
2 | FFIE0 — FIFO full interrupt enable | Прерывание при заполнении буфера FIFO0. Вызывается когда в буфере FIFO0 заполнены все три почтовых ящика при установленном бите FULL регистра CAN_RF0R. 0: Прерывание не генерируется 1: Генерируется прерывание |
1 | FMPIE0 — FIFO message pending interrupt enable | Прерывание при получении пакета из шины. Вызывается когда в буфер FIFO0 получено очередное сообщение (при значении бита FMP[1:0] регистра CAN_RF0R не равном 00b). 0: Прерывание не генерируется 1: Генерируется прерывание |
0 | TMEIE — Transmit mailbox empty interrupt enable | Прерывание при освобождении исходящего почтового ящика. Вызывается при окончании передачи сообщения при установленном бите RQCPx регистра CAN_TSR. 0: Прерывание не генерируется 1: Генерируется прерывание |
Если Вы новичок и только начинаете изучать протокол CAN и его использование на микроконтроллерах семейства STM32, то можно ограничиться одним прерыванием FMPIE0 (FIFO 0 message pending interrupt) и TMEIE (Transmit mailbox empty interrupt), которые отвечает за обработку получения входящего пакета в буфер FIFO 0, а также за обработку окончания отправки пакета в шину соответственно. Для первоначального изучения и тестирования этого вполне хватит, а дальше уже требуется более глубокое понимание физики процессов и специфики работы CAN шины.
CAN error status register (CAN_ESR)
Регистр отвечает за состояние ошибок при работе с bxCan.
Управление ошибками, как описано в протоколе CAN, обрабатывается полностью аппаратными средствами с помощью счетчиков ошибок передачи (TEC — Transmit error counter) и счетчиков ошибок приема сообщений (REC — Receive error counter), которые увеличивают или уменьшают свое значение в соответствии с состоянием ошибки.
Оба счетчика могут быть прочитаны с помощью программного обеспечения, чтобы определить стабильность сети.
Кроме того, аппаратное обеспечение может предоставлять более подробную информацию о текущем состоянии ошибок (LEC — Last error code).
Рис. 7. CAN error status register.
Address offset: 0x18
Reset value: 0x0000 0000
Биты | Название | Описание |
---|---|---|
31:24 | REC[7:0] — Receive error counter | Счетчик ошибок приема пакетов. Исполняющая часть механизма контроля состояния протокола CAN. В случае возникновения ошибки во время приема пакета, этот счетчик увеличивается на 1 или на 8 в зависимости от состояния ошибки (по определению стандарта CAN). После каждого успешного приема счетчик уменьшается на единицу или сбрасывается до 120, если его значение было выше, чем 128. Если значение счетчика превышает 127, то контроллер bxCan переходит в пассивное состояние ошибки (устанавливается бит EPVF). |
23:16 | TEC[7:0] — Transmit error counter | Счетчик ошибок передачи пакетов. Аналогично REC, только для ошибок передачи. |
15:17 | Зарезервировано | |
6:4 | LEC[2:0] — Last error code | Код последней ошибки. Это поле устанавливается аппаратно и содержит значение, которое указывает на вид последней ошибки, обнаруженной на CAN шине. Если сообщение было передано или получено без ошибок, то значение этих битов будет сброшено в ноль. Также программно можно установить эти биты в значение 0b111, что указывает, что ошибка установлена с помощью программного обеспечения. Коды ошибок: 000 — Нет ошибок 001 — Stuff error 010 — Form error 011 — Acknowledgment Error 100 — Bit recessive Error 101 — Bit dominant Error 110 — CRC Error 111 — Set by software Описание ошибок приведено ниже в таблице №4. |
3 | Зарезервировано | |
2 | BOFF — Bus-off flag | Bus-off флаг. Этот бит устанавливается, когда bxCan переходит в режим Bus-off. Режим Bus-off вводится, когда счетчик ошибок передачи (TEC) становится больше чем 255. |
1 | EPVF — Error passive flag | Флаг пассивной ошибки. Этот бит устанавливается аппаратно, когда достигнут пассивный предел счетчиков ошибок (Счетчик приема и/или передачи больше 127). |
0 | EWGF — Error warning flag | Флаг предупреждения об ошибках. Бит устанавливается аппаратно, когда достигнут предел предупреждения (Счетчик ошибок приема и/или передачи ≥ 96). |
Согласно описанию протокола CAN принято увеличивать счетчик ошибок REC (Receive error counter) на одну единицу при каждой обнаруженной ошибке приема на шине, а счетчик ошибок TEC (Transmit error counter) увеличивать на 8 при каждой ошибке передачи пакетов. Это связано стем, что существует предположение о том, что с наибольшей вероятностью источником ошибок на шине является передающий узел.
Уменьшение счетчика ошибок происходит автоматически на единицу при каждом успешном приеме или передаче сообщений по шине для счетчиков REC и TEC соответственно.
Восстановление BUS-OFF
Состояние шины Bus-Off устанавливается, когда счетчик ошибок передачи превышает 255, при этом устанавливается бит BOFF регистра CAN_ESR. В этом режиме bxCan фактически перестает принимать и передавать пакеты по шине.
При настройке bxCAN можно установить бит ABOM, который отвечает за то, что если шина перейдет в режим Bus-off, то bxCan автоматически начнет проверять сигнал CAN_RX для восстановления шины. Если бит ABOM не установлен, то разработчику необходимо контролировать этот процесс самостоятельно и в случае возникновения ошибки и перехода в режим Bus-off необходимо заново проинициализировать bxCan.
Обратите внимание, что bxCan слушает порт CAN_RX только в нормальном режиме работы. Если bxCan находится в режиме инициализации, то автоматического восстановления шины не произойдет.
Долгое время не мог понять, что это за 11 рецессивных бит 128 раз подряд и где их необходимо взять и куда подать. Путем гугления и раскурки мануалов понял, что это указывается время, через которое контроллер CAN шины автоматически выйдет из режима Bus-Off и оно равно времени, которое потребуется для передачи 11 рецессивных бит 128 раз подряд.
Другими словами, контроллер автоматически выйдет из режима Bus-Off, когда на CAN шине будет «тишина» в течении времени, равному времени передачи 11 бит * 128 раз. Естественно, если в настройках контроллера мы ему указали, что он может автоматически выходить из этого режима (установлен бит ABOM регистра CAN_MCR).
Практика
Вроде все моменты, которые касаются обработки прерываний bxCan мы рассмотрели. Текста очень много, но как это применить на практике?
Давайте разбираться.
Для начала нам необходимо определится с тем, какие прерывания bxCan мы будем использовать. Конечно можно ограничиться прерыванием на получение сообщения в буфер FIFO, но мы же не ищем легких путей, поэтому проинициализируем сразу все.
За включение/отключение прерываний bxCan отвечает функция CAN_ITConfig, эти действия выполняются в модуле инициализации can шины совместно с настройкой прерываний NVIC:
Листинг №1. Включение прерываний bxCan
// CAN Transmit mailbox empty Interrupt enable
// Обрабатывается в прерывании USB_HP_CAN1_TX_IRQHandler
CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE); // Прерывание при освобождении исходящего почтового ящика
// CAN Receive Interrupt enable
// Обрабатывается в прерывании USB_LP_CAN1_RX0_IRQHandler
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); // Прерывание получения пакета в буфер FIFO 0
CAN_ITConfig(CAN1, CAN_IT_FF0, ENABLE); // Прерывание при заполнении буфера FIFO 0
CAN_ITConfig(CAN1, CAN_IT_FOV0, ENABLE); // Прерывание при переполнении буфера FIFO 0
// Обрабатывается в прерывании CAN1_RX1_IRQHandler
CAN_ITConfig(CAN1, CAN_IT_FMP1, ENABLE); // Прерывание получения пакета в буфер FIFO 1
CAN_ITConfig(CAN1, CAN_IT_FF1, ENABLE); // Прерывание при заполнении буфера FIFO 1
CAN_ITConfig(CAN1, CAN_IT_FOV1, ENABLE); // Прерывание при переполнении буфера FIFO 1
// CAN Operating Mode Interrupt enable
// Обрабатывается в прерывании CAN1_SCE_IRQHandler
CAN_ITConfig(CAN1, CAN_IT_WKU, ENABLE); // Прерывание при "пробуждении" - выход из "спящего" режима
CAN_ITConfig(CAN1, CAN_IT_SLK, ENABLE); // Прерывание при переходе в "спящий" режим
// CAN Error Interrupts
// Обрабатывается в прерывании CAN1_SCE_IRQHandler
CAN_ITConfig(CAN1, CAN_IT_EWG, ENABLE); // Error warning Interrupt (error counter >= 96)
CAN_ITConfig(CAN1, CAN_IT_EPV, ENABLE); // Error passive Interrupt (error counter > 127)
CAN_ITConfig(CAN1, CAN_IT_BOF, ENABLE); // Bus-off Interrupt (error counter > 255)
CAN_ITConfig(CAN1, CAN_IT_LEC, ENABLE); // Last error code - при возникновении ошибок приема-передачи
CAN_ITConfig(CAN1, CAN_IT_ERR, ENABLE); // Прерывание при возникновении ошибок bxCan
// NVIC Configuration
NVIC_InitTypeDef NVIC_InitStructure;
// Enable CAN1 TX0 interrupt IRQ channel
NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable CAN1 RX0 interrupt IRQ channel
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable CAN1 RX1 interrupt IRQ channel
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable CAN1 SCE (Status Change Error) interrupt IRQ channel
NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
После того, как с помощью функции CAN_ITConfig() мы проинициализировали необходимые нам прерывания, необходимо включить обработчики этих прерываний. Делается это через NVIC. Если мы забудем хотя бы одно из них включить, то микроконтроллер при возникновении прерывания, которое мы забыли обработать, выкинет нас в стандартный обработчик прерываний и просто зависнет. Поможет только перезагрузка процессора, так как он будет сидеть в «вечном» цикле и ни на что больше реагировать не будет.
А теперь, чтобы этого не произошло, нам необходимо вставить в наш программный код функции обработки прерываний. Всего их четыре: прерывание при освобождении исходящего почтового ящика, два прерывания для буферов FIFO 1 и 2, а также прерывание по обработке ошибок и входа/выхода в «режим сна».
Обработка прерываний при освобождении исходящего почтового ящика
За обработку прерывания при освобождении исходящего почтового ящика отвечает функция USB_HP_CAN1_TX_IRQHandler(). Нам необходимо проверить флаг прерывания и, если он установлен, сбросить его и выполнить код обработки прерывания:
Листинг №2. Обработка прерываний bxCan для исходящего почтового ящика
void USB_HP_CAN1_TX_IRQHandler(void)
{
// CAN Transmit mailbox empty Interrupt enable
// Обработаем прерывания при освобождении исходящего почтового ящика
if (CAN_GetITStatus(CAN1, CAN_IT_TME)==SET) { // Прерывание при освобождении исходящего почтового ящика
CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
// Вставляем свой код по обработке прерывания
}
}
Функция CAN_GetITStatus() возвращает текущее состояние флага прерывания, значение может быть равным SET или RESET («Установлен» или «сброшен» соответственно). Значение SET говорит нам о том, что бит установлен и нам необходимо обработать это прерывание и не забыть сбросить его флаг.
Следует помнить о том, что необходимо всегда производить сброс флага прерывания, иначе оно будет вызываться постоянно. Исключение составляют только флаги прерываний ошибок, они почти все сбрасываются аппаратно, подробнее можно посмотреть в описании функции CAN_ClearITPendingBit().
Проверять освобождение исходящего почтового ящика имеет смысл, если Вы пересылаете большой объем данных по Can-шине: при обработке отправки сообщения выставляется флаг отправки сообщения, а в прерывании проверяется была выполнена отправка данных или нет. Если отправка была завершена без ошибок, то устанавливаем в флаг значение без ошибок и отправляем следующий пакет данных, иначе устанавливаем в флаг код ошибки и обрабатываем ее в модуле программы.
Несмотря на то, что исходящих почтовых ящиков у нас три, проверять отправку сообщений я все же рекомендую, иначе вполне вероятны ситуации, когда в результате проигрыша арбитража или возникновении ошибок на линии bxCan не сможет отправить сообщения, а мы в этот момент, не проверив статус отправки, будем давать ему новые на отправку. Возникнет сбой, который нам не нужен.
Проверить статус отправки сообщения можно не только с помощью прерываний, но и в момент отправки сообщения (это наверное самый оптимальный вариант):
Листинг №3. Отправка сообщения с проверкой статуса отправки
uint32_t i = 0;
uint8_t TransmitMailbox = 0;
...
TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);
i = 0;
while ((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFF)) {
i++;
}
При передаче сообщения через функцию CAN_Transmit, она нам возвращает номер исходящего почтового ящика, в который помещено сообщение. Затем мы в цикле проверяем, отправил ли bxCan наше сообщение или нет. Если отправка прошла успешно, то статус отправки сообщения из почтового ящика будет равен CANTXOK.
По окончанию цикла while() проверяем значение переменной «i». Если оно у нас равно 0xFF, значит отправка не удалась и тут мы уже думаем что сделать: то ли сбросить отправку сообщения, то ли обработать ошибку.
Вообщем все на усмотрение разработчика.
Обработка прерываний входящего буфера сообщений FIFO 0
За прерывания для входящего буфера сообщений FIFO 0 отвечают флаги CAN_IT_FMP0, CAN_IT_FF0 и CAN_IT_FOV0.
Наименование | Описание |
---|---|
CAN_IT_FMP0 | Прерывание срабатывает при получении очередного сообщения в буфер FIFO 0. |
CAN_IT_FF0 | Прерывание возникает при заполнении всех трех почтовых ящиков буфера FIFO 0. |
CAN_IT_FOV0 | А это прерывание возникает если у нас все три почтовых ящика буфера FIFO 0 заполнены и мы получаем четвертое сообщение по шине. У нас происходит переполнение буфера. |
Таб. 1. Прерывания буфера FIFO 0
Заполнение, а тем более переполнение буфера входящих сообщений говорит о том, что Ваша программа не успевает их обрабатывать. Здесь уже необходимо искать причину в организации работы CAN шины и поиграться с установкой фильтров сообщений.
Фильтры помогут на аппаратном уровне отсеивать пакеты с ненужными нам данными, чтобы не тратить время и ресурсы процессора на обработку ненужной информации. Подробнее работу с фильтрами я описал в статье STM32. Почтовые ящики. Фильтры пакетов CAN.
Действия по обработке данных прерываний возлагаются на разработчика и описываются в функции USB_LP_CAN1_RX0_IRQHandler().
Листинг №4. Обработка прерываний bxCan для буфера FIFO 0
void USB_LP_CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
// CAN Receive Interrupt enable FIFO 0
// Обработаем прерывания приемного буфера FIFO 0
if (CAN_GetITStatus(CAN1, CAN_IT_FMP0) == SET) { // Прерывание получения пакета в буфер FIFO 0
// Флаг сбрасывается автоматически после прочтения последнего сообщения
// Обнулим данные пакета
RxMessage.DLC = 0x00;
RxMessage.ExtId = 0x00;
RxMessage.FMI = 0x00;
RxMessage.IDE = 0x00;
RxMessage.RTR = 0x00;
RxMessage.StdId = 0x00;
RxMessage.Data [0] = 0x00;
RxMessage.Data [1] = 0x00;
RxMessage.Data [2] = 0x00;
RxMessage.Data [3] = 0x00;
RxMessage.Data [4] = 0x00;
RxMessage.Data [5] = 0x00;
RxMessage.Data [6] = 0x00;
RxMessage.Data [7] = 0x00;
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); // Получим сообщение
// Вставляем любой свой код обработки входящего пакета
}
if (CAN_GetITStatus(CAN1, CAN_IT_FF0)==SET) { // Прерывание при заполнении буфера FIFO 0
CAN_ClearITPendingBit(CAN1, CAN_IT_FF0);
// Вставляем свой код по обработке прерывания
// Не забываем после обработки сбросить флаг ошибки
CAN_ClearFlag(CAN1, CAN_FLAG_FF0);
}
if (CAN_GetITStatus(CAN1, CAN_IT_FOV0)==SET) { // Прерывание при переполнении буфера FIFO 0
CAN_ClearITPendingBit(CAN1, CAN_IT_FOV0);
// Вставляем свой код по обработке прерывания
// Не забываем после обработки сбросить флаг ошибки
CAN_ClearFlag(CAN1, CAN_FLAG_FOV0);
}
}
Следует обратить внимание на то, что функция USB_LP_CAN1_RX0_IRQHandler() предназначена как для обработки прерываний bxCan так и для обработки прерываний USB. Если Вы будете использовать USB в своем проекте, то нужно внимательно подойти к этому моменту, чтобы правильно обрабатывать сообщения для каждого устройства.
Обратите внимание, что в обработчике прерываний мы сбрасываем не только флаг прерывания, но также сбрасываем флаг ошибки bxCan. Это немного (точнее очень много) разные вещи: флаг прерывания отвечает за то, что мы попадем в обработчик прерывания при его установке и если его не сбросить, то мы можем сидеть вечно в этом обработчике. А флаг ошибки сигнализирует нам о том, что есть ошибка и его нужно снять после того, как мы обработали эту ошибку. Соответственно, если по какой-либо причине мы ее не обработали — этот флаг снимать не следует.
Напомню, что часть флагов прерываний (и ошибок) снимаются автоматически, здесь нужно внимательно изучать руководство.
Обработка прерываний входящего буфера сообщений FIFO 1
За прерывания для входящего буфера сообщений FIFO 1 отвечают флаги CAN_IT_FMP1, CAN_IT_FF1 и CAN_IT_FOV1. Описание и действие аналогично с обработкой прерывания для буфера FIFO 0.
Наименование | Описание |
---|---|
CAN_IT_FMP1 | Прерывание срабатывает при получении очередного сообщения в буфер FIFO 1. |
CAN_IT_FF1 | Прерывание возникает при заполнении всех трех почтовых ящиков буфера FIFO 1. |
CAN_IT_FOV1 | А это прерывание возникает если у нас все три почтовых ящика буфера FIFO 1 заполнены и мы получаем четвертое сообщение по шине. У нас происходит переполнение буфера. |
Таб. 2. Прерывания буфера FIFO 1
В отличии от буфера FIFO 0, обработка этих прерываний происходит в функции CAN1_RX1_IRQHandler().
Листинг №5. Обработка прерываний bxCan для буфера FIFO 1
void CAN1_RX1_IRQHandler(void)
{
CanRxMsg RxMessage;
// CAN Receive Interrupt enable FIFO 1
// Обработаем прерывания приеного буфера FIFO 1
if (CAN_GetITStatus(CAN1, CAN_IT_FMP1) == SET) { // Прерывание получения пакета в буфер FIFO 1
// Флаг сбрасывается автоматически после прочтения последнего сообщения
// Обнулим данные пакета
RxMessage.DLC = 0x00;
RxMessage.ExtId = 0x00;
RxMessage.FMI = 0x00;
RxMessage.IDE = 0x00;
RxMessage.RTR = 0x00;
RxMessage.StdId = 0x00;
RxMessage.Data [0] = 0x00;
RxMessage.Data [1] = 0x00;
RxMessage.Data [2] = 0x00;
RxMessage.Data [3] = 0x00;
RxMessage.Data [4] = 0x00;
RxMessage.Data [5] = 0x00;
RxMessage.Data [6] = 0x00;
RxMessage.Data [7] = 0x00;
CAN_Receive(CAN1, CAN_FIFO1, &RxMessage); // Получим сообщение
// Вставляем любой свой код обработки входящего пакета
}
if (CAN_GetITStatus(CAN1, CAN_IT_FF1)==SET) { // Прерывание при заполнении буфера FIFO 1
CAN_ClearITPendingBit(CAN1, CAN_IT_FF1);
// Вставляем свой код по обработке прерывания
// Не забываем после обработки сбросить флаг ошибки
CAN_ClearFlag(CAN1, CAN_FLAG_FF1);
}
if (CAN_GetITStatus(CAN1, CAN_IT_FOV1)==SET) { // Прерывание при переполнении буфера FIFO 1
CAN_ClearITPendingBit(CAN1, CAN_IT_FOV1);
/ Вставляем свой код по обработке прерывания
// Не забываем после обработки сбросить флаг ошибки
CAN_ClearFlag(CAN1, CAN_FLAG_FF1);
}
}
Обработчик для буфера FIFO 1 ничем не отличается от обработчика для буфера FIFO 0, разница есть только в наименовании функции обработчика и флагов, которые мы проверяем. Наполнение буфера FIFO 1 (как и FIFO 0) зависит исключительно от настроек фильтрации пакетов и в них же указывается какие сообщения в какой буфер будут попадать.
Подробно я о фильтрах рассказывал в статье STM32. Почтовые ящики. Фильтры пакетов CAN.
В своем проекте управления умным домом я с помощью фильтрации разделяю управляющие пакеты и пакеты с данными по разным буферам: сообщения данных попадают исключительно в буфер FIFO 0, а системные и приоритетные сообщения я помещаю в буфер FIFO 1.
Если у Вас нет задачи такой фильтрации сообщений, то можно вполне обойтись одним буфером FIFO 0 и в принципе не использовать буфер FIFO 1 (или наоборот, роли никакой не играет). Для большинства задач это будет вполне достаточно и сэкономит Вам несколько сотен байт прошивки.
Обработка прерываний по ошибкам и «спящему» режиму
Обработчик прерываний ошибок bxCan позволяет нам определить насколько стабильно работает наше устройство с протоколом CAN и вовремя принять меры для достижения максимально стабильного режима работы.
За обработку ошибок отвечают следующие флаги:
Наименование | Описание |
---|---|
CAN_IT_ERR | Error Interrupt — устанавливается при возникновении любой ошибки |
CAN_IT_EWG | Error warning Interrupt — предупреждение о том, что один из счетчиков ошибок достиг 96 или более ошибок |
CAN_IT_EPV | Error passive Interrupt — предупреждение о том, что один из счетчиков ошибок достиг более 127 ошибок |
CAN_IT_BOF | Bus-off Interrupt — Возникает при переходе шины в режим Bus-Off, когда любой из счетчиков ошибок превысил значение 255 |
CAN_IT_LEC | Last error code Interrupt — активируется при возникновении ошибок приема передачи |
CAN_IT_WKU | Wake-up Interrupt — возникает при «пробуждении» bxCan, когда шина выходит из спящего режима. |
CAN_IT_SLK | Sleep acknowledge Interrupt — возникает при уходе шины в «спящий» режим. |
Таб. 3. Прерывания ошибок и режима шины
Прерывание по флагам CAN_IT_WKU и CAN_IT_SLK срабатывают при входе или выходе в/из спящего режима. При этом флаг CAN_IT_ERR не устанавливается. А если же срабатывает прерывание по флагам CAN_IT_EWG, CAN_IT_EPV, CAN_IT_BOF или CAN_IT_LEC, то одновременно с ними устанавливается и флаг CAN_IT_ERR.
Флаги CAN_IT_EWG, CAN_IT_EPV и CAN_IT_BOF предназначены для контроля количества ошибок приема передачи по шине. Механизм bxxCan не только увеличивает счетчик ошибок, например когда на линии возникает помеха и счетчик ошибок увеличивается, но и уменьшает его, когда работа шины нормализуется. Флаги CAN_IT_EWG и CAN_IT_EPV являются предупреждающими о том, что идет рост ошибок и необходимо выявить причину их возникновения, а вот флаг CAN_IT_BOF нам сообщает, что счетчик ошибок достиг своего максимума и шина перешла в режим Bus-off. Выход из этого режима может произойти автоматически (при получении 128 раз 11 рецессивных бит подряд по шине) или принудительно — заново проинициализировав bxCan.
Напомню, что за автоматический выход из режима Bus-Off отвечает бит ABOM в регистре CAN_MCR. Рекомендую его устанавливать в Ваших проектах, тогда bxCan этот функционал возьмет на себя.
Флаг CAN_IT_LEC срабатывает, когда происходит ошибка приема или передачи пакета, при его обработке мы можем узнать последнюю ошибку шины или устройства.
С тем что обрабатывать — мы определились, теперь необходимо вставить в программный модуль и саму функцию обработки прерываний ошибок CAN1_SCE_IRQHandler().
В ней мы сформируем шаблон обработки исключений, возникающих при работе bxCan:
Листинг №6. Обработка прерываний засыпания/пробуждения и ошибок bxCan
void CAN1_SCE_IRQHandler(void)
{
uint8_t errorcode = 0;
if (CAN_GetITStatus(CAN1, CAN_IT_ERR)==SET) { // Прерывание при возникновении ошибки
CAN_ClearITPendingBit(CAN1, CAN_IT_ERR);
// CAN Error Interrupts
// Обработка прерываний по ошибке
if (CAN_GetITStatus(CAN1, CAN_IT_EWG)==SET) { // Error warning Interrupt (счетчик ошибок >= 96)
CAN_ClearITPendingBit(CAN1, CAN_IT_EWG);
// Вставляем свой код по обработке прерывания
}
if (CAN_GetITStatus(CAN1, CAN_IT_EPV)==SET) { // Error passive Interrupt (счетчик ошибок > 127)
CAN_ClearITPendingBit(CAN1, CAN_IT_EPV);
// Вставляем свой код по обработке прерывания
}
if (CAN_GetITStatus(CAN1, CAN_IT_BOF)==SET) { // Bus-off. Прерывание при переполнении счетчика ошибок (>255)
CAN_ClearITPendingBit(CAN1, CAN_IT_BOF); // bxCan уходит в режим Bus-OFF
// Вставляем свой код по обработке прерывания
}
if (CAN_GetITStatus(CAN1, CAN_IT_LEC)==SET) { // Прерывание при ошибке приема передачи сообщения
CAN_ClearITPendingBit(CAN1, CAN_IT_LEC);
errorcode = CAN_GetLastErrorCode(CAN1); // Получим код ошибки
// Вставляем свой код по обработке прерывания
// Не забываем после обработки сбросить флаг ошибки
CAN_ClearFlag(CAN1, CAN_FLAG_LEC);
}
} else {
// CAN Operating Mode Interrupt
// Обработка прерываний по режимам сна/пробуждения
if (CAN_GetITStatus(CAN1, CAN_IT_WKU)==SET) { // Прерывание при "пробуждении" - выход из "спящего" режима
CAN_ClearITPendingBit(CAN1, CAN_IT_WKU);
// Вставляем свой код по обработке прерывания
// Не забываем после обработки сбросить флаг ошибки
CAN_ClearFlag(CAN1, CAN_FLAG_WKU);
}
if (CAN_GetITStatus(CAN1, CAN_IT_SLK)==SET) { // Прерывание при переходе в "спящий" режим
CAN_ClearITPendingBit(CAN1, CAN_IT_SLK);
// Вставляем свой код по обработке прерывания
// Не забываем после обработки сбросить флаг ошибки
CAN_ClearFlag(CAN1, CAN_FLAG_SLAK);
}
}
}
Также как мы сбрасываем флаги прерываний, нам необходимо сбрасывать и флаги ошибок после их обработки. Но если обратить внимание на описание регистров, то мы видим, что часть флагов ошибок сбрасываются автоматически аппаратными средствами bxCan, а часть мы должны очищать вручную. Вот и сейчас при обработке ошибок мы можем сбросить только флаги CAN_IT_LEC, CAN_IT_WKU и CAN_IT_SLK, а остальные флаги ошибок в данном обработчике прерываний сбрасываются автоматически.
Не стоит забывать и о том, что перед сбросом флага ошибки мы должны ее (ошибку) обработать и уже потом менять флаг.
Еще стоит обратить внимание на обработку прерывания CAN_IT_LEC (Last Error Code), которая появляется при возникновении ошибок ввода-вывода.
В обработчике с помощью функции CAN_GetLastErrorCode() мы заполняем переменную errorcode данными о последней ошибке. Она может принимать следующие значения:
Вид | Определение | Описание |
---|---|---|
0x00 | CAN_ErrorCode_NoErr | Нет ошибок |
0x10 | CAN_ErrorCode_StuffErr | Когда узел передает последовательно в шину 5 бит с одинаковым значением, то он добавляет шестой бит с противоположным значением. Принимающие узлы этот дополнительный бит удаляют. Если узел обнаруживает на шине больше 5 последовательных бит с одинаковым значением, то он генерирует ошибку Stuff Error. |
0x20 | CAN_ErrorCode_FormErr | Некоторые части CAN-сообщения имеют одинаковое значение во всех типах сообщений. Т.е. протокол CAN точно определяет какие уровни напряжения и когда должны появляться на шине. Если формат сообщений нарушается, то узлы генерируют ошибку Form Error. |
0x30 | CAN_ErrorCode_ACKErr | Каждый узел получив правильное сообщение по сети посылает в сеть доминантный (0) бит. Если же этого не происходит, то передающий узел регистрирует ошибку Acknowledgement Error. |
0x40 | CAN_ErrorCode_BitRecessiveErr | Ошибка установки рецессивного бита. Каждый узел во время передачи битов в сеть сравнивает значение передаваемого им бита со значением бита которое появляется на шине. Если эти значения не совпадают, то узел генерирует ошибку Bit Error. Естественно, что во время арбитража на шине (передача поля арбитража в шину) этот механизм проверки ошибок отключается. |
0x50 | CAN_ErrorCode_BitDominantErr | Ошибка установки доминантного бита. Каждый узел во время передачи битов в сеть сравнивает значение передаваемого им бита со значением бита которое появляется на шине. Если эти значения не совпадают, то узел генерирует ошибку Bit Error. Естественно, что во время арбитража на шине (передача поля арбитража в шину) этот механизм проверки ошибок отключается. |
0x60 | CAN_ErrorCode_CRCErr | Каждое сообщение CAN содержит CRC сумму, и каждый принимающий узел подсчитывает значение CRC для каждого полученного сообщения. Если подсчитанное значение CRC суммы, не совпадает со значением CRC в теле сообщения, принимающий узел генерирует ошибку CRC Error. |
0x70 | CAN_ErrorCode_SoftwareSetErr | Установлено программно. Можно заполнить единицами данные битов LEC[2:0] регистра CAN_ESR. |
Таб. 4. Виды ошибок, возвращаемые при вызове функции CAN_GetLastErrorCode()
Таким образом, обрабатывая флаг CAN_IT_LEC и изучая ошибки, которые происходят при работе с CAN, мы можем заблаговременно выявить причину и предпринять некоторые действия для того, что бы предотвратить рост ошибок и сваливание CAN контроллера в режим Bus-Off.
Заключение
В этой статье я постарался подробно описать механизмы обработки прерываний bxCan, а также механизмы связанные с обработкой ошибок и методы по их сокращению. Напомню, что все тестирование кода производилось на базе микроконтроллера STM32F103C6.
Вполне вероятно, что я что-то упустил, где то наоборот ошибся и был не точен. Поэтому если есть какие-либо замечания и/или предложения к статье — добро пожаловать в комменты и я исправлюсь.
Как обычно, во вложениях весь исходный код, который рассматривается в рамках данной статьи. Но в отличие от предыдущих постов, исходный код для этой статьи представляет собой некий шаблон, который предполагается использовать в разных проектах.
З.Ы. Простите за много букафф )))
Need a practical intro to CAN bus errors?
In this tutorial you’ll learn about the basics of CAN error handling, the 5 CAN bus error types, the CAN
error frame and CAN node error states.
To get practical, we’ll also generate & record CAN errors in 6 experiments.
In this article
- What are CAN bus errors?
- The CAN error frame
- 5 CAN error types
- States & error counters
- 6 practical experiments
- LIN bus errors
- CAN error logging use cases
- FAQ
What are CAN bus errors?
As explained in our simple intro
to CAN
bus, the Controller Area Network is today the de facto standard across automotives and industrial
automation
systems.
A core benefit is the robustness of CAN, making it ideal for safety critical
applications.
Here, it is worth noting:
Error handling is vital to the robustness of CAN.
CAN bus errors can occur for several reasons — faulty cables, noise, incorrect termination, malfunctioning
CAN nodes etc. Identifying, classifying and resolving such CAN errors is key to ensuring the continued
performance of the overall CAN system.
In particular, error handling identifies and rejects erroneous messages, enabling a sender to
re-transmit the message. Further, the process helps identify and disconnect CAN nodes that
consistently transmit erroneous messages.
How does CAN error handling work?
Error handling is a built-in part of the CAN standard and every CAN controller. In other words, every
CAN node handles fault identification and confinement identically. Below we’ve made a simple illustrative example:
- CAN node 1 transmits a message onto the CAN bus — and reads every bit it sends
- In doing so, it discovers that one bit that was sent dominant was read recessive
- This is a ‘Bit Error’ and node 1 raises an Active Error Flag to inform other nodes
- In practice, this means that node 1 sends a sequence of 6 dominant bits onto the bus
- In turn, the 6 dominant bits are seen as a ‘Bit Stuffing Error’ by other nodes
- In response, nodes 2 and 3 simultaneously raise an Active Error Flag
- This sequence of raised error flags comprise part of a ‘CAN error frame’
- CAN node 1, the transmitter, increases its ‘Transmit Error Counter’ (TEC) by 8
- CAN nodes 2 and 3 increase their ‘Receive Error Counter’ (REC) by 1
- CAN node 1 automatically re-transmits the message — and now succeeds
- As a result, node 1 reduces its TEC by 1 and nodes 2 and 3 reduce their REC by 1
The example references a number of concepts that we will detail shortly: Error frames, error
types, counters and states.
The CAN bus error frame
In the illustrative example, the CAN nodes ‘raise Active Error Flags’, thus creating an ‘error frame’ in
response to detecting a CAN error.
To understand how this works, let us first look at a «normal» CAN frame (without errors):
CAN bus bit stuffing
Notice that we highlighted ‘bit stuffing’ across the CAN frame.
Bit stuffing is a subtle, but vital part of the CAN standard. Basically it states that whenever a CAN node
sends five bits of the same logic level (dominant or recessive), it must send one bit of the opposite level.
This extra bit is automatically removed by the receiving CAN nodes. This process helps ensure continuous
synchronisation of the network.
As per the previous example, when CAN node 1 detects an error during the transmission of a CAN message, it
immediately transmits a sequence of 6 bits of the same logic level — also referred to as raising an Active
Error Flag.
If we measure the transmission of a CAN frame via an oscilloscope and digitize the result, we can also
see the stuff bits in practice (see the red timestamp marks):
Active Error Flags
As we just learned, such a sequence is a violation of the bit stuffing rule — aka a ‘Bit Stuffing Error’.
Further, this error is visible to all CAN nodes on the network (in contrast to the ‘Bit Error’ that resulted
in this error flag being raised). Thus, the raising of error flags can be seen as a way of
«globalizing» the discovery of an error, ensuring that every CAN node is informed.
Note that the other CAN nodes will see the Active Error Flag as a Bit Stuffing Error. In
response they also raise an Active Error Flag.
As we’ll explain shortly, it is important to distinguish between the error flags. In particular, the first
error flag
(from the ‘discovering’ node) is often referred to as a ‘primary’ Active Error Flag, while
the error flags of
subsequent ‘reacting’ nodes are referred to as the ‘secondary’ Active Error Flag(s).
3 CAN error frame examples
Let’s look at three example scenarios:
Example 1: 6 bits of error flags
Here, all CAN nodes simultaneously discover that an error exists in a CAN message and raise their error
flags at the same time.
The result is that the error flags all overlap and the total sequence of dominant
bits lasts for 6 bits in total. All CAN nodes will in this case consider themselves the ‘discovering’ CAN
nodes.
This type of simultaneous discovery is less common in practice. However, it could e.g. happen as a
result of Form
Errors (such as a CRC delimiter being dominant instead of recessive), or if a CAN transmitter
experiences a bit error during the writing of a CRC field.
Example 2: 12 bits of error flags
Here, CAN node 1 transmits a dominant bit, but reads it as recessive — meaning that it discovers a Bit Error.
It immediately transmits a sequence of 6 dominant bits.
The other nodes only discover the Bit Stuffing Error
after the full 6 bits have been read, after which they simultaneously raise their error flags, resulting in
a subsequent sequence of 6 dominant bits — i.e. 12 in total.
Example 3: 9 bits of error flags
Here, CAN node 1 has already transmitted a sequence of 3 dominant bits when it discovers a Bit Error and
begins sending 6 dominant bits.
Once halfway through the primary Active Error Flag, nodes 2 and 3 recognize
the Bit Stuffing Error (due to the 3 initial dominant bits being followed by another 3 dominant bits) and
they begin raising their error flags. The result is that the sequence of dominant bits from error flags
becomes 9 bit long.
The above logic of raising error flags is reflected in what we call an ‘active’ CAN error frame.
Note in particular how the secondary error flags raised by various nodes overlap each other — and how the
primary and secondary flags may overlap as well. The result is that the dominant bit sequence from raised
error
flags may be 6 to 12 bits long.
This sequence is always terminated by a sequence of 8 recessive bits, marking the end of the error frame.
In practice, the active error frame may «begin» at different places in the erroneous CAN frame, depending on
when the
error is discovered. The result, however, will be the same: All nodes discard the erroneous CAN frame and
the
transmitting node can attempt to re-transmit the failed message.
Passive Error Flags
If a CAN node has moved from its default ‘active’ state to a ‘passive’ state (more on this shortly), it will only be
able to raise so-called ‘Passive Error Flags’. A Passive Error Flag is a sequence of 6 recessive bits as seen below.
In this case it’s relevant to distinguish between a Passive Error Flag raised by a transmitting node and a receiving
node.
Example 4: Transmitter is Error Passive
As shown in the illustration (Example 4), if a transmitter (such as CAN node 1 in our example) raises a
Passive Error Flag (e.g. in response to a Bit Error), this will correspond to a consecutive sequence of 6
recessive bits.
This is in turn detected as a Bit Stuffing Error by all CAN nodes. Assuming the other CAN
nodes are still in their Error Active state, they will raise Active Error Flags of 6 dominant bits. In other
words, a passive transmitter can still «communicate» that a CAN frame is erroneous.
Example 5: Receiver is Error Passive
In contrast, if a receiver raises a Passive Error Flag this is in practice «invisible» to all other CAN nodes
on the bus (as any dominant bits win over the sequence of recessive bits) — see also Example 5.
Effectively,
this means that an Error Passive receiver no longer has the ability to destroy frames transmitted by
other CAN nodes.
CAN error types
Next, let us look at what errors may cause CAN nodes to raise error flags.
The CAN bus protocol specifies 5 CAN error types:
- Bit Error [Transmitter]
- Bit Stuffing Error [Receiver]
- Form Error [Receiver]
- ACK Error (Acknowledgement) [Transmitter]
- CRC Error (Cyclic Redundancy Check) [Receiver]
We’ve already looked at Bit Errors and Bit Stuffing Errors briefly, both of which are evaluated at the bit
level. The remaining three CAN error types are evaluated at the message level.
Below we detail each error type:
#1 Bit Error
Every CAN node on the CAN bus will monitor the signal level at any given time — which means that a
transmitting CAN node also «reads back» every bit it transmits. If the transmitter reads a different data
bit level vs. what it transmitted, the transmitter detects this as a Bit Error.
If a bit mismatch occurs during the arbitration process (i.e. when sending the CAN ID), it is not
interpreted as a Bit Error. Similarly, a mismatch in the acknowledgement slot (ACK field) does not cause
a Bit Error as the ACK field specifically requires a recessive bit from the transmitter to be
overwritten by a dominant bit from a receiver.
#2 Bit Stuffing Error
As explained, bit stuffing is part of the CAN standard. It dictates that after every 5 consecutive bits of
the same logical level, the 6th bit must be a complement. This is required to ensure the on-going
synchronization of the network by providing rising edges. Further, it ensures that a stream of bits are not
mis-interpreted as an error frame or as the interframe space (7 bit recessive sequence) that marks the end
of a message. All CAN nodes automatically remove the extra bits.
If a sequence of 6 bits of the same logical level is observed on the bus within a CAN message (between the
SOF and CRC field), the receiver detects this as a Bit Stuffing Error aka Stuff Error.
#3 Form Error
This message-level check utilises the fact that certain fields/bits in the CAN message must always be of a
certain logical level. Specifically the 1-bit SOF must be dominant, while the entire 8-bit EOF field must be
recessive. Further, the ACK and CRC delimiters must be recessive. If a receiver finds that any of these are
bits are of an invalid logical level, the receiver detects this as a Form Error.
#4 ACK Error (Acknowledgement)
When a transmitter sends a CAN message, it will contain the ACK field (Acknowledgement), in which the
transmitter will transmit a recessive bit. All listening CAN nodes are expected to send a dominant bit in
this field to verify the reception of the message (regardless of whether the nodes are interested in the
message or not). If the transmitter does not read a dominant bit in the ACK slot, the
transmitter detects this as an ACK Error.
#5 CRC Error (Cyclic Redundancy Check)
Every CAN message contains a Cyclic Redundancy Checksum field of 15 bits. Here, the transmitter has
calculated the CRC value and added it to the message. Every receiving node will also calculate the CRC on
their own. If the receiver’s CRC calculation does not match the transmitter’s CRC, the
receiver detects this as a CRC Error.
CAN node states & error counters
As evident, CAN error handling helps destroy erroneous messages — and enables CAN nodes to retry the
transmission of
erroneous messages.
This ensures that short-lived local disturbances (e.g. from noise) will not
result in
invalid/lost data. Instead, the transmitter attempts to re-send the message. If it wins arbitration
(and there
are no errors), the message is successfully sent.
However, what if errors are due to a systematic malfunction in a transmitting node? This could
trigger an endless loop of sending/destroying the same message — jamming the CAN bus.
This is where CAN node states and error counters come in.
In short, the purpose of CAN error tracking is to confine errors by gracefully reducing the privileges of
problematic CAN nodes.
Specifically, let’s look at the three possible states:
-
Error Active: This is the default state of every CAN node, in which
it is able to
transmit data
and raise ‘Active Error Flags’ when detecting errors -
Error Passive: In this state, the CAN node is still able to
transmit data, but it now
raises
‘Passive Error Flags’ when detecting errors. Further, the CAN node now has to wait for an extra 8 bits
(aka
Suspend Transmission Time) in addition to the 3 bit intermission time before it can resume data
transmission (to
allow other CAN nodes to take control of the bus) -
Bus Off: In this state, the CAN node disconnects itself from the
CAN bus and can no
longer
transmit data or raise error flags
Every CAN controller keeps track of its own state and acts accordingly.
CAN nodes shift state depending on the value of their error counters. Specifically, every CAN node
keeps track on a Transmit Error Counter (TEC) and Receive Error Counter
(REC):
- A CAN node
enters the Error Passive state if the REC or TEC exceed 127 - A CAN node
enters the Bus Off state if the TEC exceeds 255
How do the error counters change?
Before we get into the logic of how error counters are increased/reduced, let us revisit the CAN error frame
as well
as the primary/secondary error flags.
As evident from the CAN error frame illustration, a CAN node that observes a dominant bit after its
own
sequence of 6
dominant bits will know that it raised a primary error flag. In this case, we can call this CAN
node the
‘discoverer’ of the error.
At first, it might sound positive to have a CAN node that repeatedly discovers errors and reacts promptly by
raising
an error flag before other nodes. However, in practice, the discoverer is typically also the culprit causing
errors
— and hence it is punished more severely as per the overview.
There are some additions/exceptions to the above rules, see e.g. this overview.
Most are pretty straight-forward based on our previous illustrative example. For example, it seems clear that CAN
node 1 would increase the TEC by 8 as it discovers the Bit Error and raises an error flag. The other nodes in
this
case increase their REC by 1.
This has the intuitive consequence that the transmitting node will quickly reach the Error Passive and eventually
Bus
Off states if it continuously produces faulty CAN messages — whereas the receiving nodes do not change state.
The case where a receiver raises the primary error flag may seem counter-intuitive. However, this could for
example
be the case if a receiver CAN node is malfunctioning in a way that causes it to incorrectly detect errors in
valid
CAN messages. In such a case, the receiver would raise the primary error flag, effectively causing an error.
Alternatively, it can happen in cases where all CAN nodes simultaneously raise error flags.
CAN/LIN data & error logger
The CANedge1 lets you easily
record data from 2 x CAN/LIN buses to an 8-32 GB SD card — incl. support for logging CAN/LIN errors. Simply
connect it to e.g. a car or truck to start logging —
and decode the data via free
software/APIs.
Further, the CANedge2
adds WiFi, letting you auto-transfer data to your own server — and update devices over-the-air.
learn
about the CANedge
Examples: Generating & logging error frames
We have now covered the theoretical basics of CAN errors and CAN error handling. Next, let us look at generating and
logging errors in practice. For this we will use a couple of CANedge devices — and for some tests a
PCAN-USB device.
Tip: Download the MF4 data for the tests to view the data in asammdf or CANalyzer.
download data
Test #1: No CAN bus errors
As a benchmark, we start with a test involving no CAN bus errors. Here, a CANedge2 ‘transmitter’ sends
data to another CANedge2 ‘receiver’ — and both log CAN bus errors.
By loading the MF4 log
file in the asammdf GUI we
verify that no CAN errors occurred during this test, which is to be expected.
Test #2: Removing the CAN bus terminal resistor
In this test, we remove the CAN termination in the middle of a log session. This effectively corresponds to
immediately setting the bit level to dominant. As a result, the CANedge2 transmitter immediately starts
logging Bit Errors (which occur when it attempts to transmit a recessive bit, but reads a
dominant bit). The
CANedge2 Receiver logs Bit Stuffing Errors as it detects 6 consecutive dominant bits.
These errors are
recorded until the termination is added again.
Lack of termination is rarely a practical issue if you’re recording data from a vehicle, machine etc.
However, it’s a common issue when working with ‘test bench’ setups. Here, the lack of termination may
cause confusion as it can be difficult to distinguish from an inactive CAN bus. If in doubt, enabling
error frame logging on the CANedge can be useful in troubleshooting.
Transmitter Bit Errors
Receiver Bit Stuffing Errors
Test #3: Setting an incorrect baud rate
In this test we configure the CANedge receiver node to have a baud rate of 493.827K vs. the baud rate of the
transmitter of 500K. This is a fairly extreme difference and results in ACK Errors for the
transmitter and Bit
Stuffing Errors for the receiver.
In more realistic scenarios, smaller differences in the baud
rate
configuration of
various nodes may cause intermittent error frames and thus message loss.
This example is rather extreme. However, in practice we have sometimes seen CAN buses that use standard
bit rates
(250K, 500K, …), but with specific bit timing settings that differ from the ones that are typically
recommended
(and hence used by the CANedge). This will not lead to a complete shut-down of the communication, but
rather
periodic frame loss of a few percentages. To resolve this, you can construct an ‘advanced bit rate’ in
the
CANedge configuration, essentially setting up the bit-timing to better match the CAN bus you’re logging
from.
Transmitter ACK Error
Receiver Bit Stuffing Errors
Test #4: Removing the acknowledging CAN node
In this test, we use three CANedge units configured as follows:
-
CANedge1: Configured to
acknowledge data -
CANedge2 A:
Configured in ‘silent mode’ (no acknowledgement) -
CANedge2 B:
Configured to transmit a CAN frame every 500 ms
In the default setup, data is transmitted by the CANedge2 B onto the CAN bus and recorded with no errors.
However, if we remove the CANedge1 from the bus there are no longer any CAN nodes to acknowledge the frames
sent by the transmitter.
As a result, the transmitter detects ACK Errors. In response, it increases its
Transmit Error Counter and raises Active Error Flags onto the CAN bus. These are in turn
recorded by CANedge2 A (which silently monitors the bus) as Form Errors.
This is due to the fact that the transmitter raises them upon identifying the lack of a dominant
bit in the ACK slot. As soon as a dominant bit is observed by the receiver in the subsequent EOF field
(which should be recessive), a Form Error is detected.
As evident, the transmitter broadcasts 16 Active Error Flags as its TEC is increased from 0 to 16 x 8 =
128.
The transmitter has now exceeded the threshold of a TEC of 127 and enters Error Passive mode. As a
result,
the transmitter still experiences ACK Errors, but now only raises Passive Error Flags (not visible to
the
receiver). At this point, the transmitter keeps attempting to transmit the same frame — and the receiver
keeps recording this retransmission sequence.
This type of error is one we often encounter in our support tickets. Specifically, users may be trying to
use our CAN loggers to record data from a single CAN node (such as a sensor-to-CAN module like our
CANmod). If they decide to enable ‘silent mode’ on the CANedge in such an installation, no CAN nodes
will acknowledge the single CAN node broadcasting data — and the result will either be empty log files,
or log files filled with retransmissions of the same CAN frame (typically at very high frequency).
Transmitter ACK Errors
Receiver Form Errors
Test #5: CAN frame collisions (no retransmission)
When setting up a CAN bus, it is key to avoid overlapping CAN IDs. Failing to do so can result in frame
collisions
as two CAN nodes may both believe they’ve won the arbitration — and hence start transmitting their frames at
the same time.
To simulate this, we use the same setup as in test #4. In addition, we connect a PCAN-USB device as a
secondary
transmitter.
The CANedge2 transmitter is now configured to output a single CAN frame every 10 ms with CAN ID 1 and a
payload of
eight 0xFF bytes. Further, we configure the CANedge2 to disable retransmission of frames that were disrupted
by
errors. The PCAN-USB outputs an identical CAN frame every 2 ms with the 1st byte of the payload changed to
0xFE. The
PCAN device has retransmissions enabled.
This setup quickly creates a frame collision, resulting in the CANedge and PCAN transmitters detecting a
Bit
Error.
In response to this, both raise an Active Error Flag, which is detected as a Bit Stuffing
Error by the
CANedge
receiver. The PCAN device immediately attempts a retransmission and succeeds, while the CANedge waits with
further
transmission until the next message is to be sent.
This type of error should of course never happen in e.g. a car, since the design and test processes will
ensure
that all CAN nodes communicate via globally unique CAN identifiers. However, this problem can easily
occur if
you install a 3rd party device (e.g. a sensor-to-CAN module) to inject data into an existing CAN bus. If
you do
not ensure the global uniqueness of the CAN IDs of external CAN nodes, you may cause frame collisions
and hence
errors on the CAN bus. This is particularly important if your external CAN node broadcasts data with
high
priority CAN IDs as you may then affect safety critical CAN nodes.
USB-to-CAN transmitter Bit Error
CANedge transmitter Bit Error
CANedge receiver Bit Stuffing Error
Test #6: CAN frame collisions (incl. retransmission)
In this test, we use the same setup as before, but we now enable retransmissions on the CANedge2 transmitter.
In this case, the frame collision results in a sequence of subsequent frame collisions as both the CANedge2
and the PCAN-USB device attempt to re-transmit their disrupted messages.
Due to the resulting Bit Errors, both raise a total of 16 Active Error Flags, which are detected as
Bit Stuffing Errors
by the silent CANedge2 receiver. Both transmitters then enter Error Passive mode and stop raising Active Error
Flags, meaning none of them can destroy CAN frames on the bus. As a result, one of the transmitters will
succeed in transmitting a full message, thus ending the retransmission frenzy — and enabling both devices to
resume transmission. However, this only lasts for a few seconds before another collision occurs.
The collision handling is a good example of how effective the CAN error handling is at ‘shutting down’
potentially
problematic sequences and enabling CAN nodes to resume communication. If a frame collision occurs, it is likely
that both CAN nodes will be set up to attempt retransmission, which would cause a jam if not for the error
handling and confinement.
USB-to-CAN transmitter Bit Errors x 16
CANedge transmitter Bit Errors x 16
CANedge receiver Bit Stuffing Errors x 16
Similar to CAN bus errors, the LIN protocol also specifies a set of four error types, which we outline briefly below.
The CANedge supports both CAN/LIN error frame logging.
As for the CAN CRC Error, this error type implies that a LIN node has calculated a different checksum vs. the one
embedded in the LIN bus frame by the transmitter. If you’re using the CANedge as a LIN Subscriber, this error
may indicate that you’ve configured the device ‘frame table’ with incorrect identifiers for some of the LIN
frames on the bus.
This can in turn be used to ‘reverse engineer’ the correct lengths and IDs of proprietary LIN frames via a
step-by-step procedure. See the CANedge Docs for details.
These occur if a specific part of the LIN message does not match the expected value, or if there is a mismatch
between what is transmitted vs. read on the LIN bus.
This error indicates an invalid synchronization field in the start of the LIN frame. It can also indicate a large
deviation between the configured bit rate for a LIN node vs. the bit rate detected from the synchronization
field.
Transmission errors can occur for LIN identifiers registered as SUBSCRIBER messages. If there are no nodes
responding to a SUBSCRIBER message, a transmission error is logged.
Example use cases for CAN error frame logging
CAN bus diagnostics in OEM prototype vehicles
An automotive OEM may have the need to record CAN error frames in the field during late stage prototype
testing. By deploying a CANedge, the OEM engineering team will both be able to troubleshoot issues based on
the actual CAN signals (speed, RPM, temperatures) — as well as issues related with the lower layer CAN
communication in their prototype systems. This is particularly vital if the issues of interest are
intermittent and e.g. only happen once or twice per month. In such scenarios, CAN bus interfaces are not
well suited — and it becomes increasingly relevant to have a cost-effective device to enable scalable
deployments for faster troubleshooting.
Remotely troubleshooting CAN errors in machinery
An OEM or aftermarket user may need to capture rare CAN error events in their machines. To do so, they deploy
a CANedge2 to record the CAN data and related error frames — and automatically upload the data via WiFi to
their own cloud server. Here, errors are automatically identified and an alert is sent to the engineering
team to immediately allow for diagnosing and resolving the issue.
FAQ
No, error frame logging is a highly specific functionality — and only relevant if you know that you need to
record this information. Typically, it’s mainly of value during diagnostics by OEM engineers — and less so for
aftermarket users. In addition, if systematic errors occur they can quickly bloat the log file size.
With the CANedge2 you can of course enable/disable error frame logging over-the-air.
Yes, the CANedge is able to record all CAN/LIN error types. It does, however, not currently record its own error
counter status as this is deemed less relevant from a logging perspective.
The CANedge is only able to raise error flags onto the CAN bus if it is configured in its ‘normal’ mode, in which
it is also able to transmit messages. If in ‘restricted’ mode it can listen to CAN frames and acknowledge CAN
frames — but not raise Active Error Flags onto the bus. In ‘monitoring’ mode (aka ‘silent mode’) it can listen
to the CAN bus traffic, but not acknowledge messages nor raise Active Error Flags.
The CANedge will always record internal CAN/LIN error frames.
If a CAN frame is erroneous, resulting in an error frame, the CANedge generally only records the error type —
without any data related to the erroneous frame (beyond the timestamp). One exception to this rule is for
acknowledgement errors, where the CANedge will still record unacknowledged CAN frames (incl. from retransmission
attempts).
Some researchers have pointed out the risk that ‘bad actors’ could utilize the CAN bus error handling
functionality to enforce remote ‘bus off’ events for safety-critical ECUs. This is a good example of why CAN bus
data loggers & interfaces like the CANedge2 with remote
over-the-air data transfer and updates need to be highly secure (see also our intro to CAN
cybersecurity). For a nice overview of a remote bus off attack, see this
intro by Adrian Colyer.
For more intros, see our guides section — or download the
‘Ultimate Guide’ PDF.
Need to log CAN bus data & errors?
Get your CAN logger today!
Recommended for you
По материалам компании Kvaser
Продолжение статьи I части.
Эта статья не претендует на полноту и абсолютную точность сведений, указанных в ней, и предназначена для ознакомления с протоколом CAN.
Содержание статьи
• Шина CAN – Введение.
• Сообщения CAN.
• Физические уровни CAN.
• Разъемы CAN.
• Тактовая синхронизация CAN.
• Обработка ошибок CAN.
Разъемы CAN
Для разъемов CAN стандартов не существует! Обычно, каждый (!) протокол более высокого уровня (Higher Layer Protocol) описывает один или несколько предпочтительных типов разъемов. Основные типы:
• 9–контактный DSUB, предложен CiA;
• 5–контактный Mini–C и/или Micro–C, используется DeviceNet и SDS;
• 6–контактный Deutsch разъем, предложенный CANHUG для транспортных гидравлических систем.
Разъемы CAN
Данное назначение контактов разъема рекомендовано CiA и фактически является промышленным стандартом.
1 | — | Резерв |
2 | CAN_L | Линия шины CAN_L (доминантная низкая) |
3 | CAN_GND | Заземление CAN |
4 | — | Резерв |
5 | (CAN_SHLD) | Опционально: экран CAN |
6 | (GND) | Опционально: заземление CAN |
7 | CAN_H | Линия шины CAN_H (доминантная высокая) |
8 | — | Резерв (линия ошибок) |
9 | CAN_V+ | Опционально: питание |
Для пользователей продукции KVASER: Пожалуйста заметьте, что специфическое употребление этих контактов в кабелях KVASER DRVcan описано в документе LAPcan Hardware Guide, который можно скачать на сайте компании.
Если питание подается, оно должно быть в диапазоне +7..+13 В, 100 мA. Модули оснащены разъемом типа «папа» и должны соединять внутри контакты 3 и 6.
Нумерация контактов действительна для разъема типа «папа„, при взгляде со стороны разъема, или для разъема типа “мама», при взгляде со стороны распайки. – Чтобы запомнить расположение контактов, заметьте, что контакт CAN_LOW имеет МЕНЬШИЙ (LOW) номер, а CAN_HIGH – БОЛЬШИЙ (HIGH).
5-контактный Mini–C
Используется как DeviceNet , так и SDS , и является совместимым для этих двух протоколов.
Контакт | Функция | Цвет DeviceNet |
1 | Экран | Неизолированный |
2 | V+ | Красный |
3 | V- | Черный |
4 | CAN_H | Белый |
5 | CAN_L | Синий |
Модули оснащены разъемами типа «папа». Подаваемое напряжение 24 В ±1%
6-контактный Deutsch DT04-6P
Рекомендован CANHUG для использования в транспортных гидравлических системах
Разъемы на модулях типа «папа», разъемы шины – «мама». На данный момент нет никаких рекомендаций по вопросу подачи питания.
Контакт | Функция | Рекомендованный цвет кабеля |
1 | «Минус» питания |
Черный |
2 | CAN_H | Белый |
3 | Опционально: заземление сигнала | Желтый |
4 | Опционально: запуск | Серый |
5 | «Плюс» питания | Красный |
6 | CAN_L | Синий |
Тактовая синхронизация CAN
Схема бита
Каждый бит, передаваемый по шине CAN, разделяется, для нужд тактовой синхронизации, как минимум на 4 части (кванта). Часть логически делится на 4 группы или сегмента:
• сегмент синхронизации
• сегмент воспроизведения
• сегмент фазы 1
• сегмент фазы 2
Схема бита данных шины CAN:
Сегмент синхронизации, который всегда имеет длину в один квант, используется для синхронизации тактовых частот. Ожидается, что край бита появится здесь при смене данных на шине.
Сегмент воспроизведения нужен для компенсации задержки на линиях шины.
Сегменты фазы могут быть сокращены (сегмент фазы 1) или удлинены (сегмент фазы 2), если это потребуется для сохранения синхронизованности тактовых частот.
Уровни шины замеряются на границе между сегментом фазы 1 и сегментом фазы 2.
Большинство контроллеров CAN также обеспечивают возможность трехкратного замера на протяжении одного бита. В таком случае, замер происходит на границах двух квантов, предшествующих точке замера и результат зависит от мажоритарного декодирования (это верно как минимум в случае 82527).
Тактовая синхронизация
Для того, чтобы регулировать встроенный в чип генератор тактовых частот шины, контроллер CAN может сократить или удлинить бит на целое число квантов. Максимальное количество таких временных поправок бита определяется параметром «ширина скачка синхронизации» (Synchronization Jump Width, SJW).
Жесткая синхронизация происходит при переходе стартового бита от рецессивного к доминантному. Отсчет времени прохождения бита начинается заново с этой границы.
Повторная синхронизация происходит когда край бита не попадает в сегмент синхронизации сообщения. Один из сегментов фазы укорачивается или удлиняется на некоторое количество квантов, зависящее от ошибки фазы сигнала; максимальное количество используемых квантов определяется параметром «ширина скачка синхронизации» (Synchronization Jump Width, SJW).
Вычисление регистра тактовой синхронизации
Большинство контроллеров CAN позволяют программисту осуществлять настройку тактовой синхронизации используя следующие параметры:
• Значение предварительного делителя тактовой частоты
• Количество квантов перед точкой замера
• Количество квантов после точки замера
• Количество квантов в «ширина скачка синхронизации» (Synchronization Jump Width, SJW)
Обычно для этих целей выделяется два регистра: btr0 и btr1. Однако они могут слегка различаться у разных контроллеров, поэтому внимательно читайте инструкцию.
В контроллерах 82c200 и SJA1000, производства NXP (ранее Philips), раскладка регистра выглядит приблизительно так:
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
btr0 | SJW1 | SJW0 | BRP5 | BRP4 | BRP3 | BRP2 | BRP1 | BRP0 |
btr1 | SAM | TSEG22 | TSEG21 | TSEG20 | TSEG13 | TSEG12 | TSEG11 | TSEG10 |
• BRP0..BRP5 устанавливают значение предварительного делителя тактовой частоты
• SJW0..SJW1 устанавливают длину SJW
• TSEG10..TSEG13 устанавливают количество квантов перед точкой замера (стартовый бит не включен)
• TSEG20..TSEG22 устанавливают количество квантов после точки замера
• SAM при установке значения 1 производится три замера, при установке значения 0 – один замер
Примечание: реальные значения этих параметров несколько отличаются от значений, вписанных в регистр.
Пример: если сигнал генератора, подаваемый на SJA1000, имеет частоту 16 МГц, и мы желаем получить скорость передачи 250 кбит/с, с точкой замера в районе 62% всего бита, и SJW равным 2 квантам, мы можем установить –
BRP = 4, что дает продолжительность кванта 2 × 4 / 16000000 с = 500 нс, и
TSEG1 = 5, что дает 5 квантов перед точкой замера, и
TSEG2 = 3, что дает 3 кванта после точки замера.
Каждый бит будет содержать 5 + 3 = 8 квантов, что даст нам желаемую скорость передачи 1 / (8 × 500 нс) = 250 кбит/с. Значения регистра должны быть следующими:
btr0= |
(SJW – 1) * 64 + (BRP -1) = (2-1)*64 + (4-1) = 67 = 0×43 |
btr1= |
SAM * 128 + (TSEG2 – 1)* 16 + (TSEG1 – 1) = 0×128 + (3-1)*16 + (4-1) = («4» потому, что стартовый бит не включен) 35 = 0×23 |
Точка замера в районе 5/8 = 62.5% бита.
Обработка ошибок CAN
Как CAN обрабатывает ошибки
Обработка ошибок встроена в протокол CAN и очень важна для производительности системы CAN. Обработка ошибок нацелена на обнаружение ошибок в сообщениях, передающихся по шине CAN, чтобы передатчик мог повторно выслать неверно принятое сообщение. Каждый CAN–контроллер на шине будет пытаться обнаружить ошибку в сообщении. Если ошибка найдётся, обнаруживший её узел будет передавать флаг ошибки, таким образом разрушая трафик шины. Другие узлы обнаружат ошибку, вызванную флагом ошибки (если еще не обнаружили оригинальную ошибку) и предпримут соответствующие действия, т.е. отбракуют текущее сообщение.
Каждый узел обслуживается двумя счетчиками ошибок: счетчиком ошибок передачи (Transmit Error Counter) и счетчиком ошибок приёма (Receive Error Counter). Существуют правила, регламентирующие повышение и/или понижение значения этих счетчиков. По существу, передатчик определяет повышение числа сбоев в счетчике ошибок передачи быстрее, нежели слушающие узлы увеличат значения своих счетчиков ошибок передачи. Это потому, что есть немалая вероятность, что сбой именно в передатчике! Когда значение любого счетчика ошибок превышает определенную величину, узел сначала становится Error Passive – это значит, что он не будет активно разрушать трафик шины при обнаружении ошибки; а затем Bus Off – это значит, что узел вообще не будет принимать участия в передаче данных по шине.
При помощи счетчиков ошибок узел CAN может не только обнаруживать сбои, но и ограничивать ошибки.
Механизмы обнаружения ошибок
Протокол CAN описывает не менее пяти различных способов обнаружения ошибок. Два из них работают на уровне бита, а остальные три – на уровне сообщения.
1.Мониторинг битов (Bit Monitoring).
2.Вставка битов (Bit Stuffing).
3.Проверка кадра (Frame Check).
4.Проверка распознавания (Acknowledgement Check).
5.Проверка циклической избыточности (Cyclic Redundancy Check).
Мониторинг бита
Каждый передатчик шины CAN осуществляет мониторинг (т.е. повторное прочтение) переданного уровня сигнала. Если уровень прочитанного бита отличается от уровня переданного, подается сигнал ошибки бита (Bit Error). (Роста бита ошибок в процессе разрешения конфликтов не происходит.) Вставка битов
После того как узел передаст пять непрерывно следующих друг за другом битов одного уровня, он добавит к исходящему потоку битов шестой бит, противоположного уровня. Получатели будут удалять этот дополнительный бит. Это делается для предупреждения появления излишнего количества компонентов DC на шине, но также дает получателям дополнительную возможность обнаружения ошибок: если по шине передается более пяти непрерывно следующих друг за другом битов одного уровня, подается сигнал ошибки вставки.
Проверка кадра
Некоторые части сообщения CAN имеют фиксированный формат, т.е. стандарт четко определяет, какие уровни должны произойти и когда. (Эти части – ограничитель CRC (CRC Delimiter), ограничитель ACK (ACK Delimiter), конец кадра (End of Frame), а также пауза (Intermission), однако для них существуют дополнительные специализированные правила проверки на ошибки.) Если контроллер CAN обнаружит неверное значение в одном из этих полей, он подаст сигнал ошибки формы (Form Error).
Проверка распознавания
Ожидается, что все узлы шины, которые получили сообщение корректно (независимо от того, было ему это сообщение «интересно» или нет), отправят доминантный уровень в так называемой области распознавания (Acknowledgement Slot) кадра. Передатчик будет передавать рецессивный уровень. Если передатчик не сможет обнаружить доминантный уровень в области распознавания, он подаст сигнал ошибки распознавания (Acknowledgement Error).
Проверка циклической избыточности
Каждое сообщение содержит 15–битную контрольную сумму циклической избыточности (Cyclic Redundancy Checksum, CRC), и любой узел, обнаруживший что CRC в сообщении отличается от посчитанного им, подаст сигнал ошибки CRC (CRC Error).
Механизмы ограничения ошибок
Каждый контроллер CAN шины будет пытаться обнаружить описанные выше ошибки в каждом сообщении. Если ошибка обнаружится, нашедший её узел передаст флаг ошибки, таким образом разрушая передачу данных по шине. Другие узлы обнаружат ошибку, вызванную флагом ошибки (если они ещё не обнаружили оригинальную ошибку) и предпримут соответствующее действие, т.е. сбросят текущее сообщение.
Каждый узел обслуживают два счетчика ошибок: счетчик ошибок передачи и счетчик ошибок приема. Существуют правила, описывающие условия повышения и/или понижения значений этих счетчиков. По существу, передатчик, обнаруживший сбой, повышает значение своего счетчика ошибок передачи быстрее, чем слушающие узлы повысят значения своих счетчиков ошибок приема. Это потому, что есть большая вероятность, что сбоит сам передатчик!
Узел начинает работу в режиме Error Active. Когда значение любого из двух счетчиков ошибок превысит 127, узел перейдет в состояние Error Passive, а когда значение счетчика ошибок передачи превысит 255, узел перейдёт в состояние Bus Off.
• Узел в режиме Error Active при обнаружении ошибки будет передавать флаги активной ошибки (Active Error Flags).
• Узел в режиме Error Passive при обнаружении ошибки будет передавать флаги пассивной ошибки (Passive Error Flags).
• Узел в режиме Bus Off не будет передавать ничего.
Правила повышения и понижения значений счетчиков ошибок довольно сложные, но принцип прост: ошибка передачи добавляет 8 пунктов, а ошибка прием – 1 пункт. Правильно переданные и/или принятые сообщения вызывают понижение значения счетчика(ов).
Пример (слегка упрощенный): Представим, что у узла A плохой день. Всякий раз, когда A пытается передать сообщение, происходит сбой (не важно, по какой причине). При каждом сбое значение счетчика ошибок передач увеличивается на 8 пунктов и передается флаг активной ошибки. Затем он пытается послать сообщение ещё раз.. и всё повторяется.
Когда значение счетчика ошибок передачи превысит 127 пунктов (т.е. после 16 попыток), узел A перейдёт в режим Error Passive. Разница в том, что теперь он будет передавать флаги пассивной ошибки. Флаг пассивной ошибки содержит 6 рецессивных битов и не будет нарушать передачу других данных по шине – поэтому другие узлы не услышат жалобы A на ошибки шины. Однако A продолжит повышать значение счетчика ошибок передачи. Когда он превысит 255 пунктов, узел A окончательно сдастся и перейдет в режим Bus Off.
Что другие узлы думают об узле A? – После каждого флага активной ошибки, переданного узлом A, остальные узлы повышают значения своих счетчиков пассивной ошибки на 1 пункт. За всё то время, что потребуется узлу A для перехода в режим Bus Off, значения счетчиков ошибок получения остальных узлов не превысят границы Error Passive, т.е. 127. Это значение будет уменьшаться на 1 пункт при каждом корректном получении сообщения. Однако узел А будет оставаться в режиме Bus Off.
Большинство контроллеров CAN будут предоставлять биты статуса (и соответствующие прерывания) для двух состояний:
• «Предупреждение об ошибке» (Error Warning) – значение одного или обеих счетчиков ошибок превысило 96 пунктов
• Bus Off, как описано выше.
Некотрые, но не все (!), контроллеры также предоставляют бит для состояния Error Passive. Немногие контроллеры также предоставляют прямой доступ к счетчикам ошибок.
Привычка контроллеров CAN автоматически переотправлять сообщения при возникновении ошибок иногда может раздражать. На рынке имеется как минимум один контроллер (SJA1000 от Philips), поддерживающий полное ручное управление обработкой ошибок.
Режимы сбоев шины
Стандарт ISO 11898 перечисляет несколько режимов сбоев кабеля шины CAN:
1.CAN_H прерван
2.CAN_L прерван
3.CAN_H короткозамкнутый на напряжение батаре
4.CAN_L короткозамкнутый на землю
5.CAN_H короткозамкнутый на землю
6.CAN_L короткозамкнутый на напряжение батареи
7.CAN_L короткозамкнутый на провод
8.CAN_H и CAN_L прерваны в одном и том же месте
9.Потеря соединения с оконечной нагрузкой сети
Для сбоев 1–6 и 9 «рекомендовано», чтобы шина сохраняла работоспособность путём снижения соотношения сигнал/шум (S/N), а в случае сбоя 8 – чтобы исходная подсистема сохранила работоспособность. Для сбоя 7 существует «опциональная» возможность сохранения работоспособности путём снижения соотношения сигнал/шум (S/N).
На практике система CAN, построенная на приемопередатчиках типа 82C250, не сохранит работоспособность при сбоях 1–7, а при сбоях 8–9 может как сохранить, так и не сохранить.
Существуют «устойчивые к сбоям» драйверы, такие как TJA1053, способные обрабатывать все сбои. Обычно за эту устойчивость приходится платить ограничением максимальной скорости; для TJA1053 она составляет 125 кбит/с.
По материалам компании Kvaser . С оригинальными текстами на английском языке можно ознакомиться на сайте компании Kvaser , перейдя по этой ссылке .
Five mechanisms to detect an error
To detect corrupted messages, the CAN protocol defines five mechanisms: bit monitoring, monitoring of the message format (Form Check), monitoring of the bit coding (Stuff Check), evaluation of the acknowledgement (ACK Check) and verifying the checksum (Cyclic Redundancy Check).
Tasks for sender and receiver
The bit monitoring and ACK check error detection mechanisms are performed by the sender. Independent of acceptance filtering, the receivers perform the form check, stuff check and cyclic redundancy check. The figure “Error Detection” shows which fields of a data or remote frame are affected by the individual error detection mechanisms.
Stuff check,
Receiver
The stuff check serves to check the bit stream. The CAN protocol specifies that the sender must transmit a complementary bit after five homogeneous bits — for synchronization purposes. There is a stuffing error if more than five homogeneous contiguous bits are received.
Bit monitoring,
Sender
Within the framework of bit monitoring, the sender compares the sent bit level with the actual bus level. A bit error exists if the sender detects a discrepancy between the two levels. Bit monitoring ensures that all global errors and all local errors occurring at the sender are detected.
Form check,
Receiver
The form check serves to check the format of a CAN message. Each CAN message always exhibits the same bit sequences at certain positions. They are the CRC delimiter, ACK delimiter and EOF. Senders always transmit these message components recessively. A format error exists if a receiver detects a dominant bus level within one of these message components in the Form Check.
Cyclic Redundancy Check (CRC),
Receiver
In the cyclic redundancy check (CRC) the polynomial R(x) associated with the arriving data or remote frame should equal a multiple of the generator polynomial G(x) specified by ISO 11898-1. If this is not the case (CRC error), then the data or remote frame was corrupted during its transmission.
ACK check,
Sender
The acknowledgement mechanism defined in the CAN protocol specifies that all receivers must acknowledge every arriving CAN message right after the cyclic redundancy check. A single positive acknowledgement is sufficient to signal to the sender that at least one receiver received the CAN message it transmitted correctly. If not a single positive acknowledgement arrives at the sender, then an acknowledgement error has occurred (ACK error).
Last modified: Wednesday, 22 September 2021, 4:09 PM
Полевая шина CAN (Controller Area Network) характеризуется высокими скоростью передачи данных и помехоустойчивостью, а также способностью обнаруживать любые возникающие ошибки. Не удивительно, что благодаря этому CAN сегодня широко используется в таких областях, как автомобильный и железнодорожный транспорт, промышленная автоматика, авиация, системы доступа и контроля. По данным ассоциации CiA (CAN in Automation, www.can-cia.de), в настоящее время в эксплуатации находится около 300 млн CAN-узлов по всему миру. В Германии CAN-шина занимает первое место по популярности среди остальных полевых шин. В данной статье приводится общее описание и технические характеристики CAN-шины и описывается логика ее работы. Кроме того, приводится описание встроенных модулей CAN, автономных контроллеров на примере микроконтроллеров (МК) Infineon, трансиверов и дросселей. Рассматриваются средства разработки устройств с CAN-шиной.
Общая тенденция в области автоматизации состоит в замене традиционной централизованной системы управления на распределенное управление путем размещения интеллектуальных датчиков и исполнительных механизмов рядом с управляемым процессом. Это вызвано ростом числа проводов связи, увеличением количества соединений, сложностью диагностики ошибок и проблемами с надежностью. Связь между узлами такой системы осуществляется с помощью полевой шины. CAN — это система связи для многоконтроллерных систем. Рассмотрим более подробно преимущества CAN и причины, по которым CAN приобретает все большее распространение.
Испытанный стандарт. Протокол CAN активно используется уже более 20 лет, что очень важно для таких консервативных областей как железнодорожный транспорт или судостроение. CAN был разработан в 1980 г. фирмой Robert Bosch для автомобильной промышленности. CAN-интерфейс регламентирован международными стандартами ISO 11898 для высокоскоростных и ISO 11519-1 для низкоскоростных приложений.Низкая стоимость определяется хорошим соотношением цена/производительность, также широкой доступностью CAN-контроллеров на рынке.Надежность определяется линейной структурой шины и равноправностью ее узлов, так называемой мультимастерностью (Multi Master Bus), при которой каждый узел CAN может получить доступ к шине. Любое сообщение может быть послано одному или нескольким узлам. Все узлы одновременно считывают с шины одну и ту же информацию, и каждый из них решает, принять данное сообщение или игнорировать его. Одновременный прием очень важен для синхронизации в системах управления. Отказавшие узлы отключаются от обмена по шине.
Высокая помехоустойчивость достигается благодаря подавлению синфазных помех дифференциальным приемопередатчиком, работе встроенных механизмов обнаружения ошибок (одна необнаруженная ошибка за 1000 лет при ежедневной 8-часовой работе сети на скорости 500 Кбит/с), повтору ошибочных сообщений, отключению неисправных узлов от обмена по шине и устойчивости к электромагнитным помехам.
Гибкость достигается за счет простого подключения к шине и отключения от шины CAN-узлов, причем общее число узлов не лимитировано протоколом нижнего уровня. Адресная информация содержится в сообщении и совмещена с его приоритетом, по которому осуществляется арбитраж. В процессе работы возможно изменение приоритета передаваемого сообщения. Следует также отметить возможность программирования частоты и фазы передаваемого сигнала и арбитраж, не разрушающий структуру сообщений при конфликтах. На физическом уровне есть возможность выбора разнотипных линий передачи данных: от дешевой витой пары до оптоволоконной линии связи.
Работа в реальном времени становится возможной благодаря механизмам сетевого взаимодействия (мультимастерность, широковещание, побитовый арбитраж) в сочетании с высокой скоростью передачи данных (до 1 Мбит/с), быстрой реакцией на запрос передачи и изменяемой длиной сообщения от 0 до 8 байт.
Приложения CAN
CAN является идеальным решением для любого приложения, где микроконтроллеры обмениваются сообщениями друг с другом и с удаленными периферийными устройствами. Изначально CAN использовался в автомобилях для обеспечения критичного по времени управления и обмена информацией между двигателем и коробкой передач при гарантированном времени ожидания сообщения и допуске каждого из участников сети к работе с текущими данными. Наряду с достаточно дорогими высокоскоростными решениями существуют и экономичные решения для подключения к сети инерционных устройств, которые работают в шкале времени сотен микросекунд (система управления дверьми, подъемник окна, управление зеркалом). При этом мощные жгуты электрических проводов заменяются двухпроводной CAN-сетью, узлами которой являются, в том числе, тормозные огни и указатели поворота.
Широкое применение CAN нашел в промышленной автоматике, где имеется большое число устройств управления, датчиков, механизмов, электроприводов и других объектов, которые связаны единым технологическим циклом (системы отопления и кондиционирования, насосы, конвейеры, лифты, эскалаторы, транспортеры и т. д.). Важной особенностью таких систем является возможность диагностики и управления объектами, расположенными на большой территории, по адаптивным алгоритмам. В результате достигается существенное уменьшение потребляемой мощности, шума, износа оборудования. Подобная картина наблюдается и в железнодорожных бортовых системах, где решающую роль играет обмен данными между подсистемами при наборе скорости, торможении, управлении дверьми и диагностике.
Физический уровень
Физический уровень CAN-шины представляет собой соединение «монтажное И» между всеми устройствами, подключенными к ней. Дифференциальные сигнальные линии называются CAN_H и CAN_L и в статическом состоянии находятся под потенциалом 2,5 В. Лог. 1 (рецессивный бит) обозначает состояние шины, при котором уровень на линии CAN_H выше, чем уровень CAN_L. При лог. 0 (доминантный бит) уровень на линии CAN_H ниже, чем уровень CAN_L. Принято следующее соглашение о состоянии шины: пассивное состояние шины соответствует уровню лог. 1, а активное — уровню лог. 0. Когда сообщения не передаются по шине, она находится в пассивном состоянии. Передача сообщения всегда начинается с доминантного бита. Логика работы шины соответствует «проводному И»: доминантный бит «0» подавляет рецессивный бит «1» (рис. 1).
Рис. 1. Логика работы CAN шины
При физической реализации конкретного проекта с CAN необходимо определить свойства шины и ее узлов: где располагаются обрабатывающие устройства, какими свойствами они обладают, какие датчики и исполнительные механизмы присутствуют в системе, являются они интеллектуальными или нет, что можно сказать об их физическом расположении. В зависимости от условий эксплуатации могут использоваться однопроводная линия (в пределах печатной платы), двухпроводная линия, витая пара или волоконно-оптическая линия. При дифференциальном методе формирования сигналов двухпроводная линия позволяет значительно повысить помехоустойчивость. При использовании дифференциальных напряжений CAN-сеть продолжает функционировать в чрезвычайно шумной среде или при обрыве одной из сигнальных линий. Даже при простой витой паре дифференциальные входы CAN эффективно нейтрализуют шум.
Максимальная скорость передачи данных составляет 1 Мбит/с при длине шины 40 м и около 40 Кбит/с при длине шины 1000 м.
Арбитраж узлов CAN-шины
CAN имеет много уникальных свойств, отличающих его от других шин. В протоколе CAN осуществляется посылка сообщений по общей CAN-шине, при этом отсутствуют адреса отправителя и получателя сообщения. Каждый узел постоянно «просматривает» шину и осуществляет локальную фильтрацию при приеме, используя битовые маски, и решает, какие сообщения извлекать из шины.
В результате узел принимает и обрабатывает только те сообщения, которые предназначены именно для него.
Каждое сообщение имеет свой приоритет, значение которого содержится в идентификаторе сообщения. Кроме того, идентификаторы используются для обозначения типа сообщения. Сообщению с младшим номером идентификатора соответствует высший приоритет; наивысшим приоритетом обладает сообщение с идентификатором, состоящим полностью из нулей. Передача сообщения начинается с отправки на шину идентификатора. Если доступ к шине требуют несколько сообщений, то сначала будет передано сообщение с наиболее высоким приоритетом, то есть с меньшим значением идентификатора, независимо от других сообщений и текущего состояния шины. Каждый узел перед передачей сообщения проверяет, работает ли узел с более высоким приоритетом. Если да, то он возвращается в состояние приемника и пытается передать сообщение в другое время. Это свойство имеет особое значение при использовании в системах управления реального времени, поскольку значение приоритета жестко определяет время ожидания.
Если передача узла А приостанавливается узлом B, посылающим сообщение с более высоким приоритетом, то, как только шина освободится, будет сделана другая попытка передачи сообщения от узла A. Этот принцип получил название CSMA/CA: Carrier Sense Multiple Access/Collision Avoidance (общий доступ с опросом/предотвращение конфликтов). Такой режим в отличие от Ethernet не позволяет конфликтующим узлам в шине выяснять отношения, а сразу выявляет победителя и сокращает время обмена.
Итак, благодаря арбитражу шины сообщение с высшим приоритетом передается первым, обеспечивая функционирование системы в реальном масштабе времени и быструю передачу информации. Распределение приоритетов между различными типами сообщений задается разработчиком при проектировании сети.
Формат сообщений
Если не учитывать процедуру повтора сообщения, принятого с ошибкой, существует два вида связи между узлами: один узел передает информацию, а другой получает, или узел A запрашивает узел B о данных и получает ответ.
Рис. 2. Кадр данных (Data Frame)
Для передачи данных служит кадр данных —
Data Frame (рис. 2), который содержит:
- идентификатор, указывающий на тип сообщения («скорость_двигателя», «температура_масла») и на приоритет доступа к шине. Поле идентификатора содержит различное количество бит в зависимости от разновидности протокола: в стандартном формате CAN V2.0A предусмотрен 11-разрядный идентификатор, а в расширенном CAN V2.0B — 29-разрядный;
- поле данных, содержащее соответствую-щее сообщение («скорость_двигателя»= 6000 об/мин, «температура_масла»=110 °C) длиной до восьми байт;
- два байта контрольной суммы —
Cyclic Redundancy Check (CRC) для выявления и коррекции ошибок передачи.
Для запроса информации узел CAN использует кадр запроса данных Remote Frame (рис. 3), который содержит:
- идентификатор, определяющий тип запрашиваемой информации («скорость_ двигателя», «температура_масла») и приоритет сообщения;
- два байта контрольной суммы
CRC.
Рис. 3. Кадр запроса данных Remote Frame
В этом случае за идентификатором не следуют данные и код длины данных не имеет прямого отношения к количеству байт данных. Узел, которому предложено передать информацию (датчик температуры масла), передает кадр данных, содержащий требуемую информацию. Таким образом, если узел А направляет узлу В кадр запроса с идентификатором «температура_масла», то узел В опрашивает датчик температуры и направляет узлу А кадр данных, содержащий идентификатор «температура_масла» и требуемую информацию.
Дополнительная информация, содержащаяся в кадре, позволяет определить формат и синхронизацию протокола передачи сообщения и тип посылки:
- какое сообщение послано — запрос о данных или собственно данные определяют бит удаленного запроса передачи (RTR для 11-разрядного идентификатора и SRR для 29-разрядного);
- код длины данных, сообщающий, сколько байтов данных содержит сообщение; все узлы принимают кадр данных, но те из них, которым эта информация не нужна, ее не сохраняют;
- для обеспечения синхронизации и контроля кадр содержит поля начала кадра Start of Frame, конца кадра End of Frame и подтверждения Acknowledgement Field;
- вход в режим синхронизации на шине осуществляется первым битом поля Start of Frame, далее синхронизация поддерживается фронтом при смене уровня посылаемых битов;
- используется механизм битстаффинга — вставка дополнительного бита при следующих подряд пяти нулях или единицах.
Обнаружение ошибок
Сигнализация об ошибках происходит путем передачи кадра ошибки Error Frame. Он инициируется любым узлом, обнаружившим ошибку. CAN-контроллеры используют метод статистической обработки ошибок. Каждый узел содержит счетчики ошибок при передаче и приеме Transmit Error Counter и Receive Error Counter. Если передатчик или приемник обнаруживают ошибку, значение соответствующего счетчика увеличивается. Когда значение счетчика превышает некоторый предел, текущая передача прерывается. Узел выдает сигнал об ошибке в виде Error Frame, где выставляет активный доминантный флаг ошибки длиной 6 бит. После этого узел, передача которого была прервана, повторяет сообщение. Ненадежным или частично поврежденным узлам разрешено посылать лишь пассивный рецессивный флаг ошибки.
В CAN существует несколько разновидностей ошибок. Из них три типа на уровне сообщений:
- CRC Error — ошибка контрольной суммы (при несовпадении принятой в поле CRC и вычисленной контрольных сумм).
- Form Error — ошибка формата кадра при несоответствии принятого сообщения формату CAN.
- Acknowledgement Error — ошибка подтверждения приема сообщения, если ни один из узлов не подтвердил правильного получения сообщения.
Кроме того, существует два типа ошибок на битовом уровне:
- Bit Error — обнаружение активным узлом расхождения между посланным в шину уровнем и фактическим значением за счет реализации узлом механизма самоконтроля.
- Stuff Error — наличие в поле сообщения шести следующих подряд бит 0 или 1 (ошибка битстаффинга).
Благодаря этим механизмам обнаружения и коррекции ошибок вероятность пропуска ошибки крайне мала. Например, при скорости 500 Кбит/с, загруженности шины 25 % и использовании в течение 2000 часов в год возникает лишь одна необнаруженная ошибка за 1000 лет. Кроме того, в шине невозможна ситуация блокировки неисправным узлом работы всей сети. Такие узлы обнаруживаются и отключаются от обмена по шине.
Разновидности CAN
В настоящее время доступны различные устройства с CAN-интерфейсом, которые помимо передачи данных из одной точки в другую позволяют реализовать синхронизацию процессов и обслуживание по приоритетам. Более ранние реализации CAN-контроллеров используют кадры с 11-разрядным идентификатором и возможностью адресации до 2048 сообщений и соответствуют спецификации CAN V. 2.0A. Такие контроллеры носят название Basic CAN и характеризуются сильной загруженностью центрального процессора (ЦПУ), так как каждое входящее сообщение запоминается в памяти и ЦПУ решает, нужны ему данные сообщения или нет (рис. 4). Контроллеры Basic CAN содержат один передающий буфер и один или два приемных буфера сообщений. Чтобы послать или получить сообщение, требуется задействовать ЦПУ через прерывания «сообщение_послано» и «сообщение_получено». В результате проверки каждого входящего сообщения загрузка ЦПУ очень велика, что ограничивает реальную скорость обмена по сети. По этой причине такие контроллеры используются в сетях CAN с низкой скоростью обмена и/или малым количеством сообщений.
Рис. 4. Структура контроллера Basic CAN
Большинство выпускаемых сегодня CAN-контроллеров используют расширенные кадры сообщений с идентификатором длиной 29 разрядов, что позволяет адресовать до 536 млн сообщений. Такие контроллеры соответствуют спецификации CAN V. 2.0B (active) и называются контроллеры Full-CAN. В них предусмотрен буфер для нескольких сообщений, причем каждое сообщение имеет свою маску, и фильтрация осуществляется по соответствию идентификатора маске.
В случае Full-CAN ЦПУ максимально разгружено, поскольку не обрабатывает ненужные сообщения (рис. 5). При приеме сообщения с идентификатором, соответствующим маске, оно запоминается в специальной зоне двухпортового ОЗУ, и работа ЦПУ прерывается. Full-CAN имеет также специальный тип сообщения, которое означает: «у кого бы ни находилась эта информация, пожалуйста, пошлите ее сейчас же». Контроллер Full-CAN автоматически прослушивает все сообщения и посылает запрошенную информацию.
Рис. 5. Структура контроллера Full-CAN
До недавнего времени в промышленности был широко распространен Basic CAN с 11-разрядным идентификатором. Этот протокол допускает простую связь между микроконтроллерами и периферийными устройствами при скорости обмена вплоть до 250 Кбит/с. Однако при стремительном удешевлении CAN-контроллеров использование Full-CAN стало оправданным и для связи с медленными устройствами. Если в промышленных приложениях требуется высокоскоростной (до 1 Мбит/с) обмен данными, то непременно следует использовать Full-CAN.
Элементная база для CAN
На самом нижнем уровне CAN-шины находится собственно двухпроводная линия с терминальными резисторами. Далее для повышения помехоустойчивости расположен дифференциальный приемопередатчик — трансивер. На следующем уровне — контроллер со встроенным модулем или автономный модуль CAN, подключаемый к главному контроллеру через параллельный или последовательный порт. Связь с узлами CAN, осуществляющими обмен информацией, ведется через линии портов микроконтроллеров. CAN-контроллеры осуществляют процедуру приема-передачи данных и соединяются с шиной двумя сигналами: RxD для приема с шины и TxD для передачи на шину. Реализация CAN-шины с помощью микроконтроллеров Infineon представлена на рис. 6.
Рис. 6. Реализация CAN-шины с помощью микроконтроллеров Infineon
Микроконтроллеры с CAN-модулем
Одним из факторов, обеспечивших популярность CAN, является богатый выбор и доступная цена элементной базы различных производителей — Infineon, Motorola, Microchip, Philips и др.
В данной статье упор сделан на элементную базу Infineon. Такое решение основано, в частности, на результатах опроса, проводимого на сайте Keil Software (www.keil.com) для микроконтроллерных платформ 8051/251/С166. На вопрос, какой микроконтроллер со встроенным CAN вы используете, по выборке из 2111 респондентов ответы распределились согласно табл. 1.
Таблица 1. Результаты опроса: «Какой микроконтроллер со встроенным CAN вы используете?»
Результат | Фирма | Тип микроконтроллера |
18% | Infineon | C505C/C515C |
28% | Infineon | C16x |
13% | Dallas | DS80C390 |
13% | Philips | 591/592/598 |
22% | Atmel/Temic | T89C51CC01 |
6% | ST Micro | ST10 |
Фирма Infineon выпускает продукты во всех классах цена/производительность. В настоящее время доступны как 8-разрядные контроллеры C505CA, C515C, так и 16-разрядные: C161CS, C164CI, C167CR, 167CS (табл. 2). Самым дешевым кристаллом с CAN является C505CA. МК C161CS и C167СS содержат два CAN-модуля. Самый мощный и дорогой микроконтроллер TriCore TC1775 также содержит реконфигурируемый модуль TwinCAN с двумя модулями CAN на 32 сообщения. TriCore — это первый 32-разрядный микроконтроллер Infineon с архитектурой DSP, оптимизированный для встроенных приложений реального времени, который заменяет собой МК, процессор DSP и заказную микросхему ASIC.Встроенный модуль соответствует спецификации CAN V2.0 B active и содержит память на 15 сообщений для приема/передачи с собственными идентификаторами, битами состояния и управления. Кроме того, он содержит регистры маски для фильтрации входящих сообщений и оснащен двумя приемными буферами. Встроенный модуль CAN позволяет строить системы с разнообразными задачами, используя минимальное количество микросхем внешнего интерфейса. Подключение любого из микроконтроллеров Infineon к CAN-шине осуществляется по одним и тем же принципам. Пример соединения C167CR с CAN-шиной представлен на рис. 7.
Таблица 2. CAN-микроконтроллеры фирмы Infineon
Тип | Версия CAN | Кол-во сообщ. | CAN-модуль | Корпус | Примечание |
С505СА | V2.0 B | 15 | 1 x CAN | MQFP-44 | 8 bit MC |
С151С | V2.0 B | 15 | 1 x CAN | MQFP-80 | 8 bit MC |
С161СS | V2.0 B | 30 | 2 x CAN | TQFP-128 | 16 bit MC |
C164CI | V2.0 B | 15 | 1 x CAN | MQFP-80 | 16 bit MC |
C167CR | V2.0 B | 15 | 1 x CAN | MQFP-144 | 16 bit MC |
C167CS | V2.0 B | 30 | 2 x CAN | MQFP-144 | 16 bit MC |
TC1775 | V2.0 B | 32 | TwinCAN | BGA-329 | 32 bit MC |
SAE81C90 | V2.0 A | 16 | 1 x CAN | PLCC-44 | Stand Alone |
SAE81C91 | V2.0 A | 16 | 1 x CAN | PLCC-28 | Stand Alone |
SAK82C900 | V2.0 B | 32 | TwinCAN | P-DSO-28 | Stand Alone |
Кроме того, следует сказать также несколько слов о МК фирмы Philips — одного из родоначальников элементной базы CAN. На смену устаревшему автономному CAN-контроллеру Philips PCA82C200 пришел полностью совместимый с ним контроллер SJA1000, работающий со стандартом CAN V2.0 B. Необходимо отметить, что PCA82C200 поддерживает только стандарт CAN V2.0 A и способен передавать и принимать только стандартный CAN-протокол, то есть при приеме расширенного кадра он генерирует ошибку и может разрушить всю сеть. В SJA1000 за счет поддержки стандарта PeliCAN (чтение и запись счетчиков ошибок, программирование их количественного порога) значительно расширены возможности по управлению CAN.
Рис. 7. Пример соединения МК С167CR c CAN-шиной
В результате объединения SJA1000 с ядром XA появился 16-разрядный МК XAC3 с интегрированным CAN-интерфейсом. Совместимый с 8051 режим микроконтроллера Philips XA позволяет осуществить простой переход от 8-разрядной архитектуры 8051 к 16-разрядной, что особенно важно для сохранения преемственности программного обеспечения. Среди 8-разрядных МК следует отметить также Philips P80C592, P8xC591 и 8xCE598.
Motorola тоже предлагает широкий спектр микроконтроллеров с интегрированным CAN-модулем: от самых дешевых 8-разрядных МК 68HC05X до 32-разрядного Power PC MPC555 с дуальным CAN V2.0 B.
Продолжение следует
How CAN Handles Errors
Error handling is built into into the CAN protocol and is of great importance for the performance of a CAN system. The error handling aims at detecting errors in messages appearing on the CAN bus, so that the transmitter can retransmit an erroneous message. Every CAN controller along a bus will try to detect errors within a message. If an error is found, the discovering node will transmit an Error Flag, thus destroying the bus traffic. The other nodes will detect the error caused by the Error Flag (if they haven’t already detected the original error) and take appropriate action, i.e. discard the current message.
Each node maintains two error counters: the Transmit Error Counter and the Receive Error Counter. There are several rules governing how these counters are incremented and/or decremented. In essence, a transmitter detecting a fault increments its Transmit Error Counter faster than the listening nodes will increment their Receive Error Counter. This is because there is a good chance that it is the transmitter who is at fault! When any Error Counter raises over a certain value, the node will first become “error passive”, that is, it will not actively destroy the bus traffic when it detects an error, and then “bus off”, which means that the node doesn’t participate in the bus traffic at all.
Using the error counters, a CAN node can not only detect faults but also perform error confinement.
Error Detection Mechanisms
The CAN protocol defines no less than five different ways of detecting errors. Two of these work at the bit level, and the other three at the message level.
-
- Bit Monitoring
- Bit Stuffing
- Frame Check
- Acknowledgement Check
- Cyclic Redundancy Check
1. Bit Monitoring
Each transmitter on the CAN bus monitors (i.e. reads back) the transmitted signal level. If the bit level actually read differs from the one transmitted, a Bit Error is signaled. (No bit error is raised during the arbitration process.)
2. Bit Stuffing
When five consecutive bits of the same level have been transmitted by a node, it will add a sixth bit of the opposite level to the outgoing bit stream. The receivers will remove this extra bit. This is done to avoid excessive DC components on the bus, but it also gives the receivers an extra opportunity to detect errors: if more than five consecutive bits of the same level occurs on the bus, a Stuff Error is signaled.
3. Frame check
Some parts of the CAN message have a fixed format, i.e. the standard defines exactly what levels must occur and when. (Those parts are the CRC Delimiter, ACK Delimiter, End of Frame, and also the Intermission, but there are some extra special error checking rules for that.) If a CAN controller detects an invalid value in one of these fixed fields, a Form Error is signaled.
4. Acknowledgement Check
All nodes on the bus that correctly receives a message (regardless of their being “interested” in the contents or not) are expected to send a dominant level in the so-called Acknowledgement Slot in the message. The transmitter will transmit a recessive level here. If the transmitter can’t detect a dominant level in the ACK slot, an Acknowledgement Error is signaled.
5. Cyclic Redundancy Check
Each message features a 15-bit Cyclic Redundancy Checksum (CRC), and any node that detects a different CRC in the message than what it has calculated itself will signal a CRC Error.
Error Confinement Mechanisms
Every CAN controller along a bus will try to detect the errors outlined above within each message. If an error is found, the discovering node will transmit an Error Flag, thus destroying the bus traffic. The other nodes will detect the error caused by the Error Flag (if they haven’t already detected the original error) and take appropriate action, i.e. discard the current message.
Each node maintains two error counters: the Transmit Error Counter and the Receive Error Counter. There are several rules governing how these counters are incremented and/or decremented. In essence, a transmitter detecting a fault increments its Transmit Error Counter faster than the listening nodes will increment their Receive Error Counter. As was mentioned, this is because there is a good chance that it is the transmitter who is at fault!
A node starts out in Error Active mode. When any one of the two Error Counters raises above 127, the node will enter a state known as Error Passive and when the Transmit Error Counter raises above 255, the node will enter the Bus Off state.
- An Error Active node will transmit Active Error Flags when it detects errors.
- An Error Passive node will transmit Passive Error Flags when it detects errors.
- A node which is Bus Off will not transmit anything on the bus at all.
The rules for increasing and decreasing the error counters are somewhat complex, but the principle is simple: transmit errors give 8 error points, and receive errors give 1 error point. Correctly transmitted and/or received messages cause the counter(s) to decrease.
Example (slightly simplified): Let’s assume that node A on a bus has a bad day. Whenever A tries to transmit a message, it fails (for whatever reason). Each time this happens, it increases its Transmit Error Counter by 8 and transmits an Active Error Flag. Then it will attempt to retransmit the message.. and the same thing happens.
When the Transmit Error Counter raises above 127 (i.e. after 16 attempts), node A goes Error Passive. The difference is that it will now transmit Passive Error Flags on the bus. A Passive Error Flag comprises 6 recessive bits, and will not destroy other bus traffic – so the other nodes will not hear A complaining about bus errors. However, A continues to increase its Transmit Error Counter. When it raises above 255, node A finally gives in and goes Bus Off.
What do the other nodes think about node A? – For every active error flag that A transmitted, the other nodes will increase their Receive Error Counters by 1. By the time that A goes Bus Off, the other nodes will have a count in their Receive Error Counters that is well below the limit for Error Passive, i.e. 127. This count will decrease by one for every correctly received message. However, node A will stay bus off.
Most CAN controllers will provide status bits (and corresponding interrupts) for two states:
- “Error Warning” – one or both error counters are above 96
- Bus Off, as described above.
Some – but not all! – controllers also provide a bit for the Error Passive state. A few controllers also provide direct access to the error counters.
The CAN controller’s habit of automatically retransmitting messages when errors have occurred can be annoying at times. There is at least one controller on the market (the SJA1000 from Philips) that allows for full manual control of the error handling.
Bus Failure Modes
The ISO 11898 standard enumerates several failure modes of the CAN bus cable:
- CAN_H interrupted
- CAN_L interrupted
- CAN_H shorted to battery voltage
- CAN_L shorted to ground
- CAN_H shorted to ground
- CAN_L shorted to battery voltage
- CAN_L shorted to CAN_H wire
- CAN_H and CAN_L interrupted at the same location
- Loss of connection to termination network
For failures 1-6 and 9, it is “recommended” that the bus survives with a reduced S/N ratio, and in case of failure 8, that the resulting subsystem survives. For failure 7, it is “optional” to survive with a reduced S/N ratio.
In practice, a CAN system using 82C250-type transceivers will not survive failures 1-7, and may or may not survive failures 8-9.
There are “fault-tolerant” drivers, like the TJA1053, that can handle all failures though. Normally you pay for this fault tolerance with a restricted maximum speed; for the TJA1053 it is 125 kbit/s.