CAN Bus Setup

Note: If you are only interested in bit-rate calculator, skip to the bottom.

Illustration

As you start designing CAN bus node around Microchip’s PIC microcontroller everything seems deceptively simple on the paper. Like with good old UART you only set for a node frequency and everything is fine and dandy. And then reality hits with various bit times and their “fuzzyness”. At times it might seem that there are a gazillion different ways it can be configured. How to decide?

There are four main parameters that determine all others. Obvious one is microcontroller’s frequency. You are pretty much required to use crystal because CAN bus tolerances and stability needs don’t allow for internal oscillator. My personal preference is using 12 MHz crystal as an oscillator source. 12 MHz allows quite high frequency (48 MHz with PLL) and it is quite commonly used for USB so you can share it (via REFO pin) with other devices on board (e.g. serial to USB converter).

Since all CAN nodes have to share the same baud rate, decision is made for you if the new node has to be integrated in the existing network. If you are designing your bus from scratch there is a whole slew of speeds you can select. I personally like to stick with CiA DS-102 defined speeds (10, 20, 50, 125, 250, 500, 800 and 1000 kbps). Higher baud rate allows for more messages/second but it works only at shorter distances and demands for better frequency stability. Lower baud rates allows for more distributed nodes and you might even get away with R/C oscillator source (at very low speeds). I use 125 kbps (500 meters max) as a starting point and deviate only if I really have to.

Maximum bus length is function of allowed signal delay. Higher the bitrate lower the distance and vice-versa. This parameter is basically our sanity checking mechanism and one of inputs when we calculate propagation segment duration.

Time quanta (TQ for friends) is smallest time unit in CAN bus and it controls duration of a single bit. To represent a single bit, you need between 8 and 25 TQ. Those TQ units are further subdivided into synchronization segment (always 1 TQ), propagation segment (1-8 TQ), phase segment 1 (1-8 TQ) and phase segment 2 (1-8 TQ). Bigger the TQ, more control you have over fine bit tuning but at the cost of higher frequency need (i.e. 16 TQ subdivision will need double the frequency compared to 8 TQ to maintain same bit rate).

Synchronization segment always last for single quanta and CAN bus uses it internally to adjust bit edge. This ensures that various nodes don’t drift in time because of slight frequency differences. This is only segment with fixed duration.

Propagation segment that follows is there to compensate for a physical delay of the signal going over wire and its receival in driver. Rule of the thumb is that its value gets bigger with physical distance.

Phase segment 1 tells us duration (in TQ) before bit is actually sampled from line. Higher value you have, later sampling will occur. Actual sampling happens after sync + propagation + phase 1 quanta. More often than not, you want this time to be as close to the full quanta as possible.

Phase segment 2 is last segment and its duration concludes full bit time. It is very useful to keep this at at least 2 TQ because otherwise your sample point might get too close to edge of next bit.

First programming parameter that PIC will actually use is the baud rate prescaler (BRP). Based on it we determine bit rate according to following formula BRP = FREQUENCY / (2 * TQ * BITRATE). This value than gives you actual TQ time (TQTIME = 2 * (BRP + 1) / FREQUENCY). From that you can get duration of a single bit (TBITTIME = TQ * TQTIME). Since BRP value can only be integer, to get nominal bit rate PIC we use another calculation BITRATE = 1 / TBITTIME. If everything goes alright actual bit rate will match desired bit rate. If such thing does not happen, a bit of input parameter tweaking might be beneficial.

I prefer to calculate phase 1 duration next. General rule is to have it last as long as possible. Half of total bit duration is as good approximation as any. Of course, maximum of 8 TQ.

Propagation segment length gets calculated based on desired physical bus. I use standard 5 ns/m figure for bus delay and I add 250 ns as worst case processing delay in transceiver and use that as a minimum value. If TQ is higher propagation delay must be increased regardless of actual physical distance because of phase 1 and phase 2 having maximum of 8 TQ.

Phase 2 gets calculated from whatever is left after sync, propagation and phase 1 segment get their share.

Synchronization jump width is fuzziest of them all. In theory it would help you if clock drifts between nodes. However, make it too big and PIC starts detecting sync bits where there are none. I usually go with half of propagation length as a starting point and then I adjust it not to be longer than either phase 1 or phase 2. This gives a bit of wiggling space for clocks to drift but it is not overly aggressive.

Below is a small form which actually does these calculations. Might come in handy.

MHz
kbps
m
 
kbps
m
%
 
(- TQ)
(- TQ)
(- TQ)
(- TQ)

PS: Some additional information that might be useful:

Forcing Rebuild in MPLAB X.

Illustration

For a project of mine I needed a random serial number. I got it in Intel hex file not by memory address as you would commonly have, but by search & replace of a string. While I prefer this approach in most cases, it also meant that once code has been replaced, next replace would fail. I needed a rebuild.

Unfortunately MPLAB is too smart and it avoids rebuilding if no file has been changed. Of course there is no option to force rebuild either. Only thing left is to actually change a file or at least its time.

Under Linux there is a touch command. Under Windows there is an almighty copy. To update file time we need to simply execute:

COPY /B **source**+,,

To use this in MPLAB X go to project Properties, Building and check Execute this line before build. In text box underneath just apply newly found command on project’s main file (App.c in my case):

COPY /B **${ProjectDir}\App.c**+,,

The Logon Attempt Failed

Illustration

Ever since I moved to USA, I have been using TeamViewer as a connection platform of choice. Reasoning was simple; it works over any firewall you can throw at it and my move was only to last for a few months. Few months turned into years so I finally decided to get myself a bit better wireless router. And since it supports VPN, I could start using Microsoft Windows Remote Desktop Connection again. Serves same purpose as TeamViewer, but I find it a bit nicer to use.

First computer to get remote desktop was one kids used. Configuration was as annoyingly clickable as ever. First go to System, then Advanced system setting and check Allow remote connections to this computer on Remote tab. If you have password-less user (as I did), setup a password for user and (optionally) use Autologon utility so you don’t need to enter it every time. Not the most secure setup but good enough for something that runs Worms and Dungeon Keeper 90% of time.

However, something obviously went wrong as I was greeted with The logon attempt failed error. Running Wireshark on destination computer proved that packets were coming in but, for some reason my authentication failed. And no, I didn’t have a wrong password. Quick check from my mobile phone proved as much; my Android connected without any issues. Only issues were on Windows 8.1 to Windows 8.1 front.

After some time I figured what the issue was. I had my computer synchronized with Microsoft Account. My kids’ account was a local one. Somebody in Microsoft decided that, if you have Microsoft Account on one side, Remote Desktop Connection would assume you had it on other side too. Pretty stupid if you ask me, especially because you cannot see it anywhere if you enter user name manually (you do get to see it in small print if you leave user name empty).

Solution was simple enough once I knew what I was dealing with. Since workgroup on destination computer was named Medved, I have entered Medved\Username as an user name. Remote Desktop Connection was fortunately still smart enough to turn off Microsoft Account stupidity and my connection was established.

PS: Don’t misunderstand me. Having a possibility of using Microsoft Account in Remote Desktop Connection is quite a nice thing. However, I hate when program changes my input without letting me know. And it is not as if they couldn’t support it both ways - every Microsoft Account is in e-mail address format. Why not use MicrosoftAccount domain only for those? Or just show me somewhere in small letters which domain you are using. Don’t leave me in the dark.

Serial Number in Intel Hex

While doing an electronic project in MPLAB, I found it necessary to create an unique serial number for each device I program in order to have a proper USB functionality. Something as simple and often needed as this has to be already solved. Or so I thought.

Oh, I found solutions and solutions for this particular issue. Most of them were only useful with their device programmers - and I wanted something to work inside of MPLAB. Some other worked by modifying source code - a big no-no when you do source control. Some required serial number placed at an exact location - annoying (and volatile) to calculate in my case because USB serial number is a part of a bigger structure. Commercial solutions were also out of question… With each visited link I grew more firm in decision to roll out my own (“me hammer, problem nail” approach).

However, simple replacement is not necessarily an easy thing to do. You see, in world of microcontrollers Intel Hex format is the ruler. Without getting into details, format has two characteristics that make it suitable for firmwares. It splits data into fixed length blocks which is really nice when you have to do chip programming in blocks. Additionally every row is checksumed so data corruption can be avoided. Both those characteristics conspire against us to do simple file change. Not only that we cannot just simply change data because of checksum but we often cannot even simply find it because it can span across the rows.

So, it was a scripting time. Because of annoyingly difficult parsing, simple CMD was out of question. Only other choices were PowerShell or a completely custom program. While custom program would probably offer easiest development, I didn’t want to embed only executable. And embedding sources would mean that I would need Visual Studio on each machine I want to compile this at - to high cost in practicality. Only other choice really was PowerShell - environment that exists on every Windows 7 and higher machine.

Requirements were straightforward. I wanted something that would be a single call (Microchip’s MPLAB can call only single external build command). It had to replace file in-place (so that I could continue using PICkit 3 programming procedure). It had to change file as little as possible (e.g. by not removing extra headers). It had to support ASCII random (USB MSD specifications). And, lastly, it had to be capable of producing a valid output hex without checksum shenanigans.

I won’t dwelve into boring details and explain each part of code but it suffices to say that it loads whole file in memory, searches for placeholder and then replaces that placeholder with random value, adjusting the checksum as it goes. End result is the file that gets pushed onto the device.

Here is an example command (Project Properties, Conf, Building, Execute this line after build):

PowerShell.exe -ExecutionPolicy RemoteSigned -File ${ProjectDir}\..\Setup\HexReplace.ps1 **${ProjectDir}\dist\default\production\Source.production.hex** **197901281815** -**AsciiHexRandom** -Destination2 **${ProjectDir}\..\Binaries\TmpUsb.hex**

First part we might as well ignore because it is only preparing terrain for script by calling PowerShell. First meaningful argument is a location of an intermediate Intel hex file followed by a placeholder value. Since my device is USB based, I opted to have a valid serial number (197901281815) as a placeholder - makes live easier if script fails. Most common approach is to use something that won’t appear by accident (various number of X characters seem to be popular choice). Anything unique will do.

Switch AsciiHexRandom ensures that our randomness will be limited to numbers 0 to 9 and letters A to F, as required by MSD Bulk Only Transport 1.0 specification. If that parameter gets omitted random binary (0 to 255) will be used. Which one is better actually depends on your use case.

Last pièce de résistance is -Destination2 argument. That ensures script will not only change file but additionally copy it to a different place. It is not strictly necessary but I find it useful for archiving purposes. You can omit it without any consequence.

And that is my way of generating random serial number from within MPLAB project. Try it out and see whether it fits your needs.


PS: Script itself was not designed but grown. As such it is full of unoptimized code (just check function that does replacement) and it treats memory as kids treat candy. But realistically we are speaking about file that won’t be bigger than couple hundreds KB in the worse case scenario. I could not justify spending time I would need to make it “proper” when it already runs (unoptimized) within a fraction of a second.

PPS: Yes, I have cheated by embedding C# code inside of PowerShell.

PPPS: If something goes wrong, add -debug argument. That will give you a bit more information to go with.

Password Change, Why?

Illustration

Heartbleed OpenSSL bug is currently main computer topic of main-stream media. And they all offer same idiotic advice - change the password. I am not saying that “change the password” mantra is useless. No, it is bloody dangerous.

Let’s see what bug does first: it simply allows attacker to read (semi)random 64K block of memory it should not see. And it allows it to repeat that attack until it has all the data it wants. If leaked blocks contain a cookie, somebody can impersonate you. If they contain user name and password, attacker just got a jackpot. If they contain private SSL key, attacker is in heaven.

Based on that fact, password change seems reasonable. But think again. Practically only way OpenSSL might have your password in its memory is if you sent it to him in the first place. When was the last time you actually sent password for e.g. GMail? Answer is a long time ago. Only piece of data server can have for you is your cookie that keeps you logged in. And you can reset that one with a simple logout. But that is not the dangerous part.

If you change password on server that is still compromised, you are putting it in OpenSSL’s memory at that exact moment. In essence, you are giving away your newly created password directly to an attacker. And, since password is freshly changed, you probably wont change it for a while. It is WORSE than doing nothing.

For safety first approach log out of any important service you are using. That way you are preventing somebody using your login cookie. Then go and CHECK whether site is compromised. Once you know host is not compromised any more, log in again. And ONLY THEN think about changing the password.

If host is still compromised, do not log onto it. I don’t care what is the service it offers. Either it is important (e.g. bank website) or it is not worth the risk.


PS: To summarize: I am not against the password change - it is probably a wise move since this bug has been out for last two years. I am just against doing it irresponsibly, without checking whether site has been fixed first.

PPS: Since you are changing passwords anyhow, be intelligent and use different password for each site.

PPPS: Seems as a good time to turn on two-factor authentication (if website has it).