Автор:
Формат предназначен для формального описания матрицы сообщений CAN.
Формат позволяет описывать структуру сообщений CAN для стандартых и расширенных пакетов, подходит для описания прикладных протоколов таких как CANopen, J1939.
На основе формата J1939DBC выполняется генерация структур данных для обработки, диагностики и разбора сообщений CAN. Целью генерации могут быть исходные коды и заголовки Си, таблицы CSV, или SQL запросы на формирование и заполнение базы.
Формат применяется для формализованного обмена сообщениями CAN между оборудованием разных производителей.
Автоматический синтез структур данных позволяет свести к минимуму ошибки прораммиста, снизить расходы на разработку программ, снизить трудозатраты связанные с синхронизацией изменений в коде при обновлении версий протокола и состава оборудования.
$ gcc can_dbc.c -o dbc `pkg-config.exe --cflags --libs glib-2.0`
- sys/can.h -- структуры can_frame, can_filter и системные типы CAN
- canopen.h -- заголовок для разбора стандарта CANopen CiA
- can_j1939.h -- заголовок для разбора кадров стандарта SAE J1939
- can_ev.h -- основной заголовок, содержит макросы разбора кадров
- can_ev.c -- сериализация данных для CAN, протокол EV-1.0
- can_ev_proxy.c -- представление данных на устройстве EV-Gateway
- can_ev_modbus.c -- сериализация данных для RS-485 Modbus RTU, протокол EV-1.0
- can_ev_serial.c -- сериализация данных для UART point-to-point, протокол EV-1.0
- can_ev_mqtt.c -- сериализация данных для протокола MQTT (Message Queuing Telemetry Transport)
- can_ev_pcap.c -- экспорт данных в формат PCAP, Linktype = SocketCAN
- can_ev_json.c -- экспорт данных в формат JSON
- can_ev_sql.c -- экспорт данных в текстовый формат SQL
- can_j1850_crc.c -- расчет контрольной суммы кадра CRC-8/SAE-J1850, компактаня реализация
Формат тестовый. Состоит из строк. Строки могут группироваться. Каждая строка начинается с ключевого слова.
Для формального описания используются обозначения:
| выбор элемента из перечня вариантов
(* *) комментарий
[ ] - необязательный элемент
{ } - повторение 0 и более раз
VERSION: "EV 2023-03-25" (* Версия документа *)
NS_: (* Пространство имен *)
BS_: (* Характеристики линии CAN *)
BU_: (* Перечисление функциональных блоков, устройств на линии *)
BO_ ... (* Описание сообщений *)
SG_ ... (* Описание сигналов *)
SG_ ... (* Описание сигналов *)
'BS_:' [baudrate ':' BTR1 ',' BTR2] ;
BTR1 = unsigned_int ;
BTR2 = unsigned_int ;
'BU_:' {node_name} ;
node_name = C_identifyer ;
'BO_' message_id message_name ':' message_size transmitter {signal} ;
message_id = unsigned_int ; (* Идентификатор сообщения, число *)
message_name = C_identifyer ; (* Имя - идентифкатор для генерации *)
message_size = unsigned_int ; (* размер тела сообщения в байтах *)
transmitter = node_name | 'Vector_XXX' ; (* Идентификатор отправителя *)
'SG_' signal_name multiplexor_id ':' start_bit '|'
signal_size '@' byte_order value_type (factor ',' offset ')'
'[' minimum '|' maximum ']' unit receiver { ',' receiver } ;
signal_name = C_identifier ;
multiplexor_id = ' ' | 'M' | m multiplexer_switch_value ;
byte_order = '0' | '1' ; (* 0-little endian, 1-big endian *)
value_type = '+' | '-' ; (* + unsigned, - signed *)
unit = char_string ;
receiver = node_name | 'Vector_XXX' ;
Правила вычисления значений из числового формата
physical_value = raw_value * factor + offset;
raw_value = (physical_value - offset)/factor;
comment = 'CM_' object message_id node_name char_string ;
object = 'BU_'|'BO_'|'SG_' ;
'BA_DEF_' object attribute_name value_type Min_Max ;
value_type = 'INT' | 'STRING' | 'REAL' | 'ENUM' ; (* INT, STRING, float или REAL , ENUM *)
Min_Max (* диапазон значений *)
'BA_DEF_DEF_' attribute_name default_value ;
default_value (* начальное значение атрибута *)
'VAL_' message_id signal_name N “DefineN” . . . 0 “Define0”;
Предполагается использование некоторых стандартизованных атрибутов
GenMsgSendType -- Defines the send type of a message
Тип отсылки может включать два или три времени: задержка на активацию, периодичность сообщений и временная привязка (time-triggered communication).
enum GenMsgSendType {//!< Defines the send type of a message
_none,
_cyclic,
_triggered,
_cyclicIfActive,
_cyclicAndTriggered,
_cyclicIfActiveAndTriggered,
};
Определение:
BA_DEF BO_ "GenMsgSendType" ENUM "cyclic","triggered","cyclicIfActive","cyclicAndTriggered","cyclicIfActiveAndTriggered"
BA_DEF_DEF "GenMsgSendType" ""
GenMsgCycleTime -- Defines the cycle time of a message in ms.
BA_DEF BO_ "GenMsgCycleTime" INT 0 0 (* определение типа атрибута *)
BA_DEF_DEF "GenMsgCycleTime" 0 (* значение по умолчанию *)
GenMsgStartDelayTime -- Defines the allowed delay after startup this message must occure the first time in ms.
BA_DEF BO_ "GenMsgStartDelayTime" INT 0 0
BA_DEF_DEF "GenMsgStartDelayTime" 0
GenMsgDelayTime -- Defines the allowed delay for a message in ms.
BA_DEF BO_ "GenMsgDelayTime" INT 0 0
BA_DEF_DEF "GenMsgDelayTime" 0
VFrameFormat -- формат сообщения CAN
BA_DEF_ BO_ "VFrameFormat" ENUM "StandardCAN","ExtendedCAN","J1939PG";
BA_DEF_DEF_ "VFrameFormat" "";
ProtocolType -- Тип протокола: OBD2, J1939, CANopen ...
BA_DEF_ "ProtocolType" STRING ;
BA_DEF_DEF_ "ProtocolType" "";
GenSigStartValue -- Defines the value as long as no value is set/received for this signal.
BA_DEF SG_ "GenSigStartValue" INT 0 0
BA_DEF_DEF "GenSigStartValue" 0
Рекомендуемое приложение для редактирования и просмотра таблиц Kvaser Database Editor 3
Определения сигналов
SG_ name
преобразуются в набор определений и структур, состоящих из битовых полей.
#define name##_Type -- тип: 'signed' 'unsigned' 'float' 'double' 'Enumerated' 'Boolean' 'BitString' 'String' 'Octets' 'Date' 'Time' 'OID'
#define name##_Pos -- позиция поля в битах
#define name##_Bits -- длина поля в битах bit size
#define name##_Msk -- маска выделения сигнала ULL до 64 бит
#define name##_Factor -- множитель для отображения значения
#define name##_Offset
#define name##_Min -- минимальное значение
#define name##_Max -- максимальное значение
Идентификаторы системных типов данных (совместимые идентификаторами BACnet)
enum _SYS_TYPE { //!< базовые типы данных в протоколе BACnet и EV-1.0
_TYPE_NULL =0x0,//!< пустышка
_TYPE_BOOLEAN =0x1,//!< логическое значение
_TYPE_UNSIGNED =0x2,//!< целое без знака
_TYPE_SIGNED =0x3,//!< целое со знаком
_TYPE_REAL =0x4,//!< вещественное 32 бита
_TYPE_DOUBLE =0x5,//!< вещественное 64 бита
_TYPE_OCTETS =0x6,//!< байтовая строка
_TYPE_STRING =0x7,//!< текстовая строка UTF-8
_TYPE_BIT_STRING=0x8,//!< битовая строка
_TYPE_ENUMERATED=0x9,//!< перечисление
_TYPE_DATE =0xA,//!< дата или шаблон даты
_TYPE_TIME =0xB,//!< время с миллисекундах
_TYPE_OID =0xC,//!< уникальный идентификатор
};
Пример генерации определений:
#define GNSS_NMEA_1_byte2_Pos 16
#define GNSS_NMEA_1_byte2_Bits 8
#define GNSS_NMEA_1_byte2_Factor 1
#define GNSS_NMEA_1_byte2_Offset 0
Пример генерации структуры данных:
typedef struct _GNSS_NMEA_6 GNSS_NMEA_6_t;
struct _GNSS_NMEA_6 {
signed GNSS_NMEA_6_byte0 :8; // 0..7:
signed GNSS_NMEA_6_byte1 :8; // 8..15:
signed GNSS_NMEA_6_byte2 :8; // 16..23:
signed GNSS_NMEA_6_byte3 :8; // 24..31:
signed GNSS_NMEA_6_byte4 :8; // 32..39:
signed GNSS_NMEA_6_byte5 :8; // 40..47:
signed GNSS_NMEA_6_byte6 :8; // 48..55:
signed GNSS_NMEA_6_byte7 :8; // 56..63:
};