You are on page 1of 9

J1939 CAN bus spy, Chapt. 7: bug in Microchip App. Note J1939.c library http://recursos3.planetaclix.pt/canuart/index_7.

html

Chapter 7

J1939.c CAN Bus plus RS232 (continued)

The "J1939 Address Claiming" Microchip sample bug

<< back to main page


<< previous chapter ( Michael Eisele's Xtm CAN bus simulator)

(Vector's AddressClaiming_CN.cfg sample bug) next chapter >>

Abstract of the 1rst Chapter:


Microchip provided source code for J1939.c CAN library (Kim Otten et al.), plus Application Maestro
generated code UARTIntC.c, were used to implement a bare-bones system with a 2-node CAN bus,
where node #129 upon receiving commands from #128 to toggle a LED also output strings "ON" and
"OFF" thru the RSR23.

Abstract of the 2nd Chapter:


We kept the 2 nodes #128 and #129 exchanging messages, and added a 3rd node, #130, listening to
them, and reporting to the PC. Everything addressed to our smart node #130 was send to our PC's
Terminal program, dumping the affected RxBuffers to the UART.

Abstract of the 3rd Chapter:


Our smart node #130 was put in ListenOnly mode, all masks to zeros - a true "spy", now.
But because the firmware J1939.c generates so few messages, the overall result is not much exciting.

Abstract of the 4th Chapter:


So we want to improve our basic firmware, but that means going deeper into understanding the SAE
J1939 protocol (automotive, commercial vehicles, etc.).
We could use some help in that, and luckily there are at least 2 free "demos" available which we can use
to simulate the bus.

Abstract of the 5th Chapter:


While learning CAN/J1939 a CAN/J1939 simulator is a nice tool, among others, to test if the NMT
behaviour (network management) you have coded and believe is OK, is indeed conforming to the SAE
standard.
CANoe simulator is a wonderful tool for that, and on top of its price can't be beaten (yes, the limited but
functional demo is free). We had a look at just a small parcel of it.

Abstract of the 6th Chapter:


This time we played with Michael Eisele's Xtm, using it as a CAN/J1939 simulator.
Michael kindly prepared a sample implementing about the same functionality as the CANoe's example of
the previous chapter - the Address Claimed message of the J1939 Address Claiming NMT procedure.

Don't want to miss the next chapter? just drop me an email to


recursos.pt@gmail.com subject: J1939 CAN, and I will notify you.
No other use will be made of your e-mail address.

After too much time playing with the simulation software(s), and having become familiar with the basic NMT
procedures of J1939, it downed on me that Microchip's provided source code for J1939.c CAN library has a
nasty bug.

Not only that, but also Vector's CAPL code for their AddressClaiming_CN.cfg sample, much touted by myself
in Chapter 5 suffers exactly the same bug!

Let us start with Microchip's J1939.c CAN library (app. note 930):

1 of 9 28/09/2012 22:53
J1939 CAN bus spy, Chapt. 7: bug in Microchip App. Note J1939.c library http://recursos3.planetaclix.pt/canuart/index_7.html

1. The "J1939 Address Claiming" Microchip sample bug


2. Hardware configuration to test the J1939.c CAN library
3. The bug in the Function CompareName ()
4. J1939.c CAN library is a nice piece of code
5. What's next?

1 - The "J1939 Address Claiming" Microchip sample bug

Saddly to say, our most beloved Microchip provided source code for J1939.c CAN library has a serious bug.

I wonder why nobody has already pointed that (as far as I know), since Microchip's source code has been around
since at least 2004. Either nobody is using it, or nobody payed much attention.

So, what is wrong with the J1939.c CAN library ?

The most basic feature of J1939 is the Address Claiming negotiation:

No two nodes can have the same Source Address, therefore according to SAE J1939-81, a node must
successfully claim an address according to the procedures explained in section 4.2 “Network Management
Procedure” prior to sending any other messages on the network.

In SAE J1939-81, the key to resolve any contention between 2 nodes claiming the same address is to use the
node's NAMEs which must always be unique:

3.1.3 Addresses and NAME (J1939/81 and Appendix B)

Each ECU on the network will have at least one name and one address associated with it. (...) The
address of an ECU defines a specific communications source or destination for messages, the name
includes identification of the primary function performed at that address and adds an indication of the
instance of that functionality in the event that multiple ECUs with the same primary function coexist on
the same network. As many as 254 different ECUs of the same function can coexist on the network,
each identified by their own address and name.
To uniquely name each ECU, J1939 defines a 64 bit NAME consisting of the fields shown in Table 1.(...)

In general, most ECUs will use their Preferred Addresses immediately upon power up. A specific
procedure (defined in J1939/81 and elaborated on in J1939/01) for assigning addresses after powerup is
used to resolve any conflicts that may occur. Each ECU must be capable of announcing which
address(es) it intends to use.

Table 1: NAME Fields


Arbitrary Industry Vehicle Vehicle Reserved Function Function ECU Manufacturer Identity
Address Group System System Instance Instance Code Number
Capable Instance

1 bit 3 bit 4 bit 7 bit 1 bit 8 bit 5 bit 3 bit 11 bit 21 bit

Byte 8 Byte 7 Byte 6 Byte 5 Byte 4 to Byte 1

Now, when it comes to comparing the 64 bit NAMEs, SAE J1939-81 states:

The byte ordering of the NAME fields in a CAN message is shown in table 2, and is arranged to allow the
NAME to be treated as a number in a manner consistent with SAE J1939-71. The entire 8 byte NAME is

2 of 9 28/09/2012 22:53
J1939 CAN bus spy, Chapt. 7: bug in Microchip App. Note J1939.c library http://recursos3.planetaclix.pt/canuart/index_7.html

used as a single numeric value in arbitration processes when multiple CAs attempt to claim the same
address (see 4.4.3.3).

Table 2: Field positions within NAME:

Byte Bits Position of Description Note:


Most
Significant bit

1 8-1 8 Least significant byte Bit 8 is the bit sent closest


of Identity Number to the DLC bits of the
message.
2 8-1 8 Second byte of
Identity Number
3 8-6 8 Least significant 3
bits of Manufacturer
Code
5-1 5 Most significant 5
bits of Identity
Number
4 8-1 8 Most significant 8
bits of Manufacturer
Code
5 8-4 8 Function Instance
3-1 3 ECU Instance
6 8-1 8 Function
7 8-2 8 Vehicle System
1 - Reserved
8 8 - Arbitrary Address
Capable
7-5 7 Industry Group
4-1 4 Vehicle System Bit 1 is the last of the data
Instance bits sent and is closest to
the CRC in the message.

Notice that "Byte1, Bit 8 is the bit sent closest to the DLC bits of the message", and that "Byte8, Bit 1 is the last of the
data bits sent and is closest to the CRC in the message" (SAE uses bits 8..1 where we use bits 7...0).
This really means that the bytes are output to the CAN bus in the reverse order of their priority.

That the Arbitrary Address Capable bit is the most significant makes all sense, as a node (in J1939 parlance, a
Controller Application (CA)) with such capability can afford to loose arbitration for a less endowed node (!):

3.3.2 Arbitrary Address Capable CA


An Arbitrary Address Capable CA is one that can select its source address from any appropriate SA
(including those in the range 128 to 247 inclusive) based on internal algorithms, and then claim that
address. This CA, in cases of address conflict, is also able to re-calculate its address and re-claim
(unless all 120 of the addresses between 128 and 247 are used). The value in the Arbitrary Address
Capable field in the NAME (See Section 4.1.1.2) indicates whether or not a CA has this capability. This
capability is needed particularly for CAs that are expected to have multiple instances of the same device
on a single vehicle. In these cases, the Arbitrary Address Capable CA will be the one to lose arbitration

3 of 9 28/09/2012 22:53
J1939 CAN bus spy, Chapt. 7: bug in Microchip App. Note J1939.c library http://recursos3.planetaclix.pt/canuart/index_7.html

for a Preferred Address since the setting of the Arbitrary Address Capable bit in its NAME lowers its
priority for address claim. This is correct behavior since its ability to operate correctly on the network
will not be affected by the loss of arbitration. Note that if its function is one that would normally use a
Preferred Address in the lower 128, it will claim that address first. Only upon losing arbitration during
Address Claim will it claim an unused
address from the range above 128.

(...)

4.1.1.2 Arbitrary Address Capable Field


This 1-bit field indicates whether a CA can use an arbitrary source address to resolve an address claim
conflict. If this bit is set to “1”, the CA will resolve an address conflict with a CA whose NAME has a
higher priority (lower numeric value) by selecting an arbitrary source address from the range 128 to 247
inclusive and claiming that source address.
A self-configurable CA that computes its address but can claim only from a more restricted set of
addresses is not considered arbitrary address capable (e.g. On-Highway Trailers.)
See section 4.2 of this document for details of the address claim process.

2 - Hardware configuration to test the J1939.c CAN library

Our hardware configuration to test the J1939.c CAN library was this:

J1939_STARTING_ADDRESS 128 129


J1939_ARBITRARY_ADDRESS 0 0
J1939_INDUSTRY_GROUP 2 2
J1939_VEHICLE_INSTANCE 10 10
J1939_VEHICLE_SYSTEM 5 5
J1939_FUNCTION 98 98
J1939_FUNCTION_INSTANCE 11 11
J1939_ECU_INSTANCE 2 2
J1939_MANUFACTURER_CODE 321 321
J1939_IDENTITY_NUMBER 12344 12345

2 PIC CAN bus + RS232 configuration to test J1939.c CAN library - the nodes' NAMEs differ only
by the J1939_IDENTITY_NUMBER (12344 for node A, 12345 for node B)

Notice that this generates the folowing 64 bit NAMEs:

2A 0A 62 5A 28 20 30 38 (#128)
2A 0A 62 5A 28 20 30 39 (#129)

Reading the source code raised the first suspicions.


But as we like empirical stuff , we traced the bug in a more difficult way:

1. our breadboard assembly was downsized to have just 2 functional PIC18F4580, one of them with the UART
interface connected to the PC
2. the J1939 NAMEs and Source Addresses were matched to the simulation run with Michael Eisele's Xtm, as
we got quite familiar with these bytes by now
3. added a few instructions to compareNames() function, see below the highlighted code
4. so that while reacting to the generated Address Claimed message, the CAN - UART PIC compareNames()
function outputs the values of the compared NAMEs arrays thru the serial port
5. which we then colect in the PC's terminal program

4 of 9 28/09/2012 22:53
J1939 CAN bus spy, Chapt. 7: bug in Microchip App. Note J1939.c library http://recursos3.planetaclix.pt/canuart/index_7.html

3 - The bug in the Function CompareName ()

Running the code in MPLAB simulator, then watching the array CA_Name:

Again, notice that the NAME's bytes are output to the CAN bus in the reverse order of their priority.
If you remember the previous chapter, bit 7 of that last byte CA_name[7] = 0x2A is the place where the Arbitrary
Address Capable bit (in our case it is 0) ended...

In the PC's Terminal v1.9b (provided by Bray++) window we collect the folowing strings, dumped by our UART:

43 41 4E 55 61 72 74 30 30 37 0D our "splash" CANUart007 start-up string


67 7A FF 80 08 38 30 20 28 5A 62 0A 2A CAN address negociation node 0x80
38 30 20 28 5A 62 0A 2A CompareName () Uart output shows wrong order
67 7A FF FE 08 38 30 20 28 5A 62 0A 2A CANnot claim address

/*********************************************************************
CompareName
This routine compares the passed in array data NAME with the CA's
current NAME as stored in CA_Name.
Parameters: unsigned char * Array of NAME bytes
Return: -1 - CA_Name is less than the data
0 - CA_Name is equal to the data
1 - CA_Name is greater than the data
*********************************************************************/
signed char CompareName( unsigned char *OtherName )
{
unsigned char i;

for (i = 0; (i<J1939_DATA_LENGTH) && (OtherName[i] == CA_Name[i]);


UARTIntPutChar(CA_Name[i]),
i++);

if (i == J1939_DATA_LENGTH)
return 0;
else if (CA_Name[i] < OtherName[i] )
return -1;
else
return 1;
}

5 of 9 28/09/2012 22:53
J1939 CAN bus spy, Chapt. 7: bug in Microchip App. Note J1939.c library http://recursos3.planetaclix.pt/canuart/index_7.html

Function CompareName () with code added to output CA_Name[i] bytes thru


the serial port

The error in the code is that instead of comparing from Name[0] up to Name[7] it should be done in reverse, from
Name[7] down to Name[0] - because the NAME's bytes are output to the CAN bus in the reverse order of their
priority.
With the code "as is", the contention is wrongly decided by first looking at the 64th bit, in the low byte of Identity
Number, then the second byte of Identity Number etc. etc., but SAE J1939-81 says it should start by the 1rst
bit, our old Arbitrary Address Capable.

4 - Nevertheless J1939.c CAN library is a nice piece of code

Don't get me wrong, other then the Function CompareName () bug, on the whole this is the best (free) piece of
source code I came upon, related to J1939.

And if you didn't notice yet, let me show you that it is prepared to be integrated in Application Maestro, which is quite
useful to generate code for diefferent configurations.

To see it yourself, grab Application Maestro from Microchip's site, install and launch (or check if you already have it
at \Program Files\Microchip\MpAM):

But it is not showing CAN J1939? Well, it needs some customization.


If you have your Microchip's J1939.c CAN library source code available, have a look at the .zip file, and there you
find:

6 of 9 28/09/2012 22:53
J1939 CAN bus spy, Chapt. 7: bug in Microchip App. Note J1939.c library http://recursos3.planetaclix.pt/canuart/index_7.html

The content of a module is defined in the Application Maestro Software script file named j1939.cls, which is located
at the root level of the Modules folder.
The Application Maestro Software uses this file to provide information for the Available Module pane (name,
revision level, language format and descriptive comments), as well as define the valid range of the configurable
parameters and the output for the module.

So, extract the above files to \Program Files\Microchip\MpAM\Modules\J1939 then move j1939.cls up one level to
folder \Modules.

** Don't forget to edit \Program Files\Microchip\MpAM\Modules\J1939\j1939.c and ammend the ill-fated


CompareName (). **

Close then relaunch MpAm.exe, and now you have a new module ready:

7 of 9 28/09/2012 22:53
J1939 CAN bus spy, Chapt. 7: bug in Microchip App. Note J1939.c library http://recursos3.planetaclix.pt/canuart/index_7.html

And now you can configure your j1939 node in the left pane with much ease.

5 - What is next?

Don't want to look paranoid, but Vector's CAPL code for their AddressClaiming_CN.cfg sample, which we used for
our Chapter 5, is also wrong (yes - the same bug; perhaps there is some link between these two sources?).
So next time we go over that.

Stay with us, may be we will get somewhere!

Don't forget: if you don't want to miss the next chapter, just drop me an email
to recursos.pt@gmail.com subject: J1939 CAN, and I will notify you.
No other use will be made of your e-mail address.

8 of 9 28/09/2012 22:53
J1939 CAN bus spy, Chapt. 7: bug in Microchip App. Note J1939.c library http://recursos3.planetaclix.pt/canuart/index_7.html

And that's all, folks.


Please let me know of any broken links, missing parts etc. you may find here.
Next issues will become more sophisticated - I hope!.

Free Hit Counter


<< back to main page
<< previous chapter ( Michael Eisele's Xtm CAN bus simulator)

(Vector's AddressClaiming_CN.cfg sample bug) next chapter >>

©Rec (recursos.pt@gmail.com)
06-05-04

9 of 9 28/09/2012 22:53

You might also like