busmust_sys/
types.rs

1use std::ffi::c_void;
2use std::os::raw::c_char;
3use bitfield_struct::bitfield;
4
5/// Size (in bytes) of an error description string.
6pub const BM_ERROR_DESC_MAX_SIZE: usize = 255;
7
8/// Size (in bytes) of BM Data header, which contains type, routing, length and timestamp.
9pub const BM_DATA_HEADER_SIZE: usize = 8;
10
11/// Size (in bytes) of BM Data payload, which contains a concrete message in `CAN-FD` | `LIN` | `FLEXRAY` | `...` type.
12pub const BM_DATA_PAYLOAD_MAX_SIZE: usize = 72;
13
14/// Size (in bytes) of BM Data, which contains a header and payload.
15pub const BM_DATA_MAX_SIZE: usize = BM_DATA_HEADER_SIZE + BM_DATA_PAYLOAD_MAX_SIZE;
16
17/// Busmust library log level, see [super::api::BM_SetLogLevel] for details.
18#[repr(u32)]
19pub enum BMLogLevel {
20    /// Show nothing on debug console
21    None = 0,
22    /// Show only ERR level messages on debug console, note this is the default level for release versions
23    Error = 1,
24    /// Show ERR and WRN level messages on debug console
25    Warning = 2,
26    /// Show ERR|WRN|INF level messages on debug console
27    Info = 3,
28    /// Show all messages on debug console, including debug messages, note this is NOT available for release versions
29    Debug = 4
30}
31
32bitflags!{
33    /// Busmust Device capability flags, retrieved when enumerating devices using [super::api::BM_Enumerate].
34    #[repr(transparent)]
35    pub struct BMCapability: u16 {
36        /// No capability
37        const NONE = 0x0000;
38        /// The device is capable of handling LIN messages
39        const LIN = 0x0001;
40        /// The device is capable of handling CAN messages
41        const CAN = 0x0002;
42        /// The device is capable of handling CAN-FD (and CAN) messages
43        const CAN_FD = 0x0004;
44        /// The device is capable of handling FlexRay messages
45        const FLEXRAY = 0x0008;
46        /// The device is capable of handling ModBus messages
47        const MODBUS = 0x0010;
48        /// The device is capable of handling Ethernet messages
49        const ETHERNET = 0x0020;
50        /// Typically used for masking the CAP fields when programming
51        const ALL = 0xFFFF;
52    }
53}
54
55/// Busmust data type flags, must be given in [BMData].
56#[repr(u8)]
57#[derive(Debug, Copy, Clone)]
58pub enum BMDataType {
59    /// Unknown data type
60    Unknown = 0,
61    /// LIN message data type
62    Lin = 1,
63    /// CAN or CAN-FD message data type (check FDF flag further)
64    Can = 2,
65    /// FlexRay message data type
66    FlexRay = 3,
67    /// MODBUS message data type
68    ModBus = 4,
69    /// Ethernet message data type
70    Ethernet = 5,
71    /// ACK from bus, which indicates `TXCMPLT` event if this is [BMDataType::Can]
72    Ack = 8
73}
74
75
76/// Busmust device & operation status, most APIs would return a status code to indicate the result of an operation
77#[repr(u32)]
78#[derive(Debug, Copy, Clone)]
79pub enum BMStatus {
80    /// SUCCESS: No error occurred
81    Ok = 0x00000,
82    /// Low level Transmit buffer is full
83    XmtFull = 0x00001,
84    /// Bus overrun (the device cannot keep up with the high bus throughput)
85    Overrun = 0x00002,
86    /// CAN Bus communication is light, see ISO11898 for details
87    BusLight = 0x00004,
88    /// CAN Bus communication is in warning state, see ISO11898 for details
89    BusWarning = 0x00008,
90    /// CAN node is in passive state, see ISO11898 for details
91    BusPassive = 0x40000,
92    /// CAN node failed to transmit message within specified time, the node might be in PASSIVE or BUS-OFF state
93    BusTimeout = 0x80000,
94    /// CAN bus is in BUS-OFF state, see ISO11898 for details
95    BusOff = 0x00010,
96    /// CAN bus error occurred
97    AnyBusError = 0x00008 | 0x00004 | 0x00010 | 0x40000,
98    /// Receive buffer is empty, this might NOT be an error if you use BM API in polling mode
99    ReceiveBufferEmpty = 0x00020,
100    /// BM API internal queue overrun
101    QueueOverrun = 0x00040,
102    /// High level Transmit queue is full
103    TransmitQueueFull = 0x00080,
104    /// Reserved
105    RegTest = 0x00100,
106    /// Reserved
107    NoDriver = 0x00200,
108    /// Hardware is in use (opened by another application)
109    HardwareInUse = 0x00400,
110    /// Reserved
111    NetInUse = 0x00800,
112    /// Hardware error or invalid hardware handle
113    HardwareError = 0x01400,
114    /// Invalid bus
115    InvalidBus = 0x01800,
116    /// Invalid client
117    InvalidClient = 0x01C00,
118    /// Out of resources
119    OutOfResources = 0x02000,
120    /// Invalid parameter type in API call
121    InvalidParameterType = 0x04000,
122    /// Invalid parameter value in API call
123    InvalidParameterValue = 0x08000,
124    /// Unknown error
125    Unknown = 0x10000,
126    /// Invalid data received/transmitted
127    InvalidData = 0x20000,
128    /// Reserved
129    Caution = 0x2000000,
130    /// The device/library is not initialized
131    NotInitialized = 0x4000000,
132    /// Invalid operation
133    InvalidOperation = 0x8000000
134}
135
136#[repr(u32)]
137#[derive(Debug, Copy, Clone)]
138/// CAN mode IDs, used by [super::api::BM_SetCanMode] to change the operation mode of CAN device.
139pub enum BMCanMode {
140    /// The device is running normally (with the capability to handle CAN and CAN-FD messages
141    Normal = 0x00,
142    /// The device is logically disconnected from CAN bus
143    BufOff = 0x01,
144    /// The device is looping back messages internally without impacting the physical CAN bus
145    InternalLoopback = 0x02,
146    /// The device is receiving messages without impacting the physical CAN bus (do not send ACKs to the bus)
147    ListenOnly = 0x03,
148    /// The device is under configuration and temporarily disconnected from CAN bus, For Internal usage only
149    Configuration = 0x04,
150    /// The device is looping back messages externally, all transmitted messages are echoed by the device itself
151    ExternalLoopback = 0x05,
152    /// The device is running normally (with the capability to handle only classical CAN2.0 messages
153    Classic = 0x06,
154    /// Reserved
155    Restricted = 0x07
156}
157
158/// Terminal resistor values, used by [super::api::BM_SetTerminalRegister] to change the terminal resistor of CAN device.
159#[repr(u32)]
160#[derive(Debug, Copy, Clone)]
161pub enum BMTerminalResistor {
162    /// Reserved, currently unsupported
163    Auto = 0,
164    /// Currently unsupported
165    Enabled60 = 60,
166    /// 120Ohm
167    Enabled120 = 120,
168    /// Disable terminal resistor
169    Disabled = 0xFFFF
170}
171
172/// CAN Message type flags, used in [BMCanMessage]
173#[repr(u8)]
174pub enum BMMessageFlags {
175    /// Normal CAN message
176    Normal = 0,
177    /// Extended CAN message
178    Extended = 1,
179    /// Remote CAN message
180    Remote = 2,
181    /// CAN-FD bitrate switching is enabled
182    BitRateSwitching = 4,
183    /// CAN-FD message
184    CanFD = 8,
185    /// Reserved for gateways
186    Esi = 16
187}
188
189/// CAN RX filter type IDs, used in [BMRxFilter]
190#[repr(u32)]
191pub enum BMRxFilterType {
192    /// Invalid (unused) RX filter entry
193    Invalid = 0,
194    /// Basic RX filter, traditional acceptance filter based on message ID mask
195    Basic = 1,
196    /// Busmust advanced RX filter, check both message ID and message payload
197    Advanced = 2,
198    /// Busmust E2E RX filter, accept only messages that passed E2E checking
199    E2EPass = 3,
200    /// Busmust E2E RX filter, accept only messages that failed E2E checking (for debugging purpose)
201    E2EFail = 4
202}
203
204/// CAN TX task type IDs, used in [BMTxTask].
205#[repr(u32)]
206pub enum BMTxTaskType {
207    /// Invalid (unused) TX task entry
208    Invalid = 0,
209    /// Basic TX task, send fixed ID and fixed payload
210    Fixed = 1,
211    /// Self-increment Data TX task
212    IncData = 2,
213    /// Self-increment ID TX task
214    IncId = 3,
215    /// Random Data TX task
216    RandomData = 4,
217    /// Random ID TX task
218    RandomId = 5
219}
220
221/// CAN runtime statistics item IDs, used in [super::api::BM_GetStatus].
222#[repr(u32)]
223pub enum BMStatType {
224    /// Invalid statistics item
225    None = 0,
226    /// Number of TX messages
227    TxMessage = 1,
228    /// Number of RX messages
229    RxMessage = 2,
230    /// Number of TX bytes
231    TxByte = 3,
232    /// Number of RX bytes
233    RxByte = 4,
234    /// Number of TX errors
235    TxError = 5,
236    /// Number of RX errors
237    RxError = 6
238}
239
240/// ISO-TP operation mode.
241#[repr(u32)]
242pub enum BMIsotpMode {
243    /// Default mode: normal (non-extended-addressing) UDS client(tester)
244    NormalTester = 0,
245    /// Normal (non-extended-addressing) UDS server(ECU)
246    NormalEcu = 1,
247    /// Currently unsupported: extended-addressing UDS client(tester)
248    ExtendedTester = 2,
249    /// Currently unsupported: extended-addressing UDS server(ECU)
250    ExtendedEcu = 3
251}
252
253/// Busmust data header, each BMData contains a header which indicates payload information.
254#[bitfield(u16)]
255#[derive(Default)]
256pub struct BMDataHeader {
257    /// Data type, see BMDataType for details.
258    #[bits(4)]
259    pub kind: u8,
260    /// Reserved flags, keep 0
261    #[bits(4)]
262    pub flags: u8,
263    /// Destination channel ID, starting from zero, used by TX data to indicate the hardware about the target port.
264    #[bits(4)]
265    pub dchn: u8,
266    /// Source channel ID, starting from zero, used by RX data to indicate the application about the source port.
267    #[bits(4)]
268    pub schn: u8,
269}
270
271/// Busmust data, abstract structure which holds concrete payload messages of various types (i.e. CAN messages).
272#[repr(C)]
273pub struct BMData {
274    /// Data header, see [BMDataHeader] for details.
275    pub header: BMDataHeader,
276    /// Length in bytes of the payload only (header excluded).
277    pub length: u16,
278    /// 32-bit device local high precision timestamp in microseconds.
279    pub timestamp: u32,
280    /// Buffer holding concrete message payload (i.e. a CAN message in [BMCanMessage] format).
281    pub payload: [u8; BM_DATA_PAYLOAD_MAX_SIZE],
282}
283
284/// Busmust CAN Message ID.
285/// You could also use an `u32`, but please take care of memory alignments.
286#[bitfield(u32)]
287pub struct BMMessageId {
288    /// Standard ID
289    #[bits(11)]
290    pub sid: u16,
291    /// Extended ID
292    #[bits(18)]
293    pub eid: u32,
294    /// Reserved
295    #[bits(1)]
296    pub reserved1: bool,
297    /// Reserved
298    #[bits(2)]
299    pub reserved2: u8,
300}
301
302/// Busmust TX CAN Message control fields.
303/// The first few fields (until FDF) are bit compatible with [BMRxMessageCtrl].
304#[bitfield(u32)]
305pub struct BMTxMessageCtrl {
306    /// CAN message DLC(0-F), note this is not the message length
307    #[bits(4)]
308    pub dlc: u8,
309    /// This message is an extended CAN message
310    #[bits(1)]
311    pub ide: bool,
312    /// This message is a remote CAN message
313    #[bits(1)]
314    pub rtr: bool,
315    /// This message requires CAN-FD bitrate switching
316    #[bits(1)]
317    pub brs: bool,
318    /// This message is a CAN-FD CAN message
319    #[bits(1)]
320    pub fdf: bool,
321    /// Reserved for gateways
322    #[bits(1)]
323    pub esi: bool,
324    /// Reserved for hardware sync
325    #[bits(23)]
326    pub seq: u32,
327}
328
329/// Busmust RX CAN Message control fields.
330/// The first few fields (until FDF) are bit compatible with [BMTxMessageCtrl].
331#[bitfield(u32)]
332pub struct BMRxMessageCtrl {
333    /// CAN message DLC(0-F), note this is not the message length
334    #[bits(4)]
335    pub dlc: u8,
336    /// This message is an extended CAN message
337    #[bits(1)]
338    pub ide: bool,
339    /// This message is a remote CAN message
340    #[bits(1)]
341    pub rtr: bool,
342    /// This message requires CAN-FD bitrate switching
343    #[bits(1)]
344    pub brs: bool,
345    /// This message is a CAN-FD CAN message
346    #[bits(1)]
347    pub fdf: bool,
348    /// Reserved for gateways
349    #[bits(1)]
350    pub esi: bool,
351    /// Reserved
352    #[bits(2)]
353    pub reserved1: u8,
354    /// By which RX filter the message was accepted
355    #[bits(5)]
356    pub rx_filter: u8,
357    /// Reserved
358    #[bits(16)]
359    pub reserved2: u16,
360}
361
362/// Busmust CAN Message control fields.
363#[repr(C)]
364#[derive(Copy, Clone)]
365pub union BMMessageCtrl {
366    /// TX control
367    pub tx: BMTxMessageCtrl,
368    /// RX control
369    pub rx: BMRxMessageCtrl
370}
371
372/// Busmust CAN Message concrete type, usually used as payload of [BMData].
373/// The total length of this structure is 72B, it supports both classic and FD CAN messages.
374#[repr(C)]
375#[derive(Copy, Clone)]
376pub struct BMCanMessage {
377    /// CAN message ID, see [BMMessageId] for details.
378    pub mid: BMMessageId,
379    /// CAN message control fields, whether TX or RX is taken depends on the message direction.
380    pub ctrl: BMMessageCtrl,
381    /// CAN message payload
382    pub payload: [u8; 64]
383}
384
385/// Channel information, created when enumerating devices by [super::api::BM_Enumerate] and used when opening device by [super::api::BM_OpenEx]
386#[repr(C)]
387#[derive(Copy, Clone)]
388pub struct BMChannelInfo {
389    /// Device full name, for display purpose
390    pub name: [c_char; 64],
391    /// Device SN
392    pub sn: [u8; 16],
393    /// Device UID
394    pub uid: [u8; 12],
395    /// Device Firmware Version
396    pub version: [u8; 4],
397    /// Device VID
398    pub vid: u16,
399    /// Device PID
400    pub pid: u16,
401    /// Port ID (0-7) of the device, note a multi-port device is enumerated as multiple dedicated [BMChannelInfo] entries
402    pub port: u16,
403    /// Device Capability flags, see [BMCapability] for details.
404    pub cap: BMCapability,
405    /// Reserved
406    pub reserved: [u8; 4]
407}
408
409/// CAN channel status detailed information, retrieved by calling [super::api::BM_GetStatus], see ISO11898 for details.
410#[repr(C)]
411#[derive(Debug)]
412pub struct BMCanStatusInfo {
413    /// The CAN channel is in BUS-OFF state
414    pub tx_bus_off: u8,
415    /// Reserved
416    reserved: u8,
417    /// The CAN channel is in TX bus passive state
418    pub tx_bus_passive: u8,
419    /// The CAN channel is in RX bus passive state
420    pub rx_bus_passive: u8,
421    /// The CAN channel is in TX warn state
422    pub tx_warn: u8,
423    /// The CAN channel is in RX warn state
424    pub rx_warn: u8,
425    /// TX Bus Error counter
426    pub tx_errors: u8,
427    /// RX Bus Error counter
428    pub rx_errors: u8
429}
430
431/// CAN channel bitrate configuration, used by [super::api::BM_SetBitrate]
432#[repr(C)]
433pub struct BMBitrate {
434    /// Nominal bitrate in kbps, default as 500, note this is the only valid bitrate in CAN CLASSIC mode.
435    pub n_bitrate: u16,
436    /// Data bitrate in kbps, default as 500, note this is ignored in CAN CLASSIC mode.
437    pub d_bitrate: u16,
438    /// Nominal sample position (percentage, 0-100, default as 75
439    pub n_sample_pos: u8,
440    /// Data sample position (percentage, 0-100, default as 75
441    pub d_sample_pos: u8,
442    // Setting any of the fields below would override the n_bitrate configuration
443    /// CAN controller clock in Mhz, default as 0
444    pub clock_freq: u8,
445    /// Reserved
446    pub reserved: u8,
447    /// Nominal BTR0 register value, note this value is calculated using clock_freq, which might not be 16MHz
448    pub n_btr0: u8,
449    /// Nominal BTR1 register value, note this value is calculated using clock_freq, which might not be 16MHz
450    pub n_btr1: u8,
451    /// Data BTR0 register value, note this value is calculated using clock_freq, which might not be 16MHz
452    pub d_btr0: u8,
453    /// Data BTR1 register value, note this value is calculated using clock_freq, which might not be 16MHz
454    pub d_btr1: u8
455}
456
457/// CAN channel RX filter item structure, used by [super::api::BM_SetRxFilters]
458/// The filter support masking ID, flags and payload according to its type,
459/// in order for a message to be accepted, all the fields are masked using AND logic:
460/// `(flags & filter.flags_mask == filter.flags_value) AND (ID & filter.id_mask == filter.id_value) AND (payload & filter.payload_mask == filter.payload_value)`
461#[repr(C)]
462pub struct BMRxFilter {
463    /// Type ID of the RX filter, see [BMRxFilterType] for details.
464    pub kind: u8,
465    /// Reserved
466    pub unused: u8,
467    /// CAN message control Flags masks, see [BMMessageFlags] for details.
468    pub flags_mask: u8,
469    /// CAN message control Flags values, see [BMMessageFlags] for details.
470    pub flags_value: u8,
471    /// Reserved
472    pub reserved: [u8; 4],
473    pub id_mask: u32,
474    /// CAN message ID values, see [BMMessageId] for details.
475    pub id_value: u32,
476    /// CAN message payload masks, for CAN-FD messages, only the first 8 bytes are checked.
477    pub payload_mask: [u8; 8],
478    /// CAN message payload values, for CAN-FD messages, only the first 8 bytes are checked.
479    pub payload_value: [u8; 8]
480
481}
482
483#[repr(C)]
484pub struct BMTxTaskIncDataPattern {
485    /// Start bit of data increment, currently only 8-bit aligned value is accepted
486    pub start_bit: u16,
487    /// Number of bits of data increment, currently only 32 is accepted
488    pub nbits: u8,
489    /// Number of bits of data increment, currently only 32 is accepted
490    pub format: u8,
491    /// Minimum value of the Increment range
492    pub min: u32,
493    /// Maximum value of the Increment range
494    pub max: u32,
495    /// Step of the Increment range
496    pub step: u32
497}
498
499#[repr(C)]
500pub struct BMTxTaskIncIdPattern {
501    /// Minimum value of the Increment range
502    pub min: u32,
503    /// Maximum value of the Increment range
504    pub max: u32,
505    /// Step of the Increment range
506    pub step: u32
507}
508
509#[repr(C)]
510pub struct BMTxTaskRndDataPattern {
511    /// Start bit of data Random, currently only 8-bit aligned value is accepted
512    pub start_bit: u16,
513    /// Number of bits of data Random, currently only 32 is accepted
514    pub nbits: u8,
515    /// 0x80=Intel, 0x00=Motorola
516    pub format: u8,
517    /// Minimum value of the Random range
518    pub min: u32,
519    /// Maximum value of the Random range
520    pub max: u32,
521    /// Seed of the Random range
522    pub seed: u32
523}
524
525#[repr(C)]
526pub struct BMTxTaskRndIdPattern {
527    /// Minimum value of the Increment range
528    pub min: u32,
529    /// Maximum value of the Increment range
530    pub max: u32,
531    /// Seed of the Random range
532    pub seed: u32
533}
534
535/// CAN channel TX task item structure, used by [super::api::BM_SetTxTasks]
536/// Once the CAN device is armed with TX tasks, it will try to parse the TX task and send CAN messages automatically.
537/// The difference with a software triggered CAN message in BusMaster is that hardware triggered CAN messages are
538/// more precise in time and could reach a higher throughput.
539#[repr(C)]
540pub struct BMTxTask {
541    /// Type ID of the TX task, see [BMTxTaskType] for details.
542    pub kind: u8,
543    /// Reserved
544    pub unused: u8,
545    /// CAN message control Flags, see [BMMessageFlags] for details.
546    pub flags: u8,
547    /// Length of payload in bytes (not DLC)
548    pub length: u8,
549    /// Index of E2E (in E2E table, currently unsupported
550    pub e2e: u8,
551    /// Reserved
552    pub reserved: u8,
553    /// ms delay between rounds
554    pub cycle: u16,
555    /// num of cycles
556    pub n_rounds: u16,
557    /// messages per round
558    pub n_messages: u16,
559    /// CAN message arbitration ID, see [BMMessageId] for details.
560    pub id: u32,
561    /// TX task pattern data
562    pub pattern: u32,
563    //TODO
564    /// Default payload data, note this is also the template payload of the unchanged part in a volatile TX task
565    pub payload: [u8; 64]
566}
567
568/// ISO-TP status report, used by ISO-TP operation callback function.
569#[repr(C)]
570pub struct BMIsoTPStatus {
571    /// Currently always 0x01
572    pub version: u8,
573    /// Current flow control status, 0=continue, 1=wait, 2=overflow, ff=timeout,
574    pub flow_control: u8,
575    /// Current flow control status, i.e. 30 00 00
576    pub st_min: u8,
577    /// Current block size
578    pub block_size: u8,
579    /// Number of transferred bytes by now.
580    pub transferred_bytes: u32,
581    /// Number of total bytes indicated by ISO-TP FF or SF.
582    pub total_bytes: u32,
583    /// Current timestamp reported by device.
584    pub timestamp: u32,
585    /// Reserved for future.
586    pub reserved: [u32; 4]
587}
588
589/// Callback type for ISO-TP status callback
590type BMIsotpCallbackHandle = extern fn(status: *const BMIsoTPStatus, arg: *const c_void);
591
592#[repr(C)]
593pub struct BMIsotpTimeoutConfig {
594    /// `A` timeout in milliseconds: `=N_As` if writing as tester or reading as ECU, otherwise `=N_Ar`
595    pub a: u16,
596    /// `B` timeout in milliseconds: `=N_Bs` if writing as tester or reading as ECU, otherwise `=N_Br`
597    pub b: u16,
598    /// `C` timeout in milliseconds: `=N_Cs` if writing as tester or reading as ECU, otherwise `=N_Cr`
599    pub c: u16
600}
601
602
603#[repr(C)]
604pub struct BMIsotpFlowControlConfig {
605    /// STmin raw value (0x00-0x7F or 0xF1-0xF9) if Busmust device is acting as UDS server
606    pub st_min: u8,
607    /// Block size if CAN card is acting as UDS server, 0 means no further FC is needed
608    pub block_size: u8,
609    /// Flow control frame length in bytes
610    pub fc_frame_length: u8,
611    /// Reserved
612    pub reserved: u8
613}
614
615#[repr(C)]
616/// ISOTP Protocol (See ISO15765-2 for details) configuration.
617pub struct BMIsotpConfig {
618    /// Currently must be set to 0x01
619    pub version: u8,
620    /// Currently only 0 is supported: normal (non-extended-addressing) UDS client(tester)
621    pub mode: u8,
622    /// Tester(UDS Client) Timeout configuration
623    pub tester_timeout: BMIsotpTimeoutConfig,
624    /// ECU(UDS Server) Timeout configuration
625    pub ecu_timeout: BMIsotpTimeoutConfig,
626    /// Current flow control status, i.e. 30 00 00
627    pub flow_control: BMIsotpFlowControlConfig,
628    /// UDS Address in Extended Addressing mode
629    pub extended_address: u8,
630    /// Enable padding for unused payload bytes
631    pub padding_enabled: u8,
632    /// Padding byte value (i.e. 0xCC) for unused payload bytes
633    pub padding_value: u8,
634    /// Enable long PDU (>4095), note if CAN message DLC>8, long PDU is enabled by default
635    pub long_pdu_enabled: u8,
636    /// Reserved for future
637    pub padding: [u8; 2],
638    /// Callback function when any progress is made, used typically by GUI to show progress bar
639    pub callback: BMIsotpCallbackHandle,
640    /// Callback user arg when any progress is made, used typically by GUI to show progress bar
641    pub callback_user_arg: *const c_void,
642    /// All tester messages will be formatted/checked using this template, configure CAN message ID and IDE/FDF flags here
643    pub tester_data_template: BMData,
644    /// All ECU messages will be formatted/checked using this template, configure CAN message ID and IDE/FDF flags here
645    pub ecu_data_template: BMData
646}