rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
mlg_types.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <concepts>
5#include <type_traits>
6
7// NOTE THAT Ordinals are part of logging serialization as described in
8// https://www.efianalytics.com/TunerStudio/docs/MLG_Binary_LogFormat_2.0.pdf
9namespace MLG::Types{
10
11/*
12 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
13 | Field Name | Offset | Length | Required | Value Description |
14 | | (bytes)| (bytes)| | |
15 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
16 | File Format | 0 | 6 | Yes | "MLVLG" padded by 0; Hex: x4D x4C x56 x4C x47 x00 |
17 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
18 | Format Version | 6 | 2 | Yes | Currently x00 x02 (future versions may increase) |
19 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
20 | Time Stamp | 8 | 4 | No | Unix 32-bit timestamp (seconds since epoch). If unavailable: x00 x00 x00|
21 | | | | | x00 |
22 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
23 | Info Data Start | 12 | 4 | No | Start offset after LoggerField[] and before Data Begin Index; set to 0 |
24 | | | | | if no Log Info Data |
25 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
26 | Data Begin Index | 16 | 4 | Yes | Address of 1st byte containing Type-Data pairs |
27 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
28 | Record Length | 20 | 2 | Yes | Length of a single data record (excluding Type-Pair overhead) |
29 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
30 | Num Logger Fields | 22 | 2 | Yes | Number of expected Logger Fields |
31 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
32 | Logger Field [] | 24 | 89*n | Yes | Array of (Num Logger Fields * 89) in length |
33 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
34 | Bit Field Names |24+n*89 | varies | No | Available if Logger Fields contain Bit Info |
35 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
36 | Info Data | varies | varies | No | Optional null-terminated string with informational data (firmware, date) |
37 +-------------------+--------+--------+----------+--------------------------------------------------------------------------+
38*/
39namespace Header {
40 constexpr size_t Size = 24;
41}
42
43/*
44 Only Scalar is currently supported and BitField is emulated via 1-byte Scalar:
45
46 +---------------+--------+--------+----------+--------------------------------------------------------------------------+
47 | Field Name | Offset | Length | Required | Value Description |
48 | | (bytes)| (bytes)| | |
49 +---------------+--------+--------+----------+--------------------------------------------------------------------------+
50 | Type | 0 | 1 | Yes | Value type: |
51 | | | | | 0=U08, 1=S08, 2=U16, 3=S16, 4=U32, 5=S32, 6=S64, 7=F32 |
52 +---------------+--------+--------+----------+--------------------------------------------------------------------------+
53 | Name | 1 | 34 | Yes | ASCII string, null terminated |
54 +---------------+--------+--------+----------+--------------------------------------------------------------------------+
55 | Units | 35 | 10 | Yes | ASCII string, null terminated |
56 +---------------+--------+--------+----------+--------------------------------------------------------------------------+
57 | Display Style | 45 | 1 | Yes | Display format: |
58 | | | | | 0=Float, 1=Hex, 2=Bits, 3=Date, 4=On/Off, 5=Yes/No, 6=High/Low, |
59 | | | | | 7=Active/Inactive, 8=True/False |
60 +---------------+--------+--------+----------+--------------------------------------------------------------------------+
61 | Scale | 46 | 4 | Yes | IEEE 754 float representing the scale applied to (raw + transform) |
62 +---------------+--------+--------+----------+--------------------------------------------------------------------------+
63 | Transform | 50 | 4 | Yes | IEEE 754 float representing any shift of raw value before scaling |
64 +---------------+--------+--------+----------+--------------------------------------------------------------------------+
65 | Digits | 54 | 1 | Yes | S08 representing the number of decimal places to display to the right |
66 +---------------+--------+--------+----------+--------------------------------------------------------------------------+
67 | Category | 55 | 34 | No | Optional category for logical grouping in MLV |
68 +---------------+--------+--------+----------+--------------------------------------------------------------------------+
69*/
70namespace Field {
71 constexpr size_t DescriptorSize = 89;
72
73 enum class Scalar : uint8_t {
74 U08 = 0,
75 S08 = 1,
76 U16 = 2,
77 S16 = 3,
78 U32 = 4,
79 S32 = 5,
80 S64 = 6,
81 F32 = 7,
82 unsupported = static_cast<uint8_t>(-1)
83 };
84
85 template<typename T>
87 using enum Scalar;
88 using CleanType = std::remove_const_t<T>;
89 constexpr auto resolvedType{[](){
90 if constexpr (std::is_integral_v<CleanType>) {
91 if constexpr (std::is_signed_v<CleanType>) {
92 if constexpr (sizeof(CleanType) == 1) { return S08; }
93 else if constexpr (sizeof(CleanType) == 2) { return S16; }
94 else if constexpr (sizeof(CleanType) == 4) { return S32; }
95 else if constexpr (sizeof(CleanType) == 8) { return S64; }
96 } else {
97 if constexpr (sizeof(CleanType) == 1) { return U08; }
98 else if constexpr (sizeof(CleanType) == 2) { return U16; }
99 else if constexpr (sizeof(CleanType) == 4) { return U32; }
100 }
101 }
102 else if constexpr (std::same_as<CleanType, float>) { return F32; }
103
104 return unsupported;
105 }()};
106 static_assert(resolvedType != unsupported, "Scalar type was not recognized as supported built in numeric type");
107 return resolvedType;
108 }
109
110 template<Scalar t>
111 consteval size_t sizeForType() {
112 constexpr auto s{[]{
113 switch (t) {
114 using enum Scalar;
115 case U08: case S08: return 1;
116 case U16: case S16: return 2;
117 case U32: case S32: case F32: return 4;
118 case S64: return 8;
119 default: return 0;
120 }
121 }()};
122 static_assert(s != 0, "Can not resolve Scalar type, check enum for new values that were left unhandled");
123 return s;
124 }
125}
126}
consteval size_t sizeForType()
Definition mlg_types.h:111
constexpr size_t DescriptorSize
Definition mlg_types.h:71
consteval Scalar resolveBuiltInNumberType()
Definition mlg_types.h:86
constexpr size_t Size
Definition mlg_types.h:40