EDS This document serves as an informal EDS schema. This format is preferred over XML Schema formalism, because it is much more readable and convenient during research phase. Where applicable, EDS syntax has been translated into ASN.1 ACN, SDL or C language. Data types Integer number Data of integer type can be exchanged in all relevant services (PS, MAS, DAS, DVS). The definition of the integer type includes a list of constraints and optional definition of binary encoding. Example ASN.1 and ACN syntax 1. <int name="MyInt"> 2. <constraints> 3. <interval> 4. <left bound="closed" value="-10"/> 5. <right bound="open" value="10"/> 6. </interval> 7. <const value="15"/> 8. </constraints> 9. <encoding> 10. <positive size="16" endianness="little"/> 11. </encoding> 12. </int> MyInt ::= INTEGER ((-10..<10) | (15)) MyInt [size 16, encoding pos-int, endianness little] The definition of the constraints is always mandatory. If more than one constraint is provided, e.g. two intervals or an interval and a constant, the resulting constraint is the union of all constraints. Constraints ASN.1 syntax 1. 2. 3. 4. <interval> <left bound="closed" value="-10"/> <right bound="open" value="10"/> </interval> MyInt ::= INTEGER (-10..<10) 1. <const value="15"/> MyInt ::= INTEGER (15) For higher level services i.e. DAS and DVS, the definition of the encoding is ignored. For lower level services i.e. PS and MAS, encoding definition is mandatory. Encodings ACN syntax 1. <positive size="16" endianness="little"/> MyInt [size 16, encoding pos-int, endianness little] 1. <twos_complement size="32" endianness="big"/> MyInt [size 32, encoding twos-complement, endianness big] Enumeration field Data of enumeration type can be exchanged in all relevant services (PS, MAS, DAS, DVS). Enumeration type should be preferred over integer in all cases, where a variable may hold one value, out of a finite set of values of distinctive meaning. It should not be considered as a collection of named integer constants like in C/C++ languages. Possible use cases for enumeration type are: Boolean types (DAS, DVS services) or bit fields (PS and MAS). Definition of an enumeration type includes a list of allowed values and optional definition of binary encoding. Example ASN.1 and ACN syntax 1. 2. 3. 4. 5. 6. 7. 8. 9. <enum name="MyEnum"> <options> <option name="Run" value="0"/> <option name="Stop" value="3"/> </options> <encoding> <positive size="2" endianness="big"/> </encoding> </enum> MyEnum ::= ENUMERATED { Run(0), Stop(3) } MyEnum [size 2, encoding pos-int, endianness big, encode-values] Constraints contain a list of allowed values. This part is always mandatory. Constraints ASN.1 syntax 1. 2. 3. 4. MyEnum ::= ENUMERATED { Run(0), Stop(3) } <options> <option name="Run" value="0"/> <option name="Stop" value="3"/> </options> For higher level services i.e. DAS and DVS, the definition of encoding is ignored. For lower level services i.e. PS and MAS, encoding definition is mandatory. Encodings ACN syntax 1. MyEnum [size 2, encoding pos-int, endianness big, encode-values] <positive size="2" endianness="big"/> Floating point number Data of floating point type can be exchanged in all relevant services (PS, MAS, DAS, DVS). Definition of a float type includes list of constraints and optional definition of binary encoding. Example ASN.1 and ACN syntax 1. <float name="MyFloat"> 2. <constraints> 3. <interval> 4. <left bound="closed" value="0"/> 5. <right bound="open" value="3.14"/> 6. </interval> 7. </constraints> 8. <encoding> 9. <ieee754 size="32" endianness="big"/> 10. </encoding> 11. </float> MyFloat ::= REAL (0..<3.14) MyFloat [encoding IEEE754-1985-32, endianness big] The definition of the constraints is always mandatory. If more than one constraint is provided, e.g. two intervals, the resulting constraint is the union of all constraints. Constraints ASN.1 syntax 1. 2. 3. 4. MyFloat ::= REAL (0..<3.14) <interval> <left bound="closed" value="0"/> <right bound="open" value="3.14"/> </interval> For higher level services i.e. DAS and DVS, the definition of encoding is ignored. For lower level services i.e. PS and MAS, encoding definition is mandatory. Encodings ACN syntax 1. <ieee754 size="32" endianness="big"/> MyFloat [encoding IEEE754-1985-32, endianness big] 1. <ieee754 size="64" endianness="big"/> MyFloat [encoding IEEE754-1985-64, endianness big] Blob data Blob type is used to describe structures exchanged with lower level services (PS, MAS). It is used to describe fields which are reserved, or fields whose structure is not known at compile time and can be resolved only at runtime. Definition of blob type consists of optional constraints and mandatory encoding definitions. Example ASN.1 and ACN syntax 1. 2. 3. 4. 5. 6. 7. 8. MyBlob ::= BIT STRING (SIZE(4)) (‘1010’B) <blob name="MyBlob"> <constraints> <const binary="1010"/> </constraints> <encoding> <static size="4"/> </encoding> </blob> MyBlob [size 4] Constraints are optional element of the definition. Constraints ASN.1 syntax 1. <const binary="1010"/> MyBlob ::= BIT STRING (‘1010’B) 1. <const hex="A"/> MyBlob ::= BIT STRING (‘A’H) It is possible to define blob type with variable length. This allows to describe frame whose both, structure and length is not known at compile time. Encodings ASN.1 and ACN syntax 1. <static size="4"/> MyBlob ::= BIT STRING (SIZE(4)) 1. <dynamic min="4" max="16"/> MyBlob [size 4] MyBlob ::= BIT STRING (SIZE(4..16)) MyBlob <INTEGER:length> [size length] Sequence Sequence type is used to describe structures exchanged in all relevant services (PS, MAS, DAS, DVS). It allows to group simpler data types into a larger structures. Definition of a sequence is essentially a list of named instances of data types. Example ASN.1 and ACN syntax 1. <sequence name="MyHeader"> 2. <declare name="sync" type="SomeBlob"/> 3. <declare name="id" type="SomeInt"/> 4. <declare name="alarm" type="SomeEnum"/> 5. </sequence> 6. 7. 8. 9. 10. 11. 12. 13. <sequence name="MessageId1"> 14. <declare name="header" type="MyHeader"> 15. <constraint field="id"> MyHeader ::= SEQUENCE { sync SomeBlob, id SomeInt, alarm SomeEnum } MyHeader [] { sync [], id [], alarm [] } MessageId1 ::= SEQUENCE { header MyHeader ( WITH COMPONENTS { 16. <const value="1"/> 17. </constraint> 18. </declare> 19. <declare name="speed" type="SomeFloat"/> 20. <declare name="angle" type="SomeFloat"/> 21. </sequence> 22. 23. 24. 25. 26. 27. 28. 29. 30. <sequence name="MessageComplexMatch"> 31. <declare name="header" type="MyHeader"> 32. <constraint field="sync"> 33. <const hex="BEEF"/> 34. </constraint> 35. <constraint field="id"> 36. <const value="0"/> 37. <interval> 38. <left bound="closed" value="2"/> 39. <right bound="closed" value="255"/> 40. </interval> 41. </constraint> 42. <constraint field="alarm"> 43. <option name="Red"/> 44. <option name="Yellow"/> 45. </constraint> 46. </declare> 47. <declare name="altitude" type="SomeFloat"/> 48. </sequence> …, id (1) } ), speed SomeFloat, angle SomeFloat } MessageId1 [] { header [], speed [], angle [] } MessageComplexMatch ::= SEQUENCE { header MyHeader ( WITH COMPONENTS { …, sync (‘BEEF’H), id ((0) | (2..255)), alarm (Red | Yellow) } ), altitude SomeFloat } MessageComplexMatch [] { header [], altitude [] } It is possible to provide additional constraints to an instance of a sequence. Provided constraints will be intersected with original constraints of the nested type. Additional constraints (sequences only) ASN.1 syntax 1. <declare name="header" type="MyHeader"> 2. <constraint field="sync"> 3. <const hex="BEEF"/> 4. </constraint> 5. <constraint field="id"> 6. <const value="0"/> 7. <interval> 8. <left bound="closed" value="2"/> 9. <right bound="closed" value="255"/> 10. </interval> 11. </constraint> 12. <constraint field="choice"> 13. <option name="Red"/> 14. <option name="Yellow"/> 15. </constraint> 16. </declare> header MyHeader ( WITH COMPONENTS { …, sync (‘BEEF’H), id ((0) | (2..255)), alarm (Red | Yellow) } ), 1. <declare name="header" type="MyOtherHeader"> 2. <constraint field="routing_trace"> 3. <constraint field="sender"> 4. <const value="65"/> 5. <constraint> 6. </constraint> 7. <constraint field="id"> 8. <const value="1"/> 9. </constraint> 10. </declare> header MyOtherHeader ( WITH COMPONENTS { …, routing_trace ( WITH COMPONENTS { …, sender(65) } ), id(1) } ), It is possible to have one element of variable size embedded in a sequence (including nested sequences). This allows to define packets whose length is not known at compile time. Should a frame contain more elements of variable sizes, this must be implemented using more levels of decoding. Sub components of variable size ASN.1 and ACN syntax 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. <blob name="MyVarBlob"> <encoding> <dynamic min="4" max="16"/> </encoding> </blob> MyVarBlob ::= BIT STRING (SIZE(4..16)) <sequence name="MyChildSeq"> <declare name="number" type="SomeInt"/> <declare name="data" type="MyVarBlob"/> </sequence> MyChildSeq ::= SEQUENCE { number SomeInt, data MyVarBlob } MyVarBlob <INTEGER:length> [size length] MyChildSeq <INTEGER:length> [] { number [], data <length> [] } <sequence name="MyParentSeq"> <declare name="id" type="SomeInt"/> <declare name="body" type="MyChildSeq"/> </sequence> MyParentSeq ::= SEQUENCE { id SomeInt, body MyChildSeq } MyParentSeq <INTEGER:length> [] { id [], body <length> [] } Array Array type is used to describe series of data exchanged in all relevant services (PS, MAS, DAS, DVS). The type stored by an array must have constant size. Example ASN.1 and ACN syntax 1. 2. 3. MyArray ::= SEQUENCE (SIZE(28)) OF MyType <array name="MyArray" type="MyType"> <count const="28"/> </array> MyArray [size 28] Array of static size is the most trivial case. Static size ASN.1 and ACN syntax 1. MyArray ::= SEQUENCE (SIZE(28)) OF MyType <count const="28"/> MyArray [size 28] It is possible to define an array of dynamic size. Similar to sequences of variable size, the number of elements can be determined at run time e.g. based on the size of incoming packets. Dynamic size ASN.1 and ACN syntax 1. MyArray ::= SEQUENCE (SIZE(10..128)) OF MyType <count min="10" max="128"/> MyArray <INTEGER:count> [size count] Functional interface / device-specific interface Description of an interface is strongly based on using data types. There are 3 data types associated with each relation: value_id, value and metadata. Following code presents a functional interface of unusual sample accelerometer. There are two relations that can be acquired: temperature and acceleration. There is also one relation that can be commanded: sampling rate. Using the mechanism of value_id, it is possible to pick a particular thermistor or accelerometer unit. Example 1. <functional_interface class="accelerometer"> 2. 3. <!-- This part describes relations that can be acquired or commanded --> 4. <interface> 5. 6. <acquire> 7. <value_id type="temperature_reading_t"/> 8. <value type="temperature_t"/> 9. <metadata type="bivalent_t"/> 10. </acquire> 11. 12. <acquire> 13. <value_id type="acceleration_reading_t"/> 14. <value type="acceleration_t"/> 15. <metadata type="bivalent_t"/> 16. </acquire> 17. 18. <command> 19. <value_id type="alter_refresh_rate_t"/> 20. <value type="interval_t"/> 21. <metadata type="bivalent_t"/> 22. </command> 23. 24. </interface> 25. 26. <!-- This part supplies necessary data type definitions to supplement interface description --> 27. <data_types> 28. 29. <!-- describe value_id structures --> 30. <sequence name="temperature_reading_t"> 31. <declare name="header" type="value_id_header_t"> 32. <constraint field="service"> 33. <option name="read_temperature"/> 34. </constraint> 35. </declare> 36. <declare name="unit" type="thermistor_unit_t"/> 37. </sequence> 38. 39. <sequence name="acceleration_reading_t"> 40. <declare name="header" type="value_id_header_t"> 41. <constraint field="service"> 42. <option name="read_acceleration"/> 43. </constraint> 44. </declare> 45. <declare name="unit" type="accelerometer_unit_t"/> 46. </sequence> 47. 48. <sequence name="alter_refresh_rate_t"> 49. <declare name="header" type="value_id_header_t"> 50. <constraint field="service"> 51. <option name="set_refresh_rate"/> 52. </constraint> 53. </declare> 54. </sequence> 55. 56. <!-- describe the common part of all value_id structs --> 57. <sequence name="value_id_header_t"> 58. <declare name="service" type="service_selection_t"/> 59. </sequence> 60. 61. <!-- auxiliary types for value_id structs --> 62. <enum name="service_selection_t"> 63. <options> 64. <option name="read_temperature" value="0"/> 65. <option name="read_acceleration" value="1"/> 66. <option name="set_refresh_rate" value="2"/> 67. </options> 68. </enum> 69. 70. <enum name="thermistor_unit_t"> 71. <options> 72. <option name="optics" value="0"/> 73. <option name="core" value="1"/> 74. <option name="package" value="2"/> 75. <option name="outside" value="3"/> 76. </options> 77. </enum> 78. 79. <enum name="accelerometer_unit_t"> 80. <options> 81. <option name="core_structure" value="0"/> 82. <option name="deployed_panel_left" value="1"/> 83. <option name="deployed_panel_right" value="2"/> 84. </options> 85. </enum> 86. 87. <!-- describe value data types --> 88. <float name="temperature_t"> 89. <constraints> 90. <interval> 91. <left bound="closed" value="0"/> 92. <right bound="closed" value="1.4167911e32"/> 93. </interval> 94. </constraints> 95. </float> 96. 97. <float name="acceleration_t"> 98. <constraints> 99. <interval> 100. <left bound="closed" value="-5.6e51"/> 101. <right bound="closed" value="5.6e51"/> 102. </interval> 103. </constraints> 104. </float> 105. 106. <enum name="interval_t"> 107. <options> 108. <option name="10 ms" value="0"/> 109. <option name="50 ms" value="1"/> 110. <option name="100 ms" value="2"/> 111. </options> 112. </enum> 113. <!-- describe the metadata format --> 114. <enum name="bivalent_t"> 115. <options> 116. <option name="success" value="0"/> 117. <option name="failure" value="1"/> 118. </options> 119. </enum> 120. 121. </data_types> 122. 123. </functional_interface> Definition of device-specific interface follows the same rules. Example 1. 2. 3. 4. 5. 6. 7. <device_specific_interface> <interface> <!-- Put here acquire and command elements --> </interface> <data_types> <!-- Put here definitions of data types --> </data_types> 8. </device_specific_interface> Packet interface To be able to use packet service in device-specific access protocol, it is necessary to declare possible packets. Since there is no meta-data or value_id exchanged with the service, a packet is identified only by the format of transferred data. It is foreseen that the data structure contains at least one field that allows to distinguish different packets. Example 1. <packet_interface> 2. 3. <!-- This part describes all possible packets --> 4. <interface> 5. <packet> 6. <data type="speed_pkt"/> 7. </packet> 8. <packet> 9. <data type="status_pkt"/> 10. </packet> 11. </interface> 12. 13. <!-- This part supplies necessary data type definitions to supplement interface description --> 14. <data_types> 15. <!-- Put here definitions of data types --> 16. </data_types> 17. 18. </packet_interface> Memory interface Memory interface is also based on type definitions. There is a support for multiple memory units per interface. It corresponds to memory_id field used in memory access service primitives. It could be compared to value_id used in DVS and DAS services. In addition to that, it is possible to specify multiple memory regions per each memory unit. Example 1. <memory_interface> 2. 3. <!-- This part describes all available memory units --> 4. <interface> 5. 6. <memory> 7. <memory_id type="sram_id_t"/> 8. <map> 9. <region name="uart1” offset="0x90000000" type="uart_peripheral_t"/> 10. </map> 11. <metadata type="bivalent_t"/> 12. </memory> 13. 14. <memory> 15. <memory_id type="flash_id_t"/> 16. <map> 17. <region name="vectors” offset="0x00000000" type="interrupt_vectors_t"/> 18. </map> 19. <metadata type="bivalent_t"/> 20. </memory> 21. 22. </interface> 23. 24. <!-- This part supplies necessary data type definitions to supplement interface description --> 25. <data_types> 26. <!-- Put here definitions of data types --> 27. </data_types> 28. 29. </memory_interface> Behavioural statements Immediate values Following example depicts how to provide a fixed (constant) value. Example 1. <const value="7"/> Aliases Aliases are identifiers that are resolved when particular EDS is converted into implemented instantiation. Aliases are useful to parameterize addresses of sub-services, time out values, etc. Example 1. <alias name="reaction_wheel_address"/> Declaring variables Declaring a variable is straightforward. A name and the type must be given. Example 1. <declare name="battery_temp" type="temperature_t"/> Accessing variables, array elements, sequence members Access a variable battery_temp ANSI C syntax 1. <variable name="battery_temp"/> battery_temp Access a sequence member ANSI C syntax 1. 2. 3. coordinates.x <variable name="coordinates"> <variable name="x"/> </variable> Access array element ANSI C syntax 1. 2. 3. 4. 5. table[5] <variable name="table"> <offset> <const value="5"/> </offset> </variable> Access a member of a member of array element ANSI C syntax 1. 2. 3. 4. 5. 6. 7. 8. table[i].member_1.sub_member_a <variable name="table"> <offset> <variable name="i"/> </offset> <variable name="member_1"> <variable name="sub_member_a"/> </variable> </variable> Copying values between variables Example 1. 2. 3. <copy> <source> <!-- constant or variable --> 4. 5. 6. 7. 8. </source> <destination> <!-- variable --> </destination> </copy> Simple arithmetic Addition 1. <addition> 2. <result> 3. <variable name="sum"/> 4. </result> 5. <addend> 6. <variable name="term1"/> 7. </addend> 8. <addend> 9. <variable name="term2"/> 10. </addend> 11. <addend> 12. <const value="17"/> 13. </addend> 14. </addition> Subtraction 1. <subtraction> 2. <result> 3. <variable name="difference"/> 4. </result> 5. <minuend> 6. <variable name="budget"/> 7. </minuend> 8. <subtrahend> 9. <variable name="cost1"/> 10. </subtrahend> 11. <subtrahend> 12. <const value="210"/> 13. </subtrahend> 14. </subtraction> Multiplication 1. <multiplication> 2. <result> 3. <variable name="product"/> 4. </result> 5. <multiplicand> 6. <variable name="value"/> 7. </multiplicand> 8. <multiplicand> 9. <const value="6"/> 10. </multiplicand> 11. <multiplicand> 12. <variable name="quantity"/> 13. </multiplicand> 14. </multiplication> Division 1. 2. 3. 4. 5. <division> <result> <variable name="dose"/> </result> <dividend> 6. <variable name="one_litre"/> 7. </dividend> 8. <divisor> 9. <const value="2"/> 10. </divisor> 11. </division> Calibration Linear 1. <linear_calibration> 2. <slope> 3. <const value="1"/> 4. </slope> 5. <bias> 6. <const value="-100"/> 7. </bias> 8. <input> 9. <variable name="temperature_raw"/> 10. </input> 11. <output> 12. <variable name="temperature_kelvin"/> 13. </output> 14. </linear_calibration> Loop Example 1. <loop> 2. <interval> 3. <left bound="closed" value="1"/> 4. <right bound="closed" value="10"/> 5. </interval> 6. <iterator> 7. <variable name="i"/> 8. </iterator> 9. <process> 10. <!-- process code --> 11. </process> 12. </loop> Condition Common reference ANSI C syntax for(i=1 ; i<=10 ; i++) { //process code } ANSI C syntax 1. <compare> 2. <subject> 3. <variable name="result"/> 4. </subject> 5. <reference> 6. <variable name="threshold"/> 7. </reference> 8. <lower_than> 9. <!-- process code A --> 10. </lower_than> 11. <greater_than> 12. <!-- process code B --> 13. </greater_than> 14. <equal> 15. <!-- process code C --> 16. </equal> 17. <not_equal> 18. <!-- process code D --> 19. </not_equal> 20. </compare> if(result < threshold) { //process code A } if(result > threshold) { //process code B } if(result == threshold) { //process code C } if(result != threshold) { //process code D } Individual reference ANSI C syntax 1. <compare> 2. <subject> 3. <variable name="result"/> 4. </subject> 5. <lower_than> 6. <reference> 7. <variable name="threshold_a"/> 8. </reference> 9. <process> 10. <!-- process code A --> 11. </process> 12. </lower_than> 13. <greater_than> 14. <reference> 15. <variable name="threshold_b"/> 16. </reference> 17. <process> 18. <!-- process code B --> 19. </process> 20. </greater_than> 21. <equal> 22. <reference> 23. <variable name="threshold_c"/> 24. </reference> 25. <process> 26. <!-- process code C --> 27. </process> 28. </equal> 29. <not_equal> 30. <reference> 31. <variable name="threshold_d"/> 32. </reference> 33. <process> 34. <!-- process code D --> 35. </process> 36. </not_equal> 37. <within> 38. <reference> 39. <left bound="closed" value="10"/> 40. <right bound="closed" value="20"/> 41. </reference> 42. <process> 43. <!-- process code E --> 44. </process> 45. </within> 46. <not_within> 47. <reference> 48. <left bound="closed" value="10"/> 49. <right bound="closed" value="20"/> 50. </reference> 51. <process> 52. <!-- process code F --> 53. </process> 54. </not_within> 55. </compare> Using device access service Acquire from DAS 1. <das_acquire> 2. <value_id> 3. <!-- Variable 4. </value_id> 5. <value> 6. <!-- Variable 7. </value> 8. <metadata> 9. <!-- Variable 10. </metadata> 11. <time_limit> 12. <!-- variable with value_id --> to be filled --> to be filled --> or constant --> if(result < threshold_a) { //process code A } if(result > threshold_b) { //process code B } if(result == threshold_c) { //process code C } if(result != threshold_d) { //process code D } if((result >= 10) && (result <= 20)) { //process code E } if((result < 10) || (result > 20)) { //process code F } 13. </time_limit> 14. <on_success> 15. <!-- executed only if indication intercepted before time out --> 16. </on_success> 17. <on_timeout> 18. <!-- executed if time out occurred --> 19. </on_timeout> 20. </das_acquire> Command to DAS 1. <das_command> 2. <value_id> 3. <!-- Variable 4. </value_id> 5. <value> 6. <!-- Variable 7. </value> 8. <metadata> 9. <!-- Variable 10. </metadata> 11. <time_limit> 12. <!-- variable 13. </time_limit> 14. <on_success> 15. <!-- executed 16. </on_success> 17. <on_timeout> 18. <!-- executed 19. </on_timeout> 20. </das_command> with value_id --> to be filled --> to be filled --> or constant --> only if indication intercepted before time out --> if time out occurred --> Using memory access service To read a particular memory region, its name must be provided and a variable of relevant type. It is possible to set up a time out if the indication is late. Example 1. <read_memory> 2. <region name="uart1"/> 3. <data> 4. <variable name="uart_registers"/> 5. </data> 6. <metadata> 7. <variable name="result"/> 8. </metadata> 9. <time_limit> 10. <alias name="reasonable_time_limit"/> 11. </time_limit> 12. <on_success> 13. <!-- executed only if indication intercepted before time out --> 14. </on_success> 15. <on_timeout> 16. <!-- executed if time out occurred --> 17. </on_timeout> 18. </read_memory> Writing to the memory is similar to reading the memory. The name of the region must be provided, variable with data of relevant type and a placeholder for meta data. A time out condition may occur if the indication response is late. Example 1. 2. <write_memory> <region name="vectors"/> 3. <data> 4. <variable name="interrupt_sw"/> 5. </data> 6. <metadata> 7. <variable name="result"/> 8. </metadata> 9. <time_limit> 10. <alias name="reasonable_time_limit"/> 11. </time_limit> 12. <on_success> 13. <!-- executed only if indication intercepted before time out --> 14. </on_success> 15. <on_timeout> 16. <!-- executed if time out occurred --> 17. </on_timeout> 18. </write_memory> EDS also allows to use READ_MODIFY_WRITE primitive of memory access service. Mask parameter is computed manually by providing the name of the field that is being modified. After modification, the previous value is returned. Example 1. <modify_memory> 2. <region name="uart1"/> 3. <modify field="prescaler"> 4. <variable name="prescaler_value"/> 5. </modify> 6. <metadata> 7. <variable name="result"/> 8. </metadata> 9. <time_limit> 10. <alias name="reasonable_time_limit"/> 11. </time_limit> 12. <on_success> 13. <!-- executed only if indication intercepted before time out --> 14. </on_success> 15. <on_timeout> 16. <!-- executed if time out occurred --> 17. </on_timeout> 18. </modify_memory> Using packet service Packet service is less constrained than Memory access service. For example, there is no Transaction ID by which request – answer could be matched. The number of answer messages depend on the device. It is also possible that semantically different messages are received depending on the state of the device. Those different messages may origin a new process branch, e.g. acknowledge message finalizes the process, while error message activates the recovery routine (see diagram on the right). Nevertheless, it is desired that some higher level distinguishment is done to the receiving messages. It is often the case that the structure of packages follows certain frame format. There is a field that has a semantic meaning of a key. Using this value it is possible to filter the messages. Following example presents how a packet can be sent. The data encoding of the packet is matched by the type of the attached variable. The example also shows how to use alias to address a particular device. The alias can be substituted with the actual address during the code generation phase, or using some sort of a database / lookup table. Example 1. <packet_send> 2. 3. 4. 5. 6. 7. 8. <destination_address> <alias name="reaction_wheel_addr"/> </destination_address> <data> <variable name="tc_set_rotation"/> </data> </packet_send> For receiving packets, EDS offers a very powerful mechanism. It is possible to wait for multiple packets (not for one at a time). It is also possible to describe various scenarios. Consider a case when it is not known which packet will be sent by the device. The device may send ACK and data value packets, or NACK and error code packets. Or, the device may not respond at all. This kind of program flow is not a rare case and is fully supported by a schema. Example 1. <!-- Blocking wait statement --> 2. <wait_for_packets> 3. 4. <!-- ACK + SPEED --> 5. <scenario> 6. 7. <minterm> 8. <packet_receive> 9. <source_address> 10. <alias name="reaction_wheel_addr"/> 11. </source_address> 12. <data> 13. <variable name="tm_ack"/> 14. </data> 15. </packet_receive> 16. <!-- and --> 17. <packet_receive> 18. <source_address> 19. <alias name="reaction_wheel_addr"/> 20. </source_address> 21. <data> 22. <variable name="tm_current_speed"/> 23. </data> 24. </packet_receive> 25. </minterm> 26. 27. <process> 28. <!-- Executed only if ACK and SPEED have been received 29. </process> 30. 31. </scenario> 32. 33. <!-- or --> 34. 35. <!-- NACK + STATUS --> 36. <scenario> 37. 38. <minterm> 39. <packet_receive> 40. <source_address> 41. <alias name="reaction_wheel_addr"/> 42. </source_address> 43. <data> 44. <variable name="tm_nack"/> 45. </data> 46. </packet_receive> 47. <!-- and --> 48. <packet_receive> 49. <source_address> 50. <alias name="reaction_wheel_addr"/> 51. </source_address> 52. <data> 53. <variable name="tm_status"/> --> 54. </data> 55. </packet_receive> 56. </minterm> 57. 58. <process> 59. <!-- Executed only if NACK and STATUS have been received 60. </process> 61. 62. </scenario> 63. 64. <!-- or --> 65. 66. <!-- time out condition --> 67. <timeout> 68. <time_limit> 69. <alias name="reasonable_time_limit"/> 70. </time_limit> 71. <process> 72. <!-- Executed only if time out has passed --> 73. </process> 74. </timeout> 75. 76. </wait_for_packets> --> Device abstraction control procedure / Device specific access protocol Request or command defined in the interface, is matched with a handler using a value_id type. It is possible to provide sub-constrained type to handle only part of the service. For example, it is possible to sub-constraint temperature_reading_t type into two sub-types and use two different handles to handle two different thermocouples. Value parameter is an input for command requests, and output for acquire requests. Metadata parameter is always output. Example 1. <device_abstraction_control_procedures> 2. 3. <request_handler> 4. <variables> 5. <declare name="id" type="temperature_reading_t"/> 6. <declare name="data" type="temperature_t"/> 7. <declare name="meta" type="bivalent_t"/> 8. </variables> 9. <value_id> 10. <variable name="id"/> 11. </value_id> 12. <value> 13. <variable name="data"/> 14. </value> 15. <metadata> 16. <variable name="meta"/> 17. </metadata> 18. <process> 19. <!-- process description --> 20. </process> 21. </request_handler> 22. 23. </device_abstraction_control_procedures> Device specific access protocol is defined in a similar way. Example 1. <device_specific_access_protocol> 2. 3. <!-- handlers here --> </device_specific_access_protocol> References 1. ASN.1 Communication Between Heterogeneous Systems – Olivier Dubuisson http://www.oss.com/asn1/resources/books-whitepapers-pubs/dubuisson-asn1-book.PDF 2. CAN User Manual – Semantix information technologies http://www.semantix.gr/asn1scc/ACN-UM-v-1.0x.pdf 3. Specification and description language Z.100 – ITU-T http://www.itu.int/ITU-T/studygroups/com10/languages/Z.100_1199.pdf