Het formaat van een CAN-bericht
CAN 2.0
Oorspronkelijk omvatte CAN enkel 11-bit identifiers. Bosch voegde de variant met 29-bit identifier toe om in Amerika de SAE J1939-standaard te kunnen ondersteunen. Dit gebeurde in 1991 en werd geïntroduceerd als CAN 2.0. Vandaag de dag kennen we enkel nog CAN 2.0 controllers. De CAN 2.0 standaard bestaat dus uit twee onderdelen:
- 11-bit identifier, ook wel CAN Standaard of 2.0A genoemd en
- 29-bit identifier, ook wel CAN Extended of 2.0B genoemd
Beide ‘soorten’ mogen door elkaar heen gebruikt worden, maar zijn wel verschillend. Een Standaard CAN-bericht met Identifier = 0, is een ander bericht dan een Extended CAN-bericht met Identifier = 0.
Een standaard CAN-bericht
Het onderstaande figuur geeft het formaat van een standaard CAN-bericht weer. Het begin van een bericht is te herkennen aan een dominant bit voorop, gevolgd door een 11-bit lange berichtensleutel en een volgend bit dat een onderscheid maakt tussen een dataframe en een dataverzoekframe (= Remote Request Frame, zie verderop).
Veldnaam | Lengte [bits] | Doel |
SOF = Start-of-frame | 1 | Maakt start van een bericht duidelijk door de bus naar dominant '0' te trekken |
Identifier | 11 | Een (unieke) identificatie voor de data die ook de berichtprioriteit aangeeft |
RTR = Remote transmission request | 1 | Dominant '0' voor een dataframe, zie ook het Remote Frame hier beneden |
IDE = Identifier extension bit | 1 | Dominant '0' voor een standaard (11 bits Id) CAN-frame |
r0 = Optional Reserved bit | 1 | Gereserveerd bit moet dominant '0' zijn! Recessief '1'staat voor CAN FD-formaat. |
DLC = Data length code | 4 | Aantal data byte's (0–8 bytes) |
Data field | 0 – 64 | Data die verzonden wordt (aantal bytes bepaald door het DLC-veld) |
CRC = Cyclic Redundancy Check | 15 | Controle rekensom over alle voorgaande velden |
CDL = CRC delimiter | 1 | Moet recessief '1' zijn |
ACK = Acknowledge slot | 1 | Zender stuurt recessief '1' en (iedere) ontvanger kan met dominant '0' de succesvolle ontvangst terug melden |
ADL = Acknowledge delimiter | 1 | Moet recessief '1' zijn |
EOF = End-of-frame | 7 | Moet recessief '1' zijn |
Het dataveld van een CAN-bericht kan tussen de nul en acht databytes bevatten. Het dataveld wordt gevolgd door een 15-bits CRC-segment. Dit veld wordt gebruikt door de ontvanger om het bericht te controleren. In het acknowledge-veld verwacht de zender van een bericht erkenning door van tenminste één ontvangende node’s binnen het netwerk het signaal te ontvangen dat het bericht foutloos is ontvangen. Deze erkenning wordt gegeven door de transmissie van een dominante bit in het acknwoledge-veld door alle (ontvangende) knooppunten binnen het netwerk die het bericht foutloos ontvangen hebben. Deze ontvangstbevestiging wordt uitsluitend gebruikt voor het uitsluiten van fout verzendende node’s. Uiteindelijk geeft het ‘einde bericht’-veld de afsluitende en foutloze transmissie van een CAN-bericht aan. Zoals al eerder aangegeven zal, indien een node een fout heeft vastgesteld, het bericht direct onderbroken worden door een Error-frame met dominante ‘0’-en.
Een Extended CAN-bericht
Het onderstaande figuur geeft het formaat van een Extended CAN-bericht weer. Het basisverschil is dat een Extended CAN-bericht een Identifier-veld van 29-bits heeft. Dit was primair nodig om CAN aan de J1939-standaard te laten voldoen.
Veldnaam | Lengte [bits] | Doel |
SOF = Start-of-frame | 1 | Maakt start van een bericht duidelijk door de bus naar dominant '0' te trekken |
Identifier A | 11 | Deel A van een (unieke) 29-bits identificatie voor de data die ook de berichtprioriteit aangeeft; MSB bits 28 t/m 18 |
SSR = Substitute remote request | 1 | Recessief '1', maakt het mogelijk dat een standaard 11-bits CAN data-bericht de arbitrage wint van een extended CAN-bericht |
IDE = Identifier extension bit | 1 | Recessief '1' voor een extended (29 bits Id) CAN-frame |
Identifier B | 18 | Deel B van een (unieke) 29-bits identificatie voor de data die ook de berichtprioriteit aangeeft; LSB bits 17 t/m 0 |
RTR = Remote transmission request | 1 | Dominant '0' voor een dataframe, zie ook het Remote Frame hier beneden |
r0 = Optional Reserved bit | 1 | Gereserveerd bit moet dominant '0' zijn! Recessief '1'staat voor CAN FD-formaat. |
r1 = Optional Reserved bit | 1 | Gereserveerd bit moet dominant '0' zijn, maar recessief '1' wordt ook geaccepteerd |
DLC = Data length code | 4 | Aantal data byte's (0–8 bytes) |
Data field | 0 – 64 | Data die verzonden wordt (aantal bytes bepaald door het DLC-veld) |
CRC = Cyclic Redundancy Check | 15 | Controle rekensom over alle voorgaande velden |
CDL = CRC delimiter | 1 | Moet recessief '1' zijn |
ACK = Acknowledge slot | 1 | Zender stuurt recessief '1' en (iedere) ontvanger kan met dominant '0' de succesvolle ontvangst terug melden |
ADL = Acknowledge delimiter | 1 | Moet recessief '1' zijn |
EOF = End-of-frame | 7 | Moet recessief '1' zijn |
Omdat het extended CAN-bericht later aan de CAN-standaard werd toegevoegd, moest het extended-bericht dusdanig aangepast worden dat het naast het standaard bericht past. Dit is gerealiseerd door de 29-bits identifier te verdelen in een 11-bits deel A (het standaard CAN-bericht Id) en een aanvullende 18-bits deel B. Een oorspronkelijk gereserveerd bit is omgedoopt in IDE om een onderscheid tussen standaard (IDE=’0’) en extended (IDE=’1’) te maken. In het extended frame werd een extra geserveerd bit toegevoegd. Het SSR-bit heeft een speciale functie: het zorgt ervoor dat een standaard 11-bits data-bericht de arbitrage wint van het vergelijkbare 29-bits extended data-bericht. Stel dat twee CAN-node’s tegelijkertijd een bericht willen verzenden met standard Id = 0h én extended Id = 0h, dan zal de node die standard Id = 0h bericht verzend de arbitrage winnen.
Remote Request Frame
Een CAN-node kan een Identifier opvragen door een Remote Request Bericht te versturen. Het is een CAN-bericht zonder data-veld én met het RTR-bit gezet op recessief '1'. Het is er natuurlijk in de smaken standaard en extended. Een Remote Request bericht kan het beste worden vertaal met “Identifier?”. het is de bedoeling dat de ‘eigenaar’ van de gevraagde identifier reageert door het corresponderende CAN data-bericht te versturen. Dit is echter afhankelijk van het soort CAN-controller: CAN controllers met een zogenaamd Dual Port Memory zullen het Id in hun DP-memory herkennen en autonoom de bijbehorende data op de bus versturen. CAN controllers die als UART werken kunnen het RTR-bericht alleen maar doorgeven en de achterliggende software zal dan de juiste acties dienen te ondernemen. Zo is dat o.a. in de CANopen-stack voorzien. Logischerwijs is het RTR-bit in een Remote Request bericht recessief '1'. Zodoende verliest een dergelijk bericht de arbitrage t.o.v. het bijbehorende databericht. Het verzenden van de data heeft immers een hogere prioriteit dat het opvragen ervan.