Home » Eclipse Projects » Eclipse Titan » Decoding J1939 name fails(decoding integer & bitstring records)
Decoding J1939 name fails [message #1828590] |
Sat, 13 June 2020 19:55 |
Michael Josenhans Messages: 99 Registered: February 2016 |
Member |
|
|
I try to decode the J1939 name octetstring.
See https://www.kvaser.com/about-can/higher-layer-protocols/j1939-introduction/, search for table 3.
Byte number in CAN message Contents/Meaning
0 Identity number, LSB
1 Identity number
2 Bits 0-4: Identity number, MSB
Bits 5-7: Manufacturer code, LSB
3 Manufacturer code, MSB
4 Bits 0-2: ECU instance
Bits 3-7: Function instance
5 Function
6 Bit 0: Reserved bit
Bits 1-7: Vehicle system
7 Bits 0-3: Vehicle system instance
Bits 4-6: Industry group
Bit 7: Arbitrary address bit
Please note that byte 0 to 7 are reveresed, byte 0 contains LSB.
I have tried 3 ways:
1. Using encoding as bitstrings
2. Using encoding as bitstrings and integers
3. Using encoding as integers (preferred solution)
All fail. Using bitstring generates wrong data, while using integers (optionally with 1 Bit bitstrings) generates dynamic runtime errors because of missing data.
// This function reverses byte 0 to 7
function f_reverse_j1939_name(in J1939_NAME p_j1939_name)
//runs on PTC_isobus_CT
return J1939_NAME{
var J1939_NAME v_j1939_name_reverse :=
p_j1939_name[7]& p_j1939_name[6]& p_j1939_name[5]&
p_j1939_name[4]& p_j1939_name[3]& p_j1939_name[2]&
p_j1939_name[1]& p_j1939_name[0];
return v_j1939_name_reverse
}
testcase tc_dec_name_1()
{
var J1939_NAME j1939_name_reverse, j1939_name
j1939_name_reverse := '3102032E003D0080'O
j1939_name := f_reverse_j1939_name(j1939_name_reverse)
log("j1939 name reverse:-------------------------")
log(j1939_name_reverse)
log("j1939 name----------------------------------")
log(j1939_name)
log("--------------------------------------------")
log(f_decode_J1939_name(j1939_name))
log("--------------------------------------------")
}
external function f_encode_J1939_name(in J1939_NAME_RECORD pdu) return octetstring
with { extension "prototype(convert) encode(RAW)" }
external function f_decode_J1939_name(in octetstring data) return J1939_NAME_RECORD
with { extension "prototype(convert) decode(RAW)" }
type record J1939_NAME_RECORD{
J1939_ARBITRARY_ADDRESS_BIT arbitraryAddresssBit,
J1939_INDUSTRY_GROUP industryGroup,
J1939_VEHICLE_SYSTEM_INSTANCE vehicleSystemInstance,
J1939_VEHICLE_SYSTEM vehicleSystem,
J1939_RESERVED reserved,
J1939_FUNCTION function_,
J1939_FUNCTION_INSTANCE functionInstance,
J1939_ECU_INSTANCE ecuInstance,
J1939_MANUFACTURER_CODE manufacturerCode,
J1939_IDENTITY_NUMBER identityNumber
} with { variant "FIELDORDER(msb)" }
// 1. Encoding as pure bitstrings
// to test uncomment this section and comment the other sections
//type BIT1 J1939_ARBITRARY_ADDRESS_BIT
//type BIT3 J1939_INDUSTRY_GROUP
//type BIT4 J1939_VEHICLE_SYSTEM_INSTANCE
//type BIT7 J1939_VEHICLE_SYSTEM
//type BIT1 J1939_RESERVED
//type BIT8 J1939_FUNCTION
//type BIT5 J1939_FUNCTION_INSTANCE
//type BIT3 J1939_ECU_INSTANCE
//type BIT11 J1939_MANUFACTURER_CODE
//type BIT21 J1939_IDENTITY_NUMBER
//type bitstring BIT21 length(21) with { variant "FIELDLENGTH(21)" };
// 2. Encoding as integers and bitstrings
// to test uncomment this section and comment the other sections
//type BIT1 J1939_ARBITRARY_ADDRESS_BIT
//type INT3BIT J1939_INDUSTRY_GROUP
//type INT4BIT J1939_VEHICLE_SYSTEM_INSTANCE
//type INT7BIT J1939_VEHICLE_SYSTEM
//type BIT1 J1939_RESERVED
//type INT8BIT J1939_FUNCTION
//type INT5BIT J1939_FUNCTION_INSTANCE
//type INT3BIT J1939_ECU_INSTANCE
//type INT11BIT J1939_MANUFACTURER_CODE
//type INT21BIT J1939_IDENTITY_NUMBER
// 3. Encoding as pure integers
// to test uncomment this section and comment the other sections
type INT1BIT J1939_ARBITRARY_ADDRESS_BIT
type INT3BIT J1939_INDUSTRY_GROUP
type INT4BIT J1939_VEHICLE_SYSTEM_INSTANCE
type INT7BIT J1939_VEHICLE_SYSTEM
type INT1BIT J1939_RESERVED
type INT8BIT J1939_FUNCTION
type INT5BIT J1939_FUNCTION_INSTANCE
type INT3BIT J1939_ECU_INSTANCE
type INT11BIT J1939_MANUFACTURER_CODE
type INT21BIT J1939_IDENTITY_NUMBER
type integer INT1BIT (0..1) // 2^1-1
type integer INT3BIT (0..7) // 2^3-1
type integer INT4BIT (0..15) // 2^4-1
type integer INT5BIT (0..31) // 2^5-1
type integer INT7BIT (0..127) // 2^7-1
type integer INT8BIT (0..255) // 2^8-1
type integer INT11BIT (0..2047) // 2^11-1
type integer INT21BIT (0..2097151) // 2^21-1
Results of 1. (pure bitstrings)
21:49:09.293006 mtc USER Isobustest.ttcn:1035(testcase:tc_dec_name_1) j1939 name reverse:-------------------------
21:49:09.293036 mtc USER Isobustest.ttcn:1036(testcase:tc_dec_name_1) '3102032E003D0080'O
21:49:09.293090 mtc USER Isobustest.ttcn:1037(testcase:tc_dec_name_1) j1939 name----------------------------------
21:49:09.293127 mtc USER Isobustest.ttcn:1038(testcase:tc_dec_name_1) '80003D002E030231'O
21:49:09.293170 mtc USER Isobustest.ttcn:1039(testcase:tc_dec_name_1) --------------------------------------------
21:49:09.293211 mtc DEBUG Isobustest.ttcn:1040(testcase:tc_dec_name_1) f_decode_J1939_name(): Stream before decoding: '80003D002E030231'O
21:49:09.293263 mtc DEBUG Isobustest.ttcn:1040(testcase:tc_dec_name_1) f_decode_J1939_name(): Decoded @J1939.J1939_NAME_RECORD: { arbitraryAddresssBit := '1'B, industryGroup := '000'B, vehicleSystemInstance := '0000'B, vehicleSystem := '0000000'B, reserved := '0'B, function_ := '00111101'B, functionInstance := '00000'B, ecuInstance := '000'B, manufacturerCode := '00000101110'B, identityNumber := '001100010000001000011'B }
21:49:09.293205 mtc USER Isobustest.ttcn:1040(testcase:tc_dec_name_1) { arbitraryAddresssBit := '1'B, industryGroup := '000'B, vehicleSystemInstance := '0000'B, vehicleSystem := '0000000'B, reserved := '0'B, function_ := '00111101'B, functionInstance := '00000'B, ecuInstance := '000'B, manufacturerCode := '00000101110'B, identityNumber := '001100010000001000011'B }
21:49:09.293397 mtc USER Isobustest.ttcn:1041(testcase:tc_dec_name_1) --------------------------------------------
According to my understanding, the
identityNumber:= '001100010000001000011'B
is equal to '62043'O, which does not match with the names-octetstring. I would be expecting the identityNumber := '000110000001000110001'B wich is '30231'O.
As far as I could see, all other fields than the 11-bit manufacturerCode and 21-bit wide identityNumber seem to be ok. The identical error seems to exist in the decoder and encoder, as encoding the decoded octetstring provides the initial octetstring.
Results of 2. (integers and bitstrings)
21:36:42.900486 mtc PARALLEL Isobustest.ttcn:1026(testcase:tc_dec_name_1) Component type Isobustest.MTC_CT was initialized.
21:36:42.900547 mtc USER Isobustest.ttcn:1035(testcase:tc_dec_name_1) j1939 name reverse:-------------------------
21:36:42.900594 mtc USER Isobustest.ttcn:1036(testcase:tc_dec_name_1) '3102032E003D0080'O
21:36:42.900669 mtc USER Isobustest.ttcn:1037(testcase:tc_dec_name_1) j1939 name----------------------------------
21:36:42.900712 mtc USER Isobustest.ttcn:1038(testcase:tc_dec_name_1) '80003D002E030231'O
21:36:42.900770 mtc USER Isobustest.ttcn:1039(testcase:tc_dec_name_1) --------------------------------------------
21:36:42.900818 mtc DEBUG Isobustest.ttcn:1040(testcase:tc_dec_name_1) f_decode_J1939_name(): Stream before decoding: '80003D002E030231'O
21:36:42.900901 mtc ERROR Isobustest.ttcn:1040(testcase:tc_dec_name_1) Dynamic test case error: While RAW-decoding type '@J1939.J1939_NAME_RECORD': There are not enough bits in the buffer to decode type @J1939.J1939_NAME_RECORD.identityNumber (needed: 8, found: 6).
21:36:42.900969 mtc VERDICTOP Isobustest.ttcn:1040(testcase:tc_dec_name_1) setverdict(error): none -> error
Results of 3. (pure integers)
21:32:57.545204 mtc PARALLEL Isobustest.ttcn:1026(testcase:tc_dec_name_1) Component type Isobustest.MTC_CT was initialized.
21:32:57.545276 mtc USER Isobustest.ttcn:1035(testcase:tc_dec_name_1) j1939 name reverse:-------------------------
21:32:57.545325 mtc USER Isobustest.ttcn:1036(testcase:tc_dec_name_1) '3102032E003D0080'O
21:32:57.545392 mtc USER Isobustest.ttcn:1037(testcase:tc_dec_name_1) j1939 name----------------------------------
21:32:57.545426 mtc USER Isobustest.ttcn:1038(testcase:tc_dec_name_1) '80003D002E030231'O
21:32:57.545470 mtc USER Isobustest.ttcn:1039(testcase:tc_dec_name_1) --------------------------------------------
21:32:57.545515 mtc DEBUG Isobustest.ttcn:1040(testcase:tc_dec_name_1) f_decode_J1939_name(): Stream before decoding: '80003D002E030231'O
21:32:57.545571 mtc ERROR Isobustest.ttcn:1040(testcase:tc_dec_name_1) Dynamic test case error: While RAW-decoding type '@J1939.J1939_NAME_RECORD': There are not enough bits in the buffer to decode type @J1939.J1939_NAME_RECORD.manufacturerCode (needed: 8, found: 0).
21:32:57.545602 mtc VERDICTOP Isobustest.ttcn:1040(testcase:tc_dec_name_1) setverdict(error): none -> error
Attached are the main files (containg other content to be deleted) for testing.
[Updated on: Tue, 16 June 2020 08:52] Report message to a moderator
|
|
|
Re: Decoding J1939 name fails [message #1828668 is a reply to message #1828590] |
Tue, 16 June 2020 09:09 |
Michael Josenhans Messages: 99 Registered: February 2016 |
Member |
|
|
For way 1, I have tried it with bitstring values not equal to zero in order to see, which bitstrings are decoded correctly:
Name reverse:
Name:
Name decodes according to gnome calculator "Taschenrechner" to bitstring:
1001001100001011001111010001100100101110000000110000001000110001
However the titan decoder decodes to:
{ arbitraryAddresssBit := '1'B, industryGroup := '001'B, vehicleSystemInstance := '0011'B, vehicleSystem := '0000101'B, reserved := '1'B, function_ := '00111101'B, functionInstance := '00011'B, ecuInstance := '001'B, manufacturerCode := '00000101110'B, identityNumber := '001100010000001000011'B }
Which corresponds to:
1001001100001011001111010001100100000101110001100010000001000011
Here it is possible to see, that only the bitstring fields manufacturerCode and identityNumber are decoded wrongly.
The other fields, which are all bitstring with less than 9-bit are decoded correctly. Thus I would guess that the decoding/alignment of bitstrings with more than 1-byte is incorrect in the titan bitstring encoder and decoder.
|
|
| |
Re: Decoding J1939 name fails [message #1828765 is a reply to message #1828755] |
Thu, 18 June 2020 09:02 |
Michael Josenhans Messages: 99 Registered: February 2016 |
Member |
|
|
Yes. The following works:
external function f_encode_J1939_name(in J1939_NAME_RECORD pdu) return octetstring
with { extension "prototype(convert) encode(RAW)" }
external function f_decode_J1939_name(in octetstring data) return J1939_NAME_RECORD
with { extension "prototype(convert) decode(RAW)" }
type record J1939_NAME_RECORD{
J1939_ARBITRARY_ADDRESS_BIT arbitraryAddresssBit,
J1939_INDUSTRY_GROUP industryGroup,
J1939_VEHICLE_SYSTEM_INSTANCE vehicleSystemInstance,
J1939_VEHICLE_SYSTEM vehicleSystem,
J1939_RESERVED reserved,
J1939_FUNCTION function_,
J1939_FUNCTION_INSTANCE functionInstance,
J1939_ECU_INSTANCE ecuInstance,
J1939_MANUFACTURER_CODE manufacturerCode,
J1939_IDENTITY_NUMBER identityNumber
} with { variant "FIELDORDER(msb)" }
type INT1BIT J1939_ARBITRARY_ADDRESS_BIT
type INT3BIT J1939_INDUSTRY_GROUP
type INT4BIT J1939_VEHICLE_SYSTEM_INSTANCE
type INT7BIT J1939_VEHICLE_SYSTEM
type INT1BIT J1939_RESERVED
type INT8BIT J1939_FUNCTION
type INT5BIT J1939_FUNCTION_INSTANCE
type INT3BIT J1939_ECU_INSTANCE
type INT11BIT J1939_MANUFACTURER_CODE
type INT21BIT J1939_IDENTITY_NUMBER
type integer INT1BIT (0..1) with { variant "FIELDLENGTH(1)"} // 2^1-1
type integer INT3BIT (0..7) with { variant "FIELDLENGTH(3)"} // 2^3-1
type integer INT4BIT (0..15) with { variant "FIELDLENGTH(4)"} // 2^4-1
type integer INT5BIT (0..31) with { variant "FIELDLENGTH(5)"} // 2^5-1
type integer INT7BIT (0..127) with { variant "FIELDLENGTH(7)"} // 2^7-1
type integer INT8BIT (0..255) with { variant "FIELDLENGTH(8)"} // 2^8-1
type integer INT11BIT (0..2047) with { variant "FIELDLENGTH(11),BYTEORDER(last)"} // 2^11-1
type integer INT21BIT (0..2097151) with { variant "FIELDLENGTH(21),BYTEORDER(last)"} // 2^21-1
|
|
| |
Re: Decoding J1939 name fails [message #1828871 is a reply to message #1828785] |
Sat, 20 June 2020 15:43 |
|
Hi Michael,
for the first structure you might be looking for the FIELDORDER attribute:
FIELDORDER
Attribute syntax: FIELDORDER(<parameter>)
Parameters allowed: msb, lsb
Default value: lsb
Can be used with: record or set types. It can also be assigned to a group of fields of a record.
Description: The attribute specifies the order in which consecutive fields of a structured type are placed into octets. * msb: coded bitfields are concatenated within an octet starting from MSB, when a field stretches the octet boundary, it continues at the MSB of next the octet. * lsb: coded bitfields are concatenated within an octet starting from LSB, when a field stretches the octet boundary, it continues at the LSB of next the octet.
Comment: Fields within an octet must be coded with the same FIELDORDER.
Fields are always concatenated in increasing octet number direction.
FIELDORDER has a slightly different effect than order attributes. While the FIELDORDER shifts the location of coded bitfields inside octets, the order attributes describes the order of the bits within a bitfield.
There is NO connection between the effect of the FIELDORDER and the effects of the other order attributes.
Note
The attribute does not extend to lower level structures. If the same field order is desired for the fields of a lower level record/set, then that record/set also needs a FIELDORDER attribute.
Examples:
//Example number 1)
type record MyRec_lsb {
BIT1 field1,
BIT2 field2,
BIT3 field3,
BIT4 field4,
BIT6 field5
}
with { variant "FIELDORDER(lsb)" }
const MyRec_lsb c_pdu := {
field1:='1'B // bits of field1: a
field2:='00'B // bits of field2: b
field3:='111'B // bits of field3: c
field4:='0000'B // bits of field4: d
field5:='111111'B // bits of field5: e
}
//Encoding of c_pdu will result in:
// 00111001 ddcccbba
// 11111100 eeeeeedd
//Example number 2)
type record MyRec_msb {
BIT1 field1,
BIT2 field2,
BIT3 field3,
BIT4 field4,
BIT6 field5
}
with { variant "FIELDORDER(msb)" }
const MyRec_msb c_pdu2 := {
field1:='1'B // bits of field1: a
field2:='00'B // bits of field2: b
field3:='111'B // bits of field3: c
field4:='0000'B // bits of field4: d
field5:='111111'B // bits of field5: e
}
//Encoding of c_pdu2 will result in:
// 10011100 abbcccdd
// 00111111 ddeeeeee
while for the J1939_NAME , BITORDER should be used:
BITORDER
Attribute syntax: BITORDER(<parameter>)
Parameters allowed: msb, lsb
Default value: lsb
Can be used with: stand-alone types or the field of a record or set.
Description: This attribute specifies the order of the bits within an octet. When set to lsb, the first bit sent will be the least significant bit of the original byte. When set to msb, the first bit sent will be the most significant bit of the original byte. When applied to an octetstring using the extension bit mechanism, only the least significant 7 bits are reversed, the 8th bit is reserved for the extension bit.
Examples:
// Example number 1)
type octetstring OCT
with {
variant "BITORDER(lsb)"
}
const OCT c_oct := '123456'O
//The encoded bitfield: 01010110 00110100 00010010
// last octet^ ^first octet
// The buffer will have the following content:
// 00010010
// 00110100
// 01010110
//The encoding result in the octetstring '123456'O
//Example number 2)
type octetstring OCTrev
with {
variant "BITORDER(msb)"
}
const OCTrev c_octr := '123456'O
//The encoded bitfield: 01010110 00110100 00010010
// last octet^ ^first octet
//The buffer will have the following content:
// 01001000
// 00101100
// 01101010
//The encoding results in the octetstring '482C6A'O
Pls check the RAW Encoder and Decoder section of the Titan reference guide.
Best regards
Elemer
|
|
| |
Re: Decoding J1939 name fails [message #1828890 is a reply to message #1828888] |
Sun, 21 June 2020 14:49 |
|
Hi MIchael,
Right; in this case you need the BYTEORDER attribute:
BYTEORDER
Attribute syntax: BYTEORDER(<parameter>)
Parameters allowed: first, last
Default value: first
Can be used with: stand-alone types or the field of a record or set.
Description: The attribute determines the order of the bytes in the encoded data.
first: The first octet placed first into the buffer.
last: The last octet placed first into the buffer.
Comment: The attribute has no effect on a single octet field.
Note
The attribute works differently for octetstring and integer types. The ordering of bytes is counted from left-to-right (starting from the MSB) in an octetstring but right-to-left (starting from the LSB) in an integer. Thus, the attribute BYTEORDER(first) for an octetstring results the same encoded value than BYTEORDER(last) for an integer having the same value.
Examples:
//Example number 1)
type octetstring OCT
with {
variant "BYTEORDER(first)"
}
const OCT c_oct := '123456'O
//The encoded bitfield: 01010110 00110100 00010010
// last octet^ ^first octet
The buffer will have the following content:
// 00010010
// 00110100
// 01010110
//The encoding will result in the octetstring '123456'O
//Example number 2)
type octetstring OCTrev
with {variant "BYTEORDER(last)"
}
const OCTrev c_octr := '123456'O
//The encoded bitfield: 01010110 00110100 00010010
// last octet^ ^first octet
//The buffer will have the following content:
// 01010110
// 00110100
// 00010010
Choosing the appropriate encoding variants as listed in the quoted paragraph should give you the desired result.
I hope this helps
Elemer
|
|
|
Re: Decoding J1939 name fails [message #1828894 is a reply to message #1828890] |
Sun, 21 June 2020 16:49 |
Michael Josenhans Messages: 99 Registered: February 2016 |
Member |
|
|
Hi Elemer,
this is what I expected too.
The encoding for:
type OCT8 J1939_NAME with {variant "BYTEORDER(last)"}
works fine.
However for the record, the BYTEORDER attribute (last/first) has no impact on encoding:
type record J1939_NAME_RECORD{
J1939_ARBITRARY_ADDRESS_BIT arbitraryAddresssBitValue, // selfConfigurableAddressValue
J1939_INDUSTRY_GROUP industryGroupValue, // deviceClassInstanceValue
J1939_VEHICLE_SYSTEM_INSTANCE vehicleSystemInstanceValue, // deviceClassInstanceValue
J1939_VEHICLE_SYSTEM vehicleSystemValue,
J1939_RESERVED reservedValue,
J1939_FUNCTION functionValue,
J1939_FUNCTION_INSTANCE functionInstanceValue,
J1939_ECU_INSTANCE ecuInstanceValue,
J1939_MANUFACTURER_CODE manufacturerCodeValue,
J1939_IDENTITY_NUMBER identityNumberValue
} with { variant "FIELDORDER(msb),BYTEORDER(last)" }
This matches the reference manual:
BYTEORDER
Attribute syntax: BYTEORDER(<parameter>)
Parameters allowed: first, last
Default value: first
Can be used with: stand-alone types or the field of a record or set.
Thus it can be applied on a field of a record, however not on the record itself.
Br,
Michael
|
|
| |
Re: Decoding J1939 name fails [message #1828900 is a reply to message #1828898] |
Sun, 21 June 2020 19:03 |
Michael Josenhans Messages: 99 Registered: February 2016 |
Member |
|
|
Hi Elemer,
I have currently not a working template, as for the J1939 socket interface, the PGN becomes a seperate parameter. Thus, as I expect only e.g. vt2ecu messages on the socket interface, it might be sufficent to have an internal port for vt2ecu, one for ecu2vt and e.g. one for addressClaimed.
type record AddressClaimed
{
J1939_NAME name
} with { variant "" }
or
type record AddressClaimed
{
J1939_NAME_RECORD name
} with { variant "" }
type record Isobus_messageWithPGN {
J1939_PGN pgn,
Isobus_message pdu
}
with {
variant (pdu) "CROSSTAG(
etp_dt, pgn = '00C700'O; //199
etp_cm, pgn = '00C800'O; //200
vt2ecu, pgn = '00E600'O; //230
ecu2vt, pgn = '00E700'O; //231
requestForAddressClaimed, pgn = '00EA00'O; //234
tp_dt, pgn = '00EB00'O; //235
tp_cm, pgn = '00EC00'O; //236
networkMessage, pgn = '00ED00'O; //237
// cannotClaimSourceAddress, pgn = '00EEFFFE'O; //238 all and conjuction needed!!!!!!
addressClaimed, pgn = '00EEFF'O; //238 all and conjuction needed!!!!!!
commandedAddress, pgn = '00FED8'O)" //254 all and conjuction needed!!!!!!
}
type union Isobus_message {
ETP_DT etp_dt, // extended TP data transfer
ETP_CM etp_cm, // extended TP connection management
VT2ECU vt2ecu, // Message Virtual Terminal (VT) to ECU
ECU2VT ecu2vt, // Message ECU to Virtual Terminal (VT)
RequestForAddressClaimed requestForAddressClaimed,
TP_DT tp_dt, // TP data transfer
TP_CM tp_cm, // TP connection management
NetworkMessage networkMessage, // Network Message according ISO 11873-4
CannotClaimSourceAddress cannotClaimSourceAddress,
AddressClaimed addressClaimed,
CommandedAddress commandedAddress
// other upper layer isobus protocols like Task Comtroller are added here ...
}
with { variant "" }
This is the J1939 record returned from socket interface:
type record SocketCAN_receive_j1939_message { // recieved J1939 message
SocketCAN_socketid id,
SocketCAN_ifr ifr,
J1939_PGN pgn,
J1939_ADDR destAddr,
J1939_NAME name,
SocketCAN_J1939_PDU pdu
}
Basically the J1939 connection setup works the following:
To set up a connection an address claim message is sent with the name (Bitorder last encoded) it contains also a 1 byte source address SA.
Then if a second connection is set up, the same procedure happens. If there are conflicts as they have choosen the same SA, the connection with the smaller NAME wins and the other has to assign a new SA and repeat this procedure. This called address claiming procedure.
The address claiming procedure could be implemented as a TTCN process. It is currently not implemented in TTCN, however there is an address claiming deamon (user space), that has to be started for each NAME, which keeps track of changing addresses. Thus if in parallel running the address claiming deamon, TTCN code has not to track of the address, it can use the NAME for addressing in the socket.
The kernel keeps track of the NAME, thus the socket interface can subscribe via bind to a PGN (optionally) , a NAME (optionally) and alternatively to a SA and then just receive the filtered messages e.g. for the subsribed NAME and PGN.
A typical procedure looks as following:
- The address is claimed for all names (NAME1 (VT), NAME2 (ecu) using addressClaim message.
- One device e.g. the VT sends a message to the global address (broadcast address, SA=0xFF) using a PGN e.g. ecu2vt. The name is given.
- The other side e.g. the ecu has subscribed to the global address receives its NAME1.
- Then the other side (the ecu) responds by setting up a socket and binding to the given NAME1 and sends a response message the NAME2 using its name, which are converted by the linux kernel driver to its source address SA and the destination addess DA of the j1939 can bus network.
For now, it looks to me that the PGN is kept seperate from the vt2ecu pdu and there is a different socket call for each PGN we are interested in. This works for ISOBUS, but it might not work of other J1939 devices, which may have hundereds of different PGNs at the same time. Thus when filtering the PGN by the kernel, there might be needed hundereds of open sockets and thus TTCN processes at the same time.
This is the way vt2ecu looks like:
type union VT2ECU
{
// put all VT2ECU messages here
SoftKeyActivationReq softKeyActivationReq,
ButtonActivationReq buttonActivationReq,
PointingEventReq pointingEventReq,
VTSelectInputObjectReq vtSelectInputObjectReq,
.....
ExtendedStoreVersionRes extendedStoreVersionRes,
ExtendedLoadVersionRes extendedLoadVersionRes,
ExtendedDeleteVersionRes extendedDeleteVersionRes,
GetVersionsRes getVersionsRes,
VTUnsupportedVTFunctionInd vtUnsupportedVTFunctionInd,
VTStatusReq vtStatusReq
}
with {variant "TAG (
// put all VT2ECU messages here
softKeyActivationReq, vtfunction = 0;
buttonActivationReq, vtfunction = 1;
pointingEventReq, vtfunction = 2;
vtSelectInputObjectReq, vtfunction = 3;
vtESCReq, vtfunction = 4;
vtChangeNumericValueReq, vtfunction = 5;
vtChangeActiveMaskReq, vtfunction = 6;
vtChangeSoftKeyMaskReq, vtfunction = 7;
.....
getVersionsRes, vtfunction = 224;
vtUnsupportedVTFunctionInd, vtfunction = 253;
vtStatusReq, vtfunction = 254;)"
}
|
|
|
Re: Decoding J1939 name fails [message #1828902 is a reply to message #1828900] |
Sun, 21 June 2020 19:26 |
|
OK,
let's assume the following values:
arbitraryAddresssBitValue:=0'B
industryGroupValue:='111'B
vehicleSystemInstanceValue:='0000'
vehicleSystemValue:='1111111'B
reservedValue:='0'B
functionValue:='11111111'B
functionInstanceValue:='00000'B
ecuInstanceValue:='111'B
manufacturerCodeValue:='00000000111'B
identityNumberValue:='000001111111100000000'B
Could you please indicate how should this look encoded ?
BR
Elemer
|
|
|
Re: Decoding J1939 name fails [message #1828903 is a reply to message #1828902] |
Sun, 21 June 2020 19:51 |
Michael Josenhans Messages: 99 Registered: February 2016 |
Member |
|
|
It sould be encoded as:
00000000 11111111 11100000 00000000 00000111 11111111 11111110 01110000
Here is an example I have created with the help of titan:
NAME as encoded:
NAME as octetstring '
NAME as record:
name := { arbitraryAddresssBitValue := 1, industryGroupValue := 1, vehicleSystemInstanceValue := 3, vehicleSystemValue := 5, reservedValue := 1, functionValue := 61, functionInstanceValue := 3, ecuInstanceValue := 1, manufacturerCodeValue := 368, identityNumberValue := 197169 }
To your example:
|
|
| | |
Re: Decoding J1939 name fails [message #1828918 is a reply to message #1828909] |
Mon, 22 June 2020 11:51 |
|
Hi Michael,
for
arbitraryAddresssBitValue :='0'B "a"
industryGroupValue :='111'B "bbb"
vehicleSystemInstanceValue :='0000' "ccc"
vehicleSystemValue :='1111111'B "ddddddd"
reservedValue :='0'B "e"
functionValue :='11111111'B "f"
functionInstanceValue :='00000'B "ggggg"
ecuInstanceValue :='111'B "hhh"
manufacturerCodeValue :='00000000111'B "iiiiiiiiiii"
identityNumberValue :='000001111111100000000'B "jjjjjjjjjjjjjjjjjjjj"
encoding is more like
jjjjjjjj jjjjjjjj iiijjjjj iiiiiiii fffffhhh ffffffff ddddddde abbbcccc
instead of jjjjjjjj jjjjjjjj iiiijjjj hiiiiiii fggggghh ddddddde abbbcccc as indicated ;
pls. check and confirm
Pls try the following:
type record J1939_NAME_RECORD_A{
J1939_IDENTITY_NUMBER identityNumber,
J1939_MANUFACTURER_CODE manufacturerCode,
J1939_ECU_INSTANCE ecuInstance,
J1939_FUNCTION_INSTANCE functionInstance,
J1939_FUNCTION function_,
J1939_RESERVED reserved,
J1939_VEHICLE_SYSTEM vehicleSystem,
J1939_VEHICLE_SYSTEM_INSTANCE vehicleSystemInstance,
J1939_INDUSTRY_GROUP industryGroup,
J1939_ARBITRARY_ADDRESS_BIT arbitraryAddresssBit
} with { variant "FIELDORDER(lsb)" /* it has no effect here, added for visibility only */
variant (identityNumber) "BYTEORDER(first)"
variant (manufacturerCode) "BYTEORDER(first)"
/* the following variants are not needed: variant (ecuInstance) "BYTEORDER(first)"
variant (functionInstance) "BYTEORDER(first)"
variant (function_) "BYTEORDER(first)"
variant (reserved) "BYTEORDER(first)"
variant (vehicleSystem) "BYTEORDER(first)"
variant (vehicleSystemInstance) "BYTEORDER(first)"
variant (industryGroup) "BYTEORDER(first)"
variant (arbitraryAddresssBit) "BYTEORDER(first)"
*/
}
template J1939_NAME_RECORD_A t_name_A := {
identityNumber := 65280,
manufacturerCode := 7,
ecuInstance := 7,
functionInstance := 0,
function_ := 255,
reserved := 0,
vehicleSystem := 127,
vehicleSystemInstance := 0,
industryGroup := 7,
arbitraryAddresssBit := 0
}
template J1939_NAME_RECORD_A t_name_A1 := {
identityNumber := 197169,
manufacturerCode := 368,
ecuInstance := 1,
functionInstance := 3,
function_ := 61,
reserved := 1,
vehicleSystem := 5,
vehicleSystemInstance := 3,
industryGroup := 1,
arbitraryAddresssBit := 1
}
should result in:
13:44:18.268737 RAWTest2.ttcn:147 ----------------------------------------------------------------------------------
13:44:18.268769 RAWTest2.ttcn:149 Encode '00FFE00007FFFE70'O
13:44:18.268818 RAWTest2.ttcn:151 EncodedBitstr '0000000011111111111000000000000000000111111111111111111001110000'B
13:44:18.268857 RAWTest2.ttcn:153 Decode{ identityNumber := 65280, manufacturerCode := 7, ecuInstance := 7, functionInstance := 0, function_ := 255, reserved := 0, vehicleSystem := 127, vehicleSystemInstance := 0, industryGroup := 7, arbitraryAddresssBit := 0 }
13:44:18.268898 RAWTest2.ttcn:157 ----------------------------------------------------------------------------------
13:44:18.268919 RAWTest2.ttcn:158 Encode '3102032E193D0B93'O
13:44:18.268947 RAWTest2.ttcn:160 EncodedBitstr '0011000100000010000000110010111000011001001111010000101110010011'B
13:44:18.268984 RAWTest2.ttcn:162 Decode{ identityNumber := 197169, manufacturerCode := 368, ecuInstance := 1, functionInstance := 3, function_ := 61, reserved := 1, vehicleSystem := 5, vehicleSystemInstance := 3, industryGroup := 1, arbitraryAddresssBit := 1 }
pls mind that there might be several paths to result in the same encoding.
I hope this helps
Elemer
|
|
| |
Re: Decoding J1939 name fails [message #1828934 is a reply to message #1828929] |
Mon, 22 June 2020 16:00 |
|
Hi Michael,
yes , for some reason I entered fffff instead of ggggg;
however the RAW encoding variant should work as it conforms , at least as far as I can see, to:
jjjjjjjjjjjjjjjjiiijjjjjiiiiiiiiggggghhhffffffffdddddddeabbbcccc
(not to jjjjjjjjjjjjjjjjiiijjjjjiiiiiiiifffffhhhffffffffdddddddeabbbcccc, which was a typo)
BR
Elemer
[Updated on: Mon, 22 June 2020 16:12] Report message to a moderator
|
|
|
Re: Decoding J1939 name fails [message #1828953 is a reply to message #1828934] |
Tue, 23 June 2020 07:20 |
Michael Josenhans Messages: 99 Registered: February 2016 |
Member |
|
|
Hi Elemer,
this now works for encoding of reverse byte order and normalbyte order. I need both.
type record J1939_NAME_RECORD{
J1939_ARBITRARY_ADDRESS_BIT arbitraryAddresssBit, // selfConfigurableAddressValue
J1939_INDUSTRY_GROUP industryGroup, // deviceClassInstanceValue
J1939_VEHICLE_SYSTEM_INSTANCE vehicleSystemInstance, // deviceClassInstanceValue
J1939_VEHICLE_SYSTEM vehicleSystem,
J1939_RESERVED reserved,
J1939_FUNCTION function_,
J1939_FUNCTION_INSTANCE functionInstance,
J1939_ECU_INSTANCE ecuInstance,
J1939_MANUFACTURER_CODE manufacturerCode,
J1939_IDENTITY_NUMBER identityNumber
} with { variant "FIELDORDER(msb)"
variant (identityNumber) "BYTEORDER(last)"
variant (manufacturerCode) "BYTEORDER(last)"
}
type record J1939_NAME_RECORD_REVERSE_BYTE_ENCODING{
J1939_IDENTITY_NUMBER identityNumber,
J1939_MANUFACTURER_CODE manufacturerCode,
J1939_ECU_INSTANCE ecuInstance,
J1939_FUNCTION_INSTANCE functionInstance,
J1939_FUNCTION function_,
J1939_RESERVED reserved,
J1939_VEHICLE_SYSTEM vehicleSystem,
J1939_VEHICLE_SYSTEM_INSTANCE vehicleSystemInstance, // deviceClassInstanceValue
J1939_INDUSTRY_GROUP industryGroup, // deviceClassInstanceValue
J1939_ARBITRARY_ADDRESS_BIT arbitraryAddresssBit // selfConfigurableAddressValue
} with { variant "FIELDORDER(lsb)" /* it has no effect here, added for visibility only */
variant (identityNumber) "BYTEORDER(first)"
variant (manufacturerCode) "BYTEORDER(first)"
/* the following variants are not needed:
variant (ecuInstance) "BYTEORDER(first)"
variant (functionInstance) "BYTEORDER(first)"
variant (function_) "BYTEORDER(first)"
variant (reserved) "BYTEORDER(first)"
variant (vehicleSystem) "BYTEORDER(first)"
variant (vehicleSystemInstance) "BYTEORDER(first)"
variant (industryGroup) "BYTEORDER(first)"
variant (arbitraryAddresssBit) "BYTEORDER(first)"
*/
}
type INT1BIT J1939_ARBITRARY_ADDRESS_BIT
type INT3BIT J1939_INDUSTRY_GROUP
type INT4BIT J1939_VEHICLE_SYSTEM_INSTANCE
type INT7BIT J1939_VEHICLE_SYSTEM
type INT1BIT J1939_RESERVED
type INT8BIT J1939_FUNCTION
type INT5BIT J1939_FUNCTION_INSTANCE
type INT3BIT J1939_ECU_INSTANCE
type INT11BIT J1939_MANUFACTURER_CODE
type INT21BIT J1939_IDENTITY_NUMBER
type integer INT1BIT (0..1) with { variant "FIELDLENGTH(1)"} // 2^1-1
type integer INT3BIT (0..7) with { variant "FIELDLENGTH(3)"} // 2^3-1
type integer INT4BIT (0..15) with { variant "FIELDLENGTH(4)"} // 2^4-1
type integer INT5BIT (0..31) with { variant "FIELDLENGTH(5)"} // 2^5-1
type integer INT7BIT (0..127) with { variant "FIELDLENGTH(7)"} // 2^7-1
type integer INT8BIT (0..255) with { variant "FIELDLENGTH(8)"} // 2^8-1
type integer INT11BIT (0..2047) with { variant "FIELDLENGTH(11),BYTEORDER(last)"} // 2^11-1
type integer INT21BIT (0..2097151) with { variant "FIELDLENGTH(21),BYTEORDER(last)"} // 2^21-1
Thanks a lot.
Br,
Michael
|
|
|
Goto Forum:
Current Time: Sat Nov 09 00:23:58 GMT 2024
Powered by FUDForum. Page generated in 0.06678 seconds
|