odxtools 10.2.1__py3-none-any.whl → 10.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odxtools/cli/browse.py +4 -2
- odxtools/cli/compare.py +3 -3
- odxtools/compositecodec.py +1 -1
- odxtools/configdata.py +70 -0
- odxtools/configdatadictionaryspec.py +57 -0
- odxtools/configiditem.py +18 -0
- odxtools/configitem.py +85 -0
- odxtools/configrecord.py +146 -0
- odxtools/database.py +21 -0
- odxtools/dataiditem.py +18 -0
- odxtools/datarecord.py +132 -0
- odxtools/decodestate.py +1 -1
- odxtools/diagcommdataconnector.py +61 -0
- odxtools/diaglayers/diaglayer.py +8 -6
- odxtools/diagservice.py +10 -10
- odxtools/ecuconfig.py +89 -0
- odxtools/encryptcompressmethod.py +16 -3
- odxtools/externflashdata.py +21 -2
- odxtools/flashdata.py +40 -2
- odxtools/identvalue.py +16 -3
- odxtools/internflashdata.py +4 -0
- odxtools/isotp_state_machine.py +11 -11
- odxtools/itemvalue.py +77 -0
- odxtools/nameditemlist.py +2 -2
- odxtools/optionitem.py +79 -0
- odxtools/parameters/codedconstparameter.py +2 -3
- odxtools/readdiagcommconnector.py +79 -0
- odxtools/readparamvalue.py +52 -0
- odxtools/request.py +3 -3
- odxtools/response.py +8 -4
- odxtools/statemachine.py +3 -2
- odxtools/systemitem.py +23 -0
- odxtools/templates/diag_layer_container.odx-d.xml.jinja2 +4 -0
- odxtools/templates/ecu_config.odx-e.xml.jinja2 +38 -0
- odxtools/templates/flash.odx-f.xml.jinja2 +2 -2
- odxtools/templates/macros/printAudience.xml.jinja2 +3 -3
- odxtools/templates/macros/printChecksum.xml.jinja2 +1 -1
- odxtools/templates/macros/printCompuMethod.xml.jinja2 +2 -2
- odxtools/templates/macros/printConfigData.xml.jinja2 +39 -0
- odxtools/templates/macros/printConfigDataDictionarySpec.xml.jinja2 +22 -0
- odxtools/templates/macros/printConfigItems.xml.jinja2 +66 -0
- odxtools/templates/macros/printConfigRecord.xml.jinja2 +73 -0
- odxtools/templates/macros/printDOP.xml.jinja2 +5 -6
- odxtools/templates/macros/printDataRecord.xml.jinja2 +35 -0
- odxtools/templates/macros/printDiagCommDataConnector.xml.jinja2 +66 -0
- odxtools/templates/macros/printExpectedIdent.xml.jinja2 +1 -1
- odxtools/templates/macros/printFlashdata.xml.jinja2 +2 -2
- odxtools/templates/macros/printItemValue.xml.jinja2 +31 -0
- odxtools/templates/macros/printOwnIdent.xml.jinja2 +1 -1
- odxtools/templates/macros/printSecurity.xml.jinja2 +4 -4
- odxtools/templates/macros/printSegment.xml.jinja2 +1 -1
- odxtools/validbasevariant.py +62 -0
- odxtools/validityfor.py +16 -3
- odxtools/variantmatcher.py +4 -4
- odxtools/version.py +2 -2
- odxtools/writediagcommconnector.py +77 -0
- odxtools/writepdxfile.py +15 -0
- {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/METADATA +2 -1
- {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/RECORD +63 -39
- {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/WHEEL +1 -1
- {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/entry_points.txt +0 -0
- {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/licenses/LICENSE +0 -0
- {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/top_level.txt +0 -0
odxtools/optionitem.py
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import Any
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from .audience import Audience
|
7
|
+
from .configitem import ConfigItem
|
8
|
+
from .itemvalue import ItemValue
|
9
|
+
from .odxdoccontext import OdxDocContext
|
10
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
11
|
+
from .snrefcontext import SnRefContext
|
12
|
+
from .utils import dataclass_fields_asdict
|
13
|
+
|
14
|
+
|
15
|
+
@dataclass(kw_only=True)
|
16
|
+
class OptionItem(ConfigItem):
|
17
|
+
"""This class represents a OPTION-ITEM."""
|
18
|
+
|
19
|
+
physical_default_value: str | None = None
|
20
|
+
item_values: list[ItemValue] = field(default_factory=list)
|
21
|
+
write_audience: Audience | None = None
|
22
|
+
read_audience: Audience | None = None
|
23
|
+
|
24
|
+
@staticmethod
|
25
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "OptionItem":
|
26
|
+
kwargs = dataclass_fields_asdict(ConfigItem.from_et(et_element, context))
|
27
|
+
|
28
|
+
physical_default_value = et_element.findtext("PHYSICAL-DEFAULT-VALUE")
|
29
|
+
|
30
|
+
item_values = [
|
31
|
+
ItemValue.from_et(el, context) for el in et_element.iterfind("ITEM-VALUES/ITEM-VALUE")
|
32
|
+
]
|
33
|
+
|
34
|
+
write_audience = None
|
35
|
+
if (wa_elem := et_element.find("WRITE-AUDIENCE")) is not None:
|
36
|
+
write_audience = Audience.from_et(wa_elem, context)
|
37
|
+
|
38
|
+
read_audience = None
|
39
|
+
if (ra_elem := et_element.find("READ-AUDIENCE")) is not None:
|
40
|
+
read_audience = Audience.from_et(ra_elem, context)
|
41
|
+
|
42
|
+
return OptionItem(
|
43
|
+
physical_default_value=physical_default_value,
|
44
|
+
item_values=item_values,
|
45
|
+
write_audience=write_audience,
|
46
|
+
read_audience=read_audience,
|
47
|
+
**kwargs)
|
48
|
+
|
49
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
50
|
+
result = super()._build_odxlinks()
|
51
|
+
|
52
|
+
for item_value in self.item_values:
|
53
|
+
result.update(item_value._build_odxlinks())
|
54
|
+
if self.write_audience is not None:
|
55
|
+
result.update(self.write_audience._build_odxlinks())
|
56
|
+
if self.read_audience is not None:
|
57
|
+
result.update(self.read_audience._build_odxlinks())
|
58
|
+
|
59
|
+
return result
|
60
|
+
|
61
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
62
|
+
super()._resolve_odxlinks(odxlinks)
|
63
|
+
|
64
|
+
for item_value in self.item_values:
|
65
|
+
item_value._resolve_odxlinks(odxlinks)
|
66
|
+
if self.write_audience is not None:
|
67
|
+
self.write_audience._resolve_odxlinks(odxlinks)
|
68
|
+
if self.read_audience is not None:
|
69
|
+
self.read_audience._resolve_odxlinks(odxlinks)
|
70
|
+
|
71
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
72
|
+
super()._resolve_snrefs(context)
|
73
|
+
|
74
|
+
for item_value in self.item_values:
|
75
|
+
item_value._resolve_snrefs(context)
|
76
|
+
if self.write_audience is not None:
|
77
|
+
self.write_audience._resolve_snrefs(context)
|
78
|
+
if self.read_audience is not None:
|
79
|
+
self.read_audience._resolve_snrefs(context)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import warnings
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import Any
|
4
|
+
from typing import Any
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from typing_extensions import override
|
@@ -57,8 +57,7 @@ class CodedConstParameter(Parameter):
|
|
57
57
|
coded_value_raw=coded_value_raw, diag_coded_type=diag_coded_type, **kwargs)
|
58
58
|
|
59
59
|
def __post_init__(self) -> None:
|
60
|
-
self._coded_value =
|
61
|
-
AtomicOdxType, self.diag_coded_type.base_data_type.from_string(self.coded_value_raw))
|
60
|
+
self._coded_value = self.diag_coded_type.base_data_type.from_string(self.coded_value_raw)
|
62
61
|
|
63
62
|
@override
|
64
63
|
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import Any
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from .diagcomm import DiagComm
|
7
|
+
from .exceptions import odxrequire
|
8
|
+
from .odxdoccontext import OdxDocContext
|
9
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
10
|
+
from .readparamvalue import ReadParamValue
|
11
|
+
from .snrefcontext import SnRefContext
|
12
|
+
|
13
|
+
|
14
|
+
@dataclass(kw_only=True)
|
15
|
+
class ReadDiagCommConnector:
|
16
|
+
read_param_values: list[ReadParamValue]
|
17
|
+
|
18
|
+
# exactly one of the following attributes must be non-None
|
19
|
+
read_diag_comm_ref: OdxLinkRef | None = None
|
20
|
+
read_diag_comm_snref: str | None = None
|
21
|
+
|
22
|
+
# exactly one of the following attributes must be non-None
|
23
|
+
read_data_snref: str | None = None
|
24
|
+
read_data_snpathref: str | None = None
|
25
|
+
|
26
|
+
@property
|
27
|
+
def read_diag_comm(self) -> DiagComm | None:
|
28
|
+
return self._read_diag_comm
|
29
|
+
|
30
|
+
@staticmethod
|
31
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ReadDiagCommConnector":
|
32
|
+
read_param_values = [
|
33
|
+
ReadParamValue.from_et(el, context)
|
34
|
+
for el in et_element.iterfind("READ-PARAM-VALUES/READ-PARAM-VALUE")
|
35
|
+
]
|
36
|
+
|
37
|
+
read_diag_comm_ref = OdxLinkRef.from_et(et_element.find("READ-DIAG-COMM-REF"), context)
|
38
|
+
read_diag_comm_snref = None
|
39
|
+
if (read_diag_comm_snref_elem := et_element.find("READ-DIAG-COMM-SNREF")) is not None:
|
40
|
+
read_diag_comm_snref = odxrequire(read_diag_comm_snref_elem.attrib.get("SHORT-NAME"))
|
41
|
+
|
42
|
+
read_data_snref = None
|
43
|
+
if (read_data_snref_elem := et_element.find("READ-DATA-SNREF")) is not None:
|
44
|
+
read_data_snref = odxrequire(read_data_snref_elem.attrib.get("SHORT-NAME"))
|
45
|
+
|
46
|
+
read_data_snpathref = None
|
47
|
+
if (read_data_snpathref_elem := et_element.find("READ-DATA-SNPATHREF")) is not None:
|
48
|
+
read_data_snpathref = odxrequire(read_data_snpathref_elem.attrib.get("SHORT-NAME-PATH"))
|
49
|
+
|
50
|
+
return ReadDiagCommConnector(
|
51
|
+
read_param_values=read_param_values,
|
52
|
+
read_diag_comm_ref=read_diag_comm_ref,
|
53
|
+
read_diag_comm_snref=read_diag_comm_snref,
|
54
|
+
read_data_snref=read_data_snref,
|
55
|
+
read_data_snpathref=read_data_snpathref,
|
56
|
+
)
|
57
|
+
|
58
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
59
|
+
odxlinks = {}
|
60
|
+
|
61
|
+
for rpv in self.read_param_values:
|
62
|
+
odxlinks.update(rpv._build_odxlinks())
|
63
|
+
|
64
|
+
return odxlinks
|
65
|
+
|
66
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
67
|
+
self._read_diag_comm = None
|
68
|
+
if self.read_diag_comm_ref is not None:
|
69
|
+
self._read_diag_comm = odxlinks.resolve(self.read_diag_comm_ref, DiagComm)
|
70
|
+
|
71
|
+
for rpv in self.read_param_values:
|
72
|
+
rpv._resolve_odxlinks(odxlinks)
|
73
|
+
|
74
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
75
|
+
# read_diag_comm_snref cannot be uniquely resolved ahead of
|
76
|
+
# time as it depends on the diag layer which is used
|
77
|
+
|
78
|
+
for rpv in self.read_param_values:
|
79
|
+
rpv._resolve_snrefs(context)
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import Any
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from .exceptions import odxrequire
|
7
|
+
from .odxdoccontext import OdxDocContext
|
8
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
9
|
+
from .snrefcontext import SnRefContext
|
10
|
+
|
11
|
+
|
12
|
+
@dataclass(kw_only=True)
|
13
|
+
class ReadParamValue:
|
14
|
+
phys_constant_value: str
|
15
|
+
|
16
|
+
# exactly one of the following attributes must be non-None
|
17
|
+
in_param_if_snref: str | None = None
|
18
|
+
in_param_if_snpathref: str | None = None
|
19
|
+
|
20
|
+
semantic: str
|
21
|
+
|
22
|
+
@staticmethod
|
23
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ReadParamValue":
|
24
|
+
phys_constant_value = odxrequire(et_element.findtext("PHYS-CONSTANT-VALUE"))
|
25
|
+
|
26
|
+
in_param_if_snref = None
|
27
|
+
if (in_param_if_snref_elem := et_element.find("IN-PARAM-IF-SNREF")) is not None:
|
28
|
+
in_param_if_snref = odxrequire(in_param_if_snref_elem.attrib.get("SHORT-NAME"))
|
29
|
+
|
30
|
+
in_param_if_snpathref = None
|
31
|
+
if (in_param_if_snpathref_elem := et_element.find("IN-PARAM-IF-SNPATHREF")) is not None:
|
32
|
+
in_param_if_snpathref = odxrequire(
|
33
|
+
in_param_if_snpathref_elem.attrib.get("SHORT-NAME-PATH"))
|
34
|
+
|
35
|
+
semantic = odxrequire(et_element.attrib.get("SEMANTIC"))
|
36
|
+
|
37
|
+
return ReadParamValue(
|
38
|
+
phys_constant_value=phys_constant_value,
|
39
|
+
in_param_if_snref=in_param_if_snref,
|
40
|
+
in_param_if_snpathref=in_param_if_snpathref,
|
41
|
+
semantic=semantic,
|
42
|
+
)
|
43
|
+
|
44
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
45
|
+
odxlinks: dict[OdxLinkId, Any] = {}
|
46
|
+
return odxlinks
|
47
|
+
|
48
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
49
|
+
pass
|
50
|
+
|
51
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
52
|
+
pass
|
odxtools/request.py
CHANGED
@@ -113,8 +113,8 @@ class Request(IdentifiableElement):
|
|
113
113
|
|
114
114
|
return encode_state.coded_message
|
115
115
|
|
116
|
-
def decode(self, message: bytes) -> ParameterValueDict:
|
117
|
-
decode_state = DecodeState(coded_message=message)
|
116
|
+
def decode(self, message: bytes | bytearray) -> ParameterValueDict:
|
117
|
+
decode_state = DecodeState(coded_message=bytes(message))
|
118
118
|
param_values = self.decode_from_pdu(decode_state)
|
119
119
|
|
120
120
|
if not isinstance(param_values, dict):
|
@@ -129,5 +129,5 @@ class Request(IdentifiableElement):
|
|
129
129
|
def decode_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
130
130
|
return composite_codec_decode_from_pdu(self, decode_state)
|
131
131
|
|
132
|
-
def coded_const_prefix(self, request_prefix: bytes = b'') ->
|
132
|
+
def coded_const_prefix(self, request_prefix: bytes = b'') -> bytearray:
|
133
133
|
return composite_codec_get_coded_const_prefix(self, request_prefix)
|
odxtools/response.py
CHANGED
@@ -109,14 +109,18 @@ class Response(IdentifiableElement):
|
|
109
109
|
context.response = None
|
110
110
|
context.parameters = None
|
111
111
|
|
112
|
-
def encode(self,
|
113
|
-
|
112
|
+
def encode(self,
|
113
|
+
coded_request: bytes | bytearray | None = None,
|
114
|
+
**kwargs: ParameterValue) -> bytearray:
|
115
|
+
encode_state = EncodeState(
|
116
|
+
triggering_request=bytes(coded_request) if coded_request is not None else None,
|
117
|
+
is_end_of_pdu=True)
|
114
118
|
|
115
119
|
self.encode_into_pdu(physical_value=kwargs, encode_state=encode_state)
|
116
120
|
|
117
121
|
return encode_state.coded_message
|
118
122
|
|
119
|
-
def decode(self, message: bytes) -> ParameterValueDict:
|
123
|
+
def decode(self, message: bytes | bytearray) -> ParameterValueDict:
|
120
124
|
decode_state = DecodeState(coded_message=message)
|
121
125
|
param_values = self.decode_from_pdu(decode_state)
|
122
126
|
|
@@ -151,5 +155,5 @@ class Response(IdentifiableElement):
|
|
151
155
|
|
152
156
|
print(parameter_info(self.free_parameters), end="")
|
153
157
|
|
154
|
-
def coded_const_prefix(self, request_prefix: bytes = b'') ->
|
158
|
+
def coded_const_prefix(self, request_prefix: bytes = b'') -> bytearray:
|
155
159
|
return composite_codec_get_coded_const_prefix(self, request_prefix)
|
odxtools/statemachine.py
CHANGED
@@ -97,8 +97,9 @@ class StateMachine:
|
|
97
97
|
self._state_chart = state_chart
|
98
98
|
self._active_state = state_chart.start_state
|
99
99
|
|
100
|
-
def execute(
|
101
|
-
|
100
|
+
def execute(
|
101
|
+
self, service: "DiagService", **service_params: Any
|
102
|
+
) -> Generator[bytes | bytearray, bytes | bytearray | ParameterValueDict, None]:
|
102
103
|
"""Run a diagnostic service and update the state machine
|
103
104
|
depending on the outcome.
|
104
105
|
|
odxtools/systemitem.py
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from xml.etree import ElementTree
|
4
|
+
|
5
|
+
from .configitem import ConfigItem
|
6
|
+
from .exceptions import odxrequire
|
7
|
+
from .odxdoccontext import OdxDocContext
|
8
|
+
from .utils import dataclass_fields_asdict
|
9
|
+
|
10
|
+
|
11
|
+
@dataclass(kw_only=True)
|
12
|
+
class SystemItem(ConfigItem):
|
13
|
+
"""This class represents a SYSTEM-ITEM."""
|
14
|
+
|
15
|
+
sysparam: str
|
16
|
+
|
17
|
+
@staticmethod
|
18
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "SystemItem":
|
19
|
+
kwargs = dataclass_fields_asdict(ConfigItem.from_et(et_element, context))
|
20
|
+
|
21
|
+
sysparam = odxrequire(et_element.attrib.get("SYSPARAM"))
|
22
|
+
|
23
|
+
return SystemItem(sysparam=sysparam, **kwargs)
|
@@ -1,6 +1,10 @@
|
|
1
1
|
{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MIT
|
4
|
+
#
|
5
|
+
# This template writes an .odx-d file containing a diag layer container, i.e.,
|
6
|
+
# a collection of descriptions of the diagnostic interactions which are
|
7
|
+
# supported by variants of ECUs.
|
4
8
|
-#}
|
5
9
|
{%- import('macros/printOdxCategory.xml.jinja2') as poc %}
|
6
10
|
{%- import('macros/printEcuSharedData.xml.jinja2') as pecusd -%}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
#
|
5
|
+
# This template writes an .odx-e file containing an ECU-CONFIG description
|
6
|
+
# for variant coding.
|
7
|
+
-#}
|
8
|
+
{%- import('macros/printOdxCategory.xml.jinja2') as poc %}
|
9
|
+
{%- import('macros/printConfigData.xml.jinja2') as pcd %}
|
10
|
+
{%- import('macros/printConfigDataDictionarySpec.xml.jinja2') as pcdds %}
|
11
|
+
{%- import('macros/printAudience.xml.jinja2') as paud %}
|
12
|
+
{#- -#}
|
13
|
+
|
14
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
15
|
+
<!-- Written using odxtools {{odxtools_version}} -->
|
16
|
+
<ODX MODEL-VERSION="2.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="odx.xsd">
|
17
|
+
{{- set_category_docfrag(ecu_config.short_name, "ECU-CONFIG") }}
|
18
|
+
<ECU-CONFIG {{- poc.printOdxCategoryAttribs(ecu_config) }}>
|
19
|
+
{{- poc.printOdxCategorySubtags(ecu_config)|indent(4) }}
|
20
|
+
{%- if ecu_config.config_datas %}
|
21
|
+
<CONFIG-DATAS>
|
22
|
+
{%- for config_data in ecu_config.config_datas %}
|
23
|
+
{{ pcd.printConfigData(config_data) | indent(6) }}
|
24
|
+
{%- endfor %}
|
25
|
+
</CONFIG-DATAS>
|
26
|
+
{%- endif %}
|
27
|
+
{%- if ecu_config.additional_audiences %}
|
28
|
+
<ADDITIONAL-AUDIENCES>
|
29
|
+
{%- for additional_audience in ecu_config.additional_audiences %}
|
30
|
+
{{ paud.printAdditionalAudience(additional_audience) | indent(6) }}
|
31
|
+
{%- endfor %}
|
32
|
+
</ADDITIONAL-AUDIENCES>
|
33
|
+
{%- endif %}
|
34
|
+
{%- if ecu_config.config_data_dictionary_spec %}
|
35
|
+
{{ pcdds.printConfigDataDictionarySpec(ecu_config.config_data_dictionary_spec) | indent(4) }}
|
36
|
+
{%- endif %}
|
37
|
+
</ECU-CONFIG>
|
38
|
+
</ODX>
|
@@ -2,8 +2,8 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MIT
|
4
4
|
#
|
5
|
-
# This template writes an .odx-
|
6
|
-
#
|
5
|
+
# This template writes an .odx-f file containing descriptions of firmware
|
6
|
+
# blobs that can be flashed to ECUs.
|
7
7
|
-#}
|
8
8
|
{%- import('macros/printOdxCategory.xml.jinja2') as poc %}
|
9
9
|
{%- import('macros/printEcuMem.xml.jinja2') as pem %}
|
@@ -11,8 +11,8 @@
|
|
11
11
|
</ADDITIONAL-AUDIENCE>
|
12
12
|
{%- endmacro -%}
|
13
13
|
|
14
|
-
{%- macro printAudience(audience) -%}
|
15
|
-
<
|
14
|
+
{%- macro printAudience(audience, tag_name="AUDIENCE") -%}
|
15
|
+
<{{tag_name}} {{-make_bool_xml_attrib("IS-SUPPLIER", audience.is_supplier_raw)}}
|
16
16
|
{{-make_bool_xml_attrib("IS-DEVELOPMENT", audience.is_development_raw)}}
|
17
17
|
{{-make_bool_xml_attrib("IS-MANUFACTURING", audience.is_manufacturing_raw)}}
|
18
18
|
{{-make_bool_xml_attrib("IS-AFTERSALES", audience.is_aftersales_raw)}}
|
@@ -31,5 +31,5 @@
|
|
31
31
|
{%- endfor %}
|
32
32
|
</DISABLED-AUDIENCE-REFS>
|
33
33
|
{%- endif%}
|
34
|
-
</
|
34
|
+
</{{tag_name}}>
|
35
35
|
{%- endmacro -%}
|
@@ -31,6 +31,6 @@
|
|
31
31
|
{%- if checksum.checksum_result.value_type is not none %}
|
32
32
|
{#- #} TYPE="{{ checksum.checksum_result.value_type.value }}"
|
33
33
|
{%- endif %}
|
34
|
-
{#- #}>{{checksum.checksum_result.
|
34
|
+
{#- #}>{{checksum.checksum_result.value_raw}}</CHECKSUM-RESULT>
|
35
35
|
</CHECKSUM>
|
36
36
|
{%- endmacro -%}
|
@@ -110,7 +110,7 @@
|
|
110
110
|
</PROG-CODE>
|
111
111
|
{%- endmacro -%}
|
112
112
|
|
113
|
-
{%- macro printCompuMethod(cm)
|
113
|
+
{%- macro printCompuMethod(cm) %}
|
114
114
|
<COMPU-METHOD>
|
115
115
|
<CATEGORY>{{cm.category.value}}</CATEGORY>
|
116
116
|
{%- if cm.compu_internal_to_phys is not none %}
|
@@ -144,4 +144,4 @@
|
|
144
144
|
</COMPU-PHYS-TO-INTERNAL>
|
145
145
|
{%- endif %}
|
146
146
|
</COMPU-METHOD>
|
147
|
-
{%- endmacro
|
147
|
+
{%- endmacro %}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
1{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
-#}
|
5
|
+
|
6
|
+
{%- import('macros/printAdminData.xml.jinja2') as pad %}
|
7
|
+
{%- import('macros/printConfigRecord.xml.jinja2') as pcr %}
|
8
|
+
{%- import('macros/printElementId.xml.jinja2') as peid %}
|
9
|
+
{%- import('macros/printSpecialData.xml.jinja2') as psd %}
|
10
|
+
|
11
|
+
{%- macro printConfigData(config_data) -%}
|
12
|
+
<CONFIG-DATA>
|
13
|
+
{{peid.printElementIdSubtags(config_data)|indent(2) }}
|
14
|
+
{%- if config_data.valid_base_variants %}
|
15
|
+
<VALID-BASE-VARIANTS>
|
16
|
+
{%- for valid_base_variant in config_data.valid_base_variants %}
|
17
|
+
<VALID-BASE-VARIANT>
|
18
|
+
{%- if valid_base_variant.ecu_variant_snrefs %}
|
19
|
+
<ECU-VARIANT-SNREFS>
|
20
|
+
{%- for ecu_variant_snref in valid_base_variant.ecu_variant_snrefs %}
|
21
|
+
<ECU-VARIANT-SNREF SHORT-NAME="{{ecu_variant_snref}}" />
|
22
|
+
{%- endfor %}
|
23
|
+
</ECU-VARIANT-SNREFS>
|
24
|
+
{%- endif %}
|
25
|
+
<BASE-VARIANT-SNREF SHORT-NAME="{{valid_base_variant.base_variant_snref}}" />
|
26
|
+
</VALID-BASE-VARIANT>
|
27
|
+
{%- endfor %}
|
28
|
+
</VALID-BASE-VARIANTS>
|
29
|
+
{%- endif %}
|
30
|
+
{%- if config_data.config_records %}
|
31
|
+
<CONFIG-RECORDS>
|
32
|
+
{%- for config_record in config_data.config_records %}
|
33
|
+
{{ pcr.printConfigRecord(config_record) | indent(4) }}
|
34
|
+
{%- endfor %}
|
35
|
+
</CONFIG-RECORDS>
|
36
|
+
{%- endif %}
|
37
|
+
{{- psd.printSpecialDataGroups(config_data.sdgs)|indent(2, first=True) }}{#- #}
|
38
|
+
</CONFIG-DATA>
|
39
|
+
{%- endmacro -%}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
-#}
|
5
|
+
|
6
|
+
{%- import('macros/printDOP.xml.jinja2') as pdop %}
|
7
|
+
{%- import('macros/printUnitSpec.xml.jinja2') as punit %}
|
8
|
+
|
9
|
+
{%- macro printConfigDataDictionarySpec(cdds) -%}
|
10
|
+
<CONFIG-DATA-DICTIONARY-SPEC>
|
11
|
+
{%- if cdds.data_object_props %}
|
12
|
+
<DATA-OBJECT-PROPS>
|
13
|
+
{%- for dop in cdds.data_object_props %}
|
14
|
+
{{- pdop.printDataObjectProp(dop)|indent(3) }}
|
15
|
+
{%- endfor %}
|
16
|
+
</DATA-OBJECT-PROPS>
|
17
|
+
{%- endif %}
|
18
|
+
{%- if cdds.unit_spec %}
|
19
|
+
{{ punit.printUnitSpec(cdds.unit_spec)|indent(2) }}
|
20
|
+
{%- endif %}
|
21
|
+
</CONFIG-DATA-DICTIONARY-SPEC>
|
22
|
+
{%- endmacro -%}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
1{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
-#}
|
5
|
+
|
6
|
+
{%- import('macros/printAudience.xml.jinja2') as paud %}
|
7
|
+
{%- import('macros/printElementId.xml.jinja2') as peid %}
|
8
|
+
{%- import('macros/printItemValue.xml.jinja2') as piv %}
|
9
|
+
{%- import('macros/printSpecialData.xml.jinja2') as psd %}
|
10
|
+
|
11
|
+
{%- macro printConfigItemSubtags(config_item) %}
|
12
|
+
{#-#}{{ peid.printElementIdSubtags(config_item) }}
|
13
|
+
{%- if config_item.byte_position is not none %}
|
14
|
+
<BYTE-POSITION>{{config_item.byte_position}}</BYTE-POSITION>
|
15
|
+
{%- endif %}
|
16
|
+
{%- if config_item.bit_position is not none %}
|
17
|
+
<BIT-POSITION>{{config_item.bit_position}}</BIT-POSITION>
|
18
|
+
{%- endif %}
|
19
|
+
{%- if config_item.data_object_prop_ref is not none %}
|
20
|
+
<DATA-OBJECT-PROP-REF {{ make_ref_attribs(config_item.data_object_prop_ref) }} />
|
21
|
+
{%- endif %}
|
22
|
+
{%- if config_item.data_object_prop_snref is not none %}
|
23
|
+
<DATA-OBJECT-PROP-SNREF SHORT-NAME="{{ config_item.data_object_prop_snref }}" />
|
24
|
+
{%- endif %}
|
25
|
+
{{- psd.printSpecialDataGroups(config_item.sdgs) }}
|
26
|
+
{%- endmacro %}
|
27
|
+
|
28
|
+
{%- macro printConfigIdItem(config_id_item) %}
|
29
|
+
<CONFIG-ID-ITEM>
|
30
|
+
{{ printConfigItemSubtags(config_id_item)|indent(2) }}
|
31
|
+
</CONFIG-ID-ITEM>
|
32
|
+
{%- endmacro %}
|
33
|
+
|
34
|
+
{%- macro printDataIdItem(data_id_item) %}
|
35
|
+
<DATA-ID-ITEM>
|
36
|
+
{{ printConfigItemSubtags(data_id_item)|indent(2) }}
|
37
|
+
</DATA-ID-ITEM>
|
38
|
+
{%- endmacro %}
|
39
|
+
|
40
|
+
{%- macro printOptionItem(option_item) %}
|
41
|
+
<OPTION-ITEM>
|
42
|
+
{{ printConfigItemSubtags(option_item)|indent(2) }}
|
43
|
+
{%- if option_item.physical_default_value is not none %}
|
44
|
+
<PHYSICAL-DEFAULT-VALUE>{{ option_item.physical_default_value|e }}</PHYSICAL-DEFAULT-VALUE>
|
45
|
+
{%- endif %}
|
46
|
+
{%- if option_item.item_values %}
|
47
|
+
<ITEM-VALUES>
|
48
|
+
{%- for item_value in option_item.item_values %}
|
49
|
+
{{ piv.printItemValue(item_value) }}
|
50
|
+
{%- endfor %}
|
51
|
+
</ITEM-VALUES>
|
52
|
+
{%- endif %}
|
53
|
+
{%- if option_item.write_audience is not none %}
|
54
|
+
{{ paud.printAudience(option_item.write_audience, "WRITE-AUDIENCE")}}
|
55
|
+
{%- endif %}
|
56
|
+
{%- if option_item.read_audience is not none %}
|
57
|
+
{{ paud.printAudience(option_item.read_audience, "READ-AUDIENCE")}}
|
58
|
+
{%- endif %}
|
59
|
+
</OPTION-ITEM>
|
60
|
+
{%- endmacro %}
|
61
|
+
|
62
|
+
{%- macro printSystemItem(system_item) %}
|
63
|
+
<SYSTEM-ITEM {{ make_xml_attrib("SYSPARAM", system_item.sysparam) }}>
|
64
|
+
{{ printConfigItemSubtags(system_item)|indent(2) }}
|
65
|
+
</SYSTEM-ITEM>
|
66
|
+
{%- endmacro %}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
1{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
-#}
|
5
|
+
|
6
|
+
{%- import('macros/printAdminData.xml.jinja2') as pad %}
|
7
|
+
{%- import('macros/printAudience.xml.jinja2') as paud %}
|
8
|
+
{%- import('macros/printDataRecord.xml.jinja2') as pdr %}
|
9
|
+
{%- import('macros/printDiagCommDataConnector.xml.jinja2') as pdcdc %}
|
10
|
+
{%- import('macros/printElementId.xml.jinja2') as peid %}
|
11
|
+
{%- import('macros/printConfigItems.xml.jinja2') as pcits %}
|
12
|
+
{%- import('macros/printSpecialData.xml.jinja2') as psd %}
|
13
|
+
|
14
|
+
{%- macro printConfigRecord(config_record) -%}
|
15
|
+
<CONFIG-RECORD>
|
16
|
+
{{peid.printElementIdSubtags(config_record)|indent(2) }}
|
17
|
+
{%- if config_record.config_id_item is not none %}
|
18
|
+
{{- pcits.printConfigIdItem(config_record.config_id_item)|indent(2)}}
|
19
|
+
{%- endif %}
|
20
|
+
{%- if config_record.data_items %}
|
21
|
+
<DATA-ITEMS>
|
22
|
+
{%- for data_item in config_record.data_items %}
|
23
|
+
{{ pcits.printDataItem(data_item) | indent(4) }}
|
24
|
+
{%- endfor %}
|
25
|
+
</DATA-ITEMS>
|
26
|
+
{%- endif %}
|
27
|
+
{%- if config_record.diag_comm_data_connectors %}
|
28
|
+
<DIAG-COMM-DATA-CONNECTORS>
|
29
|
+
{%- for connector in config_record.diag_comm_data_connectors %}
|
30
|
+
{{ pdcdc.printDiagCommDataConnector(connector) | indent(4) }}
|
31
|
+
{%- endfor %}
|
32
|
+
</DIAG-COMM-DATA-CONNECTORS>
|
33
|
+
{%- endif %}
|
34
|
+
{%- if config_record.config_id is not none %}
|
35
|
+
<CONFIG-ID
|
36
|
+
{%- if config_record.config_id.value_type is not none %}
|
37
|
+
{#- #} TYPE="{{ config_record.config_id.value_type.value }}"
|
38
|
+
{%- endif %}
|
39
|
+
{#- #}>{{config_record.config_id.value}}</CONFIG-ID>
|
40
|
+
{%- endif %}
|
41
|
+
{%- if config_record.data_records %}
|
42
|
+
<DATA-RECORDS>
|
43
|
+
{%- for data_record in config_record.data_records %}
|
44
|
+
{{ pdr.printDataRecord(data_record) | indent(4) }}
|
45
|
+
{%- endfor %}
|
46
|
+
</DATA-RECORDS>
|
47
|
+
{%- endif %}
|
48
|
+
{%- if config_record.audience is not none %}
|
49
|
+
{{ paud.printAudience(config_record.audience) | indent(2) }}
|
50
|
+
{%- endif %}
|
51
|
+
{%- if config_record.system_items %}
|
52
|
+
<SYSTEM-ITEMS>
|
53
|
+
{%- for system_item in config_record.system_items %}
|
54
|
+
{{- pcits.printSystemItem(system_item) | indent(4) }}
|
55
|
+
{%- endfor %}
|
56
|
+
</SYSTEM-ITEMS>
|
57
|
+
{%- endif %}
|
58
|
+
{%- if config_record.data_id_item is not none %}
|
59
|
+
{{- pcits.printDataIdItem(config_record.data_id_item)|indent(2)}}
|
60
|
+
{%- endif %}
|
61
|
+
{%- if config_record.option_items %}
|
62
|
+
<OPTION-ITEMS>
|
63
|
+
{%- for option_item in config_record.option_items %}
|
64
|
+
{{- pcits.printOptionItem(option_item) | indent(4) }}
|
65
|
+
{%- endfor %}
|
66
|
+
</OPTION-ITEMS>
|
67
|
+
{%- endif %}
|
68
|
+
{%- if config_record.default_data_record_snref is not none %}
|
69
|
+
<DEFAULT-DATA-RECORD-SNREF SHORT-NAME="{{config_record.default_data_record_snref}}" />
|
70
|
+
{%- endif %}
|
71
|
+
{{- psd.printSpecialDataGroups(config_record.sdgs)|indent(2, first=True) }}{#- #}
|
72
|
+
</CONFIG-RECORD>
|
73
|
+
{%- endmacro -%}
|
@@ -10,7 +10,7 @@
|
|
10
10
|
{%- import('macros/printDescription.xml.jinja2') as pd %}
|
11
11
|
|
12
12
|
|
13
|
-
{%- macro printDiagCodedType(dct)
|
13
|
+
{%- macro printDiagCodedType(dct) %}
|
14
14
|
<DIAG-CODED-TYPE {{-make_xml_attrib("BASE-DATA-TYPE", dct.base_data_type.value)}}
|
15
15
|
{{-make_xml_attrib("BASE-TYPE-ENCODING", dct.base_type_encoding and dct.base_type_encoding.value)}}
|
16
16
|
{{-make_bool_xml_attrib("IS-HIGHLOW-BYTE-ORDER", dct.is_highlow_byte_order_raw)}}
|
@@ -34,7 +34,7 @@
|
|
34
34
|
<MIN-LENGTH>{{dct.min_length}}</MIN-LENGTH>
|
35
35
|
{%- endif %}
|
36
36
|
</DIAG-CODED-TYPE>
|
37
|
-
{%- endmacro
|
37
|
+
{%- endmacro %}
|
38
38
|
|
39
39
|
{%- macro printPhysicalType(physical_type) %}
|
40
40
|
{%- if physical_type.display_radix is not none %}
|
@@ -84,7 +84,6 @@
|
|
84
84
|
{%- macro printDopBaseAttribs(dop) %}
|
85
85
|
{{- make_xml_attrib("ID", dop.odx_id.local_id) }}
|
86
86
|
{{- make_xml_attrib("OID", dop.oid) }}
|
87
|
-
{#- -#}
|
88
87
|
{%- endmacro %}
|
89
88
|
|
90
89
|
{%- macro printDopBaseSubtags(dop) %}
|
@@ -92,8 +91,8 @@
|
|
92
91
|
{%- if dop.admin_data %}
|
93
92
|
{{ pad.printAdminData(dop.admin_data)|indent(1) }}
|
94
93
|
{%- endif %}
|
95
|
-
{{ psd.printSpecialDataGroups(dop.sdgs)|indent(1) }}
|
96
|
-
{%- endmacro
|
94
|
+
{{- psd.printSpecialDataGroups(dop.sdgs)|indent(1) }}
|
95
|
+
{%- endmacro %}
|
97
96
|
|
98
97
|
{%- macro printComplexDopAttribs(st) %}
|
99
98
|
{{- printDopBaseAttribs(st) }}
|
@@ -101,7 +100,7 @@
|
|
101
100
|
|
102
101
|
{%- macro printComplexDopSubtags(st) %}
|
103
102
|
{{- printDopBaseSubtags(st) }}
|
104
|
-
{%- endmacro
|
103
|
+
{%- endmacro %}
|
105
104
|
|
106
105
|
{%- macro printDataObjectProp(dop) %}
|
107
106
|
<DATA-OBJECT-PROP {{- printDopBaseAttribs(dop) }}>
|