Low Level CAN Framework Application Programmers Interface
来源:互联网 发布:解绑支付宝与淘宝账户 编辑:程序博客网 时间:2024/06/07 01:01
Contents
- Introduction
- Legal Notices
- Extended Disclaimer
- Logo
- Linux Module License
- Transport protocols
- General information on the socket API in LLCF
- Timestamp
- RAW Sockets
- Test programms
- Sockets for Broadcast-Manager
- Communication with the Broadcast-Manager
- TX_SETUP
- TX_DELETE
- TX_READ
- TX_SEND
- RX_SETUP
- LLCF status in /proc Filesystem
- Version information: /proc/net/can/version
- Statistics: /proc/net/can/stats
- Resetting statistics: /proc/net/can/reset_stats
- Internal receive lists on the RX dispatcher
- CAN network devices in the directory /proc/net/drivers
- Contact
Introduction
Among various projects in the research department of Volkswagen AGthere is a so-calledLow Level CAN Framework (LLCF) developed for easy access of the communicationlayers of theController Area Network (CAN) for applications. TheLow Level CAN Framework should, where possible, be modular in design to the greatest possible extentto achieve reuse in other projects.
Essential components of the LLCF are the network (!) Driver for thedifferent CAN controller and the overlying protocols such as TP1.6,TP2.0, MCNet, ISO-TP, etc. These components are implemented in the Linux Kerneland are using the standardized Socket interface. The goal of this concept isthat communication on the CAN bus be as far as possible similar to the ordinary useof TCP/IP sockets. This is only partly possible because theCAN bus has a number of differences with TCP/IP and Ethernet:
- CAN has no device addresses as the MAC addresses in Ethernet. The CAN frame contains a CAN-ID, the standard being that CAN-IDs match real devices likely and represent a sender address. Because all messages are broadcast, it is not possible to send a CAN message to a signle device. Devices on the CAN bus receive all messages and can only use the CAN-ID as 'return address' filter. CAN frames cannot therefore - as with Ethernet - be explicitly adressed to a target device.
- There is no network layer and therefore no Network-layer addressing, such as IP addresses. Consequently, there is no routing (e.g. via different network interfaces), as is possible with IP addresses.
These differences mean that the structure struct sockaddr_can
is not entirelyanalogous to the knownstruct sockaddr_in
for the TCP/IP protocol family.The process to establish a connection and the use of open sockets for data exchange,however, are heavily based on TCP/IP model.
Besides this document, there are also the manual pages:socket(2),bind(2), listen(2),accept(2),connect(2), read(2),write(2),recv(2), recvfrom(2),recvmsg(2),send(2), sendto(2),sendmsg(2),socket(7), packet(7) relevant toLLCF.The manual mages ip(7),udp(7) and tcp(7) give insights on thefoundations on which theLLCF is based.
The Low Level CAN Framework is in addition to the known protocols, such as thethe ones from the Internet Protocol family PF_INET. A new protocolfamily PF_CAN has been introduxed. To meet time constraints, the implementationof the various CAN protocols has been made as kernel modules, in the kernel context. Animplementation in user sapce could not have met the same constraints.During execution of different applications (leading to several open socket instances), thesame code is used for execution.
The LLCF provides various transport protocols and theso-calledBroadcast-Manager (BCM). In addition a RAW socket is provided, to givedirect access to the CAN bus without intervening protocol layers.
A special feature is the so-called LLCF RX-dispatcher. It is used to managethe addressing of CAN-frames by CAN ID. By using theLLCF functions rx_register()and rx_unregister(), the protocol modules can register one or more CAN-IDs theyare interested in and theLLCF-core module will dispatch the messages at the receptionautomatically. TheLLCF-core module sends to the CAN bus a local echo ('local loopback') ofsent CAN frames to allow all applications on a system to share the same information.
For the connection of the CAN network drivers, a new'Ethernet protocol type' ETH_P_CAN was introduced to allow the transitof the received CAN frames through the Linux network layer. TheLLCF-core moduleregisters himself as recipient of ETH_P_CAN 'Ethernet frames' to the kernel.
Through the consistent implementation of the CAN bus withinterfaces from the established information technology standard,many opportunities open up for the user (programmer).I.e. Any number of sockets (also different socket types ondifferent CAN buses) from one or more applications can be open simultaneously.When communicating with different sockets, for example,select(2) can be usedto write efficient and simple code.
Legal Notices
Volkswagen requires that the users read, understood and accepted thefollowing the legal notices.
In the source code of the Low Level CAN Framework there is the following notice:
/* * Copyright (c) 2002-2005 Volkswagen Group Electronic Research * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, the following disclaimer and * the referenced file 'COPYING'. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Volkswagen nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * Alternatively, provided that this notice is retained in full, this * software may be distributed under the terms of the GNU General * Public License ("GPL") version 2 as distributed in the 'COPYING' * file from the main directory of the linux kernel source. * * The provided data structures and external interfaces from this code * are not restricted to be used by modules with a GPL compatible license. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * Send feedback to <socketcan-users@lists.berlios.de> * */
Extended Disclaimer
In the scope of the German law there is also, in case of free transfer fromgross negligence or intentionally concealed defects, the possibility that theauthor can be held liable for resulting (consequential) damage.
Although the authors strive to make available error-free software, they cannotexclude bugs. Therefore, the user that agrees to the use ofLow Level CAN Framework, agrees to the disclaimerin relation to the Authors and Volkswagen AG and fully recognize and waive any legaloptions / claims in the event of Defects / damage / damages resulting from the use of theLLCF.
Logo
The logo of the Low Level CAN Framework('/dev/ beetle') is a compoundfigurative mark owned by Volkswagen AG. It symbolizes the integrationof the vehicle in a neighborhood of the standard information technology.
Linux Module License
Part of the complete LLCF distribution is not subject to the GNU PublicLicense, but is proprietary code of Volkswagen AG. This is the source code ofthe individual Kernel modules marked with the macroMODULE_LICENSE("VolkswagenGroup closed source"). When loading thoseLLCF modules in theKernel the following warning message will be displayed:
Warning: loading can-tp20.o will taint the kernel: Volkswagen Group closed sourceSee http://www.tux.org/lkml/#export-tainted for information about tainted modulesModule tainted loaded, with warnings
This is a warning that the module is not loaded under the GNUPublic License, but it does not affect the functionality of theLow Level CAN FrameworkTypically, however, questions about error messages generated by 'contaminated' tainted kernelsare not, in general, commented / answered by the Linux community.
Modules, which are under the GNU Public License contain the macro MODULE_LICENSE("GPL").
Transport protocols
The complete LLCF distribution contained protocol modules forTransport protocols (currently TP1.6 VAG, VAG TP2.0, Bosch MCNet)that are only available in conjunction with a Non Disclosure Agreement (NDA)available for suppliers of Volkswagen AG. This protocol modules have no referencedrivers.
The source code for the designated CAN transport protocol isclearly separated modules, and existed before integrationin the Linux Kernel:
This TP code is in clearly seperate modules and had a life outside Linuxfrom the beginning and does something self-contained that doesn'treally have any impact on the rest of the kernel. The transportprotocol drivers have been originally written for something else anddo not need any but the standard UNIX read/write kind of interfaces.See <http://www.atnf.csiro.au/people/rgooch/linux/docs/licensing.txt>
MCNet is a CAN transport protocol by Robert Bosch GmbH. Theimplmentation is covered by MCNet disclaimersANFORDERUNG DER MCNet-SPEZIFIKATION dated 13.07.1998.More information on MCNet are available from:
Robert Bosch GmbH
Abteilung K7/EFT62
Postfach 77 77 77
D-31132 Hildesheim
Contact:
Dr. Uwe Zurmühl uwe.zurmuehl@de.bosch.com
Detlef Rode detlef.rode@de.bosch.com
General information on the socket API in LLCF
For communication on the CAN bus a new protocol familyPF_CAN
has been implemented in the socket Layer. From the user,or programmer's, point of view it is analogous to Internet protocol sockets(protocol familyPF_INET
) with the standard system callssocket(2),bind(2), listen(2),accept(2),connect(2), read(2),write(2) undclose(2). See also the introduction in chapter 1.
In contrast to the address structure of Internet addresses (sockaddr_in
),the addressing of the PF_CAN sockets needs other content. The address structure issockaddr_can
, defined in the include fileaf_can.h
:
struct sockaddr_can { sa_family_t can_family; int can_ifindex; union { struct { canid_t rx_id, tx_id; } tp16; struct { canid_t rx_id, tx_id; } tp20; struct { canid_t rx_id, tx_id; } mcnet; } can_addr;};
In addition to the interface index of the CAN interface, the CAN-IDs tx_id
andrx_id
is particularly relevant for the respective transport protocols.Transport protocols offer on the CAN bus a virtual point-to-point connection betweentwo CAN-IDs.
Another important structure represents the CAN frame, thatthe include file can.h
defines:
typedef __u32 canid_t;struct can_frame { canid_t can_id; /* 32 bit CAN_ID + EFF/RTR flags */ __u8 can_dlc; /* data length code: 0 .. 8 */ __u8 data[8] __attribute__ ((aligned(8)));};/* special address description flags for the CAN_ID */#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */#define CAN_RTR_FLAG 0x40000000U /* remote transmission request *//* valid bits in CAN ID for frame formats */#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
The structure can_frame
contains the elements of aCAN frame, as defined on the CAN bus. The arrangement of theData (byte order, word order, Little/Big Endian) on theCAN-bus is generally not defined, so the data elementsdata[]
are kept in an array of 8 bytes. Since thedata elements, however, focus on an 8 byte memory limit,access is possible up to a width of 64 bits:
#define U64_DATA(p) (*(unsigned long long*)(p)->data)U64_DATA(&myframe) = 0xFFFFFFFFFFFFFFFFULL;U64_DATA(&myframe) = 0;
By separating the information in the include files af_can.h
andcan.h
, only the include filecan.h
is necessary to create aCAN network-driver.
Timestamp
For the applications in the CAN environment it is often of interest anaccurate timestamp, that is the time of reception of a message from CAN bus.Such a timestamp can be read withioctl(2) after reading a message fromthe socket. This also applies to the sockets of transport protocols, where thetimestamp is that of the last corresponding TPDU. The call - for exampleioctl(s, SIOCGSTAMP, &tv)
-is used in the respective test programs for illustrative purposes.
The timestamp on Linux have a resolution of one microsecondand the reception of a CAN frame in CAN-Network Device is set automatically.
RAW Sockets
Raw sockets allow direct reception and transmission of messages on a CAN bus.Open a RAW socket like this:
s = socket(PF_CAN, SOCK_RAW, 0);
The open socket must first be bound using bind(2) to a CAN-bus interface.The transport protocols address elementstx_id
and rx_id
in thestruct sockaddr_can
structure have no role. The following code binds theopen socket s to the CAN-InterfaceCAN1
:
struct sockaddr_can addr;struct ifreq ifr;addr.can_family = AF_CAN;strcpy(ifr.ifr_name, "can1");ioctl(s, SIOCGIFINDEX, &ifr);addr.can_ifindex = ifr.ifr_ifindex;bind(s, (struct sockaddr *)&addr, sizeof(addr));
It can now use read(2) to receive all CAN frames available on the busandwrite(2) to send CAN frames.
read(2) and write(2) use the structurestruct can_frame
.For each CAN frame to be sent one call write(2) must be made andfor for each call toread(2) one CAN frame is received.
For simultaneous reception of messages on all CAN network interfaces(for example, withrecvfrom(2)) use zero (0) as the interface index (for example:addr.can_ifindex = 0
). The transmission of CAN frames over such a RAW socketmust then make use ofsendmsg(2).
The RAW socket provides a simple filter function by specifying ranges of CAN IDsthat can be filtered out from the data stream. This may be done before callingbind(2)with the system call setsockopt(2) and an array of simple filters to be set. In thisExample, all CAN IDs from 0x200 - 0x2FF are passed:
struct can_filter rfilter;rfilter.can_id = 0x200; /* SFF frame */rfilter.can_mask = 0xF00;setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
By using rfilter.can_id |= CAN_INV_FILTER;
the filter can also bereversed so that in this case, the CAN-IDs from 0x200 - 0x2FFwould not be allowed through.
struct can_filter rfilter[4];rfilter[0].can_id = 0x80001234; /* Exactly this EFF frame */rfilter[0].can_mask = CAN_EFF_MASK; /* 0x1FFFFFFFU all bits valid */rfilter[1].can_id = 0x123; /* Exactly this SFF frame */rfilter[1].can_mask = CAN_SFF_MASK; /* 0x7FFU all bits valid */rfilter[2].can_id = 0x200 | CAN_INV_FILTER; /* all, but 0x200-0x2FF */rfilter[2].can_mask = 0xF00; /* (CAN_INV_FILTER set in can_id) */rfilter[3].can_id = 0; /* don't care */rfilter[3].can_mask = 0; /* ALL frames will pass this filter */setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
For using the filter function, the include file raw.h
is involved. A change of the filter at run time is possible withadditional calls to mansetsockopt2.
Test programms
- candump
- is a program that receives CAN frames over a RAW socketfrom one or more CAN device(s) and outputs them in a readable form -available with time stamps. The described filter function of RAW sockets (see above)can be used with adjustable command line parameters.The output can be also in ASC format.
If
candump
is called without parameters, a help text is shown:hartko@pplinux1:~/llcf/src/test > ./candump Usage: candump [can-interfaces]Options: -m <mask> (default 0x00000000) -v <value> (default 0x00000000) -i <0|1> (inv_filter) -t <type> (timestamp: Absolute/Delta/Zero) -c (color mode) -s <level> (silent mode - 1: animation 2: nothing) -b <can> (bridge mode - send received frames to <can>) -a (create ASC compatible output) -1 (increment interface numbering in ASC mode) -A (enable ASCII output)When using more than one CAN interface the optionsm/v/i have comma seperated values e.g. '-m 0,7FF,0'
Examples of the use of candump:Simple example to look at two CAN buses. Timestamps start from zero.
hartko@pplinux1:~/llcf/src/test > candump can0 can1 -t z(0.000000) can0 3FC [1] 05 (0.001185) can0 64 [8] 20 14 3F 16 B8 0B 98 3A (0.002396) can0 66 [8] 39 00 A1 45 00 00 00 00 (0.015395) can0 C9 [6] 13 01 00 00 10 27 (0.028665) can1 110 [3] 87 00 00 (0.049990) can0 3FC [1] 05 (0.051176) can0 64 [8] 20 14 3F 16 B8 0B 98 3A (0.052386) can0 66 [8] 39 00 A1 45 00 00 00 00 (0.065397) can0 C9 [6] 13 01 00 00 10 27 (0.099974) can0 3FC [1] 05 (0.101159) can0 64 [8] 20 14 3F 16 B8 0B 98 3A
Open two CAN buses. Timestamps start from zero.Output in ASC format. The channel numbers are increased by 1(
can0
1,can1
2).hartko@pplinux1:~/llcf/src/test > candump can0 can1 -t z -a -1date Tue Oct 18 09:39:57 2005base hex timestamps absoluteno internal events logged 0.0000 1 3FC Rx d 1 05 0.0011 1 64 Rx d 8 20 14 3F 14 B8 0B 98 3A 0.0023 1 66 Rx d 8 49 00 A1 45 00 00 00 00 0.0154 1 C9 Rx d 6 13 01 00 00 10 27 0.0286 2 110 Rx d 3 87 00 00 0.0500 1 3FC Rx d 1 05 0.0512 1 64 Rx d 8 20 14 3F 14 B8 0B 98 3A 0.0524 1 66 Rx d 8 49 00 A1 45 00 00 00 00 0.0654 1 C9 Rx d 6 13 01 00 00 10 27 0.0999 1 3FC Rx d 1 05 0.1011 1 64 Rx d 8 20 14 3F 14 B8 0B 98 3A
Filtering messages on
CAN0
with bit mask 0x7FC andcomparative value 0x66. Timestamp with time difference.hartko@pplinux1:~/llcf/src/test > candump can0 -m 0x7FC -v 0x66 -t d CAN ID filter[0] for can0 set to mask = 000007FC, value = 00000066 (0.000000) can0 64 [8] 1B 14 3F 21 B8 0B 98 3A (0.001202) can0 66 [8] B9 DA A0 45 00 00 00 00 (0.048833) can0 64 [8] 1B 14 3F 21 B8 0B 98 3A (0.001192) can0 66 [8] EB DA A0 45 00 00 00 00 (0.048790) can0 64 [8] 1B 14 3F 21 B8 0B 98 3A
Filtering messages on
CAN0
with bit mask 0x7FC andcomparative value 0x66. Timestamp with time difference. The CAn bus CAN1is read without filtering.hartko@lin1:~/llcf/src/test > candump can0 can1 -m 0x7FC,0 -v 0x66,0 -t d CAN ID filter[0] for can0 set to mask = 000007FC, value = 00000066 (0.000000) can0 64 [8] 20 14 3F 14 B8 0B 98 3A (0.001202) can0 66 [8] 48 00 A1 45 00 00 00 00 (0.048794) can0 64 [8] 20 14 3F 14 B8 0B 98 3A (0.001201) can0 66 [8] 48 00 A1 45 00 00 00 00 (0.026214) can1 110 [3] 87 00 00 (0.003006) can1 41B [4] 1C 12 02 FF (0.019612) can0 64 [8] 20 14 3F 14 B8 0B 98 3A (0.001201) can0 66 [8] 48 00 A1 45 00 00 00 00 (0.048770) can0 64 [8] 20 14 3F 14 B8 0B 98 3A
Inverted filter on
CAN0
with bit mask 0x7FC andcomparative value 0x66. The CAN busCAN1
has no filtering. The timestampis displayed completely, i.e. in seconds since 01/01/1970.Analog to'date +%s'
see date(1).hartko@pplinux1:~/llcf/src/test > candump can0 can1 -m 0x7FC,0 -v 0x66,0 -i 1,0 -t a CAN ID filter[0] for can0 set to mask = 000007FC, value = 00000066 (inv_filter)(1129625880.726372) can0 C9 [6] 13 01 00 00 10 27 (1129625880.739543) can1 110 [3] 87 00 00 (1129625880.760949) can0 3FC [1] 05 (1129625880.776377) can0 C9 [6] 13 01 00 00 10 27 (1129625880.810983) can0 3FC [1] 05 (1129625880.811580) can1 41C [4] 1D 12 02 FF (1129625880.826379) can0 C9 [6] 13 01 00 00 10 27 (1129625880.839544) can1 110 [3] 87 00 00 (1129625880.860955) can0 3FC [1] 05 (1129625880.876380) can0 C9 [6] 13 01 00 00 10 27 (1129625880.910986) can0 3FC [1] 05
- tst-raw
- is a program to test RAW sockets. Uses the read(2) system call.
- tst-raw-filter
- is a programm to test the filter function of RAWsockets. Uses the recvfrom(2) system call.
- tst-raw-sendto
- is a program to send a CAN-Frame on a non-bound interface withthe sendto(2) system call.
- canecho
- is a program that after receiving a CAN frame retransmits it withthe CAN ID increased by 1. It was implemented for the first trials of a real CAN bus interface.Since theLLCF V0.6 has the local echo functionality implemented,
canecho
is suitable onlyto carry out full load test ...
Sockets for Broadcast-Manager
The Broadcast-Manager provides functions to send messages on the CAN bus once orperiodically, as well as notify of changes in received CAN frames,recognizing specific CAN IDs.
The Broadcast-Manager must meet the following requirements:
Transmission side:
- Cyclic transmission of a CAN message with a given interval
- Modification of message content and intervals at runtime (e.g. switching to a new interval with or without immediate restart of the timer)
- Counting intervals and automatically switching to a second interval
- Instant issue of changing messages, without influencing the interval cycle
- One-time transmission of CAN messages
Receiving side:
- Receive filter to detect changes in message contents
- Receive filter without consideration of message content (CAN ID filter)
- Receive filter for multiplex messages (e.g. with packet counters in the message contents)
- Receive filter to detect changes of message lengths
- RTR reply to messages
- time-out monitoring of messages
- reduction in the frequency of update messages (throttle function)
Communication with the Broadcast-Manager
In contrast to the raw socket (chapter 4), the socket ofBroadcast-Manager is not used to send individualCAN frames, instead longer user data structures are transmitted.
Broadcast-Manager is rather a programmable interface that is controlled by special messages from theuser via the socket interface.
To use Broadcast-Manager the include file to be used isbcm.h
.
A socket for Broadcast-Manager is created with:
s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
With a call to connect() on the socket, the CAN interface is assigned.If a process must operate on multiple CAN buses, it must therefore open several sockets.It is also possible that a process opens multiple instances (sockets) of Broadcast-Manager ona single CAN-bus, if that makes sense for the application programmer to structuredifferent data flows. Every single instance ofBroadcast-Manager is able to realize any numberof filter and/or send requests.
addr.can_family = AF_CAN;strcpy(ifr.ifr_name, "can0");ioctl(s, SIOCGIFINDEX, &ifr);addr.can_ifindex = ifr.ifr_ifindex;connect(s, (struct sockaddr *)&addr, sizeof(addr));
All messages from the (user) process to Broadcast-Manager have the same structure. Itconsists of a message header with the command and several values and zero or moreCAN frames, depending on the command used and the action requested:
struct bcm_msg_head { int opcode; /* command */ int flags; /* special flags */ int count; /* run 'count' times ival1 then ival2 */ struct timeval ival1, ival2; /* intervals */ canid_t can_id; /* 32 Bit SFF/EFF. MSB set at EFF */ int nframes; /* number of can_frame's in the next field */ struct can_frame frames[0];};
The value of nframes
indicates how many user data frames follow the messageheader. The user data frames are used to describe the actual content of a CAN message:
struct can_frame { canid_t can_id; /* 32 bit CAN_ID + EFF/RTR flags */ __u8 can_dlc; /* data length code: 0 .. 8 */ __u8 data[8] __attribute__ ((aligned(8)));};
The opcode
defines the kind of message. Messages from the user toBroadcast-Manager controlthe operations of the Broadcast-Manager, replies from the Broadcast-Manager indicate certain changes to the user,timeouts, etc.
The transmit and receive path of the Broadcast-Manager are two independent functional blocks.
For the transmit path the following opcodes exist:
- TX_SETUP
- for setting up and modifying transmission requests
- TX_DELETE
- to delete send requests
- TX_READ
- to read out the current broadcasting commands (for debugging purposes)
- TX_SEND
- for sending a single CAN message
For the receive path the following opcodes exist:
- RX_SETUP
- for setting and modifying receive filters
- RX_DELETE
- for deleting receive filters
- RX_READ
- to read out the current receive filter (for debugging purposes)
The Broadcast-Manager sends response messages in the same form. TheBroadcast-Manager sends these these opcodes:
- TX_STATUS
- in response to TX_READ
- TX_EXPIRED
- is sent when the counter
count
reachesival1
(only if flag TX_COUNTEVT is set, see below) - RX_STATUS
- in response to RX_READ
- RX_TIMEOUT
- sent if the time-controlled reception of a message failed
- RX_CHANGED
- sent if the first or a revised CAN message was received
Each of these opcode
functions uses the can_id
referenced.
In addition, there are optional flags
which can influence Broadcast-Managers behavior:
- SETTIMER :
- set the value of
ival1
,ival2
andcount
- STARTTIMER :
- start the timer with the actual value of
ival1
,ival2
andcount
. Starting the timer leads simultaneously to emit a can_frame. - TX_COUNTEVT :
- create the message TX_EXPIRED when
count
expires - TX_ANNOUNCE :
- A change of data by the process is emitted immediatly.(Requirement of 'Changing Now' - BAES)
- TX_CP_CAN_ID :
- copies the
can_id
from the message header attached to eachofcan_frame
. This is intended only as usage simplification. - TX_RESET_MULTI_IDX :
- forces a reset of the index counter from the updateto be sent by multiplex message even if it would not be necessarybecause of the length. See page[*].
- RX_FILTER_ID :
- there is no filtering of the user data. A match with thereceived message
can_id
automatically leads to a RX_CHANGED. so usecaution in cyclic messages! If RX_FILTER_ID flag is set, the CANframe in RX_SETUP can be ignored (i.e.,nframes = 0
). - RX_RTR_FRAME :
- the filter passed is used as CAN message to be sent when receivingan RTR frame.
- RX_CHECK_DLC :
- A change of the DLC leads to an RX_CHANGED.
- RX_NO_AUTOTIMER :
- If the timer
ival1
in the RX_SETUP has been set equalto zero, on receipt of the CAN message the timer for the timeout monitoring isautomatically started. Setting this flag prevents the automatic start timer. - RX_ANNOUNCE_RESUME :
- refers also to the time-out supervision of themanagement RX_SETUP. By setting this flag, when an RX-outs occours, a RX_CHANGED willbe generated when the (cyclic) receive restarts. This will happen even if the userdata have not changed.
TX_SETUP
With TX_SETUP a specific CAN ID for cyclic send is set or changed.
Typically, it is used with a structure in which the components can_id
,flags
(SETTIMER
, STARTTIMER
), count
=0,ival2
=100ms, nframes
=1are set and the user data in the can_frame
structure are filled in accordingly. Thisvariable is then transmitted with thewrite() system call onthe socket to Broadcast-ManagerExample:
struct { struct bcm_msg_head msg_head; struct can_frame frame[4]; /* just an example */ } msg; msg.msg_head.opcode = TX_SETUP; msg.msg_head.can_id = 0x42; msg.msg_head.flags = SETTIMER|STARTTIMER|TX_CP_CAN_ID; msg.msg_head.nframes = 1; msg.msg_head.count = 0; msg.msg_head.ival1.tv_sec = 0; msg.msg_head.ival1.tv_usec = 0; msg.msg_head.ival2.tv_sec = 0; msg.msg_head.ival2.tv_usec = 100000; msg.frame[0].can_id = 0x42; /* obsolete when using TX_CP_CAN_ID */ msg.frame[0].can_dlc = 3; msg.frame[0].data[0] = 0x123; msg.frame[0].data[1] = 0x312; msg.frame[0].data[2] = 0x231; write(s, &msg, sizeof(msg));
The message length for the command TX_SETUP is, therefore,{[bcm_msg_head] [can_frame]+}i.e. a message header andat least one CAN-Frame.
Timer specifics
The timer can be set to 0 ms (ival1
and ival2
). In this case, the variableshould be transferred with the flag SETTIMERBroadcast-ManagerTo start a cyclic send timerwith the given values, the flagsSETTIMER
and STARTTIMER
in theelement flags
have to be set.To complement the above example, you can work with two intervals for the cyclicaltransmission of the CAN message. Here, the CAN message is sent firstcount
timeswith interval ival1
and then by an explicit deletion with TX_DELETE or bystopping the timer, with the intervalival2
. The interval ival2
may be zero,in which case the transmission after the firstcount
messages stops.If count
is zero, the value of ival1
has no role and does not need tobe specified.
If the flag STARTTIMER
is set, the first CAN message is sent out immediately.
It is important for the user, when switching the Broadcast-Manager from the interval+ival1+ to +ival2+ (the transmission may stop), that the flagTX_COUNTEVT
of Broadcast-Manager can be used. When the valuecount
is decremented down to zero, theflag TX_COUNTEVT
is set, andBroadcast-Manager sends a message with the opcodeTX_EXPIRED to the process. This message contains only a message header(+nframes+ = 0).
Modification of data at runtime
At runtime, the data in the CAN message can be changed. The data aremodified in the variable and transferred with the opcode TX_SETUP to theBroadcast-ManagerThis can generate the following special cases:- The cycle should be restarted: set the flag
STARTTIMER
- The cycle is to be retained, but the changed / appended data will be sentimmediately once: set the flag
TX_ANNOUNCE
- The cycle should be maintained and the changed data is sent instead of theolder one: default behavior
Note: when restarting the cycle, the last timer values set (ival1
,ival2
)are not modified by Broadcast-Manager. But if working with two timers, the value ofcount
is decremented for the period byBroadcast-Manager.
Transmitting different data (multiplexed message datagram)
The Broadcast-Manager can also send multiplex messages. This is needed if, for example,the first byte of user data contains a value used to look up information in the followingseven bytes. Another application is the switching / toggling of data content. Touse this, a structure with more than one user data frame after the header mustbe sent toBroadcast-ManagerAs a consequence not a single CAN-ID is sent to theBroadcast-Manager but a numberof can_frame
. The various user data are sent consecutively in the cycle of transmission.I.e. twocan_frame
are alternately sent in the desired interval. A changein the data at runtime, causes the transmssion of the the firstcan_frame
the updatechanged. If the number of messages did not change, a reset of the index can bedone by setting the flagTX_RESET_MULTI_IDX
.
TX_DELETE
This message will delete the entry for the transmission of the CAN-messagewith the specifiedcan_id
CAN identifier. The message length for thecommand TX_DELETE is{[bcm_msg_head]} (only the header).
TX_READ
With this message, the current state is read for the specified can_id
CAN identifier,i.e. CAN message to be sent, counter, timer values, etc.Broadcast-Manager respondswith a message with the opcode
TX_STATUS that contains the item. Thelength of this answer can be different from the original TX_SETUP request.The message length for the command TX_READ is{[bcm_msg_head]} (only a message header).
TX_SEND
To send a single CAN message, without using the special functionality of Broadcast-Managerthe TX_SEND opcode
is used. In this case one structure is generated in whichthe componentscan_id
, can_dlc
, data[]
are filled with theappropriate values. TheBroadcast-Manager sends the CAN message directly to the socket definedby the CAN bus. The message length for the command TX_SEND is{[bcm_msg_head] [can_frame]}(i.e. a message header and exactlyone CAN-Frame).
Note: of course, single CAN message can be sent with the RAW socket. But you would have toopen a RAW socket for a single CAN message when you have an already openBCM-Socket.That is a disproportionately large programming effort.
RX_SETUP
RX_SETUP is used to create or change a receive job for a specific CAN ID.The Broadcast-Manager is used to filter such CAN messages according to various criteria, andsend a message to the process for changes and/or timeouts.
Similar to the opcode
TX_SETUP (see page [*], a Broadcast-Manager messagestructure has to be created. The message length for the command RX_SETUP is{[bcm_msg_head] [can_frame]+}(i.e. a message header and at least one CAN-Frame).
In contrast to TX_SETUP the components of the structure in the context of thereceiving functionality have some other meanings when they are sent from theprocess at theBroadcast-Manager:
- count
- no function
- ival1
- timeout for CAN message reception
- ival2
- reduction of RX_CHANGED messages
- can_data
- contains a mask to filter user data
Timeout monitoring
If the Broadcast-Manager does not receive a CAN message for a longer period thanival1
, amessage is sent to the process with the opcode
RX_TIMEOUT. This messagecontains only a message header (nframes
= 0). A timeout monitoring is not inthis case started again.
Typically, the timeout monitoring starts with the reception of a CAN message. By settingthe flagSTARTTIMER
in the RX_SETUP the timeout is immediately started. Settingthe flagRX_NO_AUTOTIMER
prevents the automatic start of the surveillance timeoutwhen receiving a CAN message.
Background: The automatic start of the surveillance timeout when receiving a messagemakes each occurring cyclic failure of a CAN message clearly, without the userhaving to do anything.
To recognize a resumption of the cycle under the same user data securely,the flagRX_ANNOUNCE_RESUME
must be set.
Reduction of RX_CHANGED messages
Even when the filtering of user data is active, the user application can be overwhelmedby RX_CHANGED messages when the data change rapidly (e.g. speed).
For this purpose, the timer ival2
can be set. It describes the minimumperiod in which successive RX_CHANGED messages for eachcan_id
may be sentfrom the Broadcast-Manager.
Note: If, during the blocked time, further changed CAN messages are received, the lastvalid one will be transferred after the lockout with a RX_CHANGED. It can happenthat intermittent (e.g. alternating) state transitions are lost.
Note for MUX messages: After the lockout, all occurring RX_CHANGED messages are sentin succession to the process. I.e. a change for each MUX entry is displayed.
Message filtering (user data - simple)
Analogous to the transfer of user data in TX_SETUP (see page [*]),in RX_SETUP a mask can be set to filter the incoming user data. Only the first userdata entry (data[]
) of the structurecan_frame
is evaluated by theBroadcast-Manager for message filtering.
A bit set in the mask in this case means that the corresponding bit in the CAN messagemust be monitored for a change.
In a received CAN message, if one change is detected from the last received message in oneof the bits specified in the mask, the message RX_CHANGED with the full CAN frame receivedwill be sent to the process.The first time a message is received, the received CAN frame is generally sentto the process - only then it can eventually be tested forchanges.Tip: by setting the filter mask to zero, the process will receive a unique example ofan otherwise cyclical message.
Message filtering (user data - multiplex)
If there is a CAN message with a single CAN-ID to be transferred with cyclicallyrepetitive content, it is called a multiplex message. For example in the first byte ofthe payload of the CAN frame a MUX identifier is inserted, which defines the meaning ofthe next bytes. Example: if the first byte (byte 0) has the value0x02
then inthe bytes 1-7 the number of Km is available. If, otherwise, in the first byte (byte 0)the value is0x04
, then in the bytes 1-7 the running hours number isregistered. And so on.Such multiplex messages can managed by Broadcast-Manager by sending more than a user data framecan_frame
for a CAN-ID (see page[*]).
In order to filter multiplex messages, there must be at least two (nframes
2)can_frame
sent to theBroadcast-Manager, where the first can_frame
contains the MUXmask and the secondcan_frame
the user data mask, as described above.The points that define the MUX-mask are in the user data masks, they aredistinguished by the MUX Identifier in the user data.
For the example above it would mean:
The first byte in the first can_frame
(the MUX-mask) would be 0xFF
- thefollowing 7 bytes would be 0x00
- this is the MUX-mask defined. The following twocan_frame
each contain at least in the first byte the0x02
or 0x04
values so that the identifier of the Multiplex messages are defined. In addition,(reasonably) in the user data other bits are set, which for example correspondto a change in operating hours.
A change in a multiplex message with a particular MUX identifier results in amessage RX_CHANGED to the process with the received CAN Frame. I.e. the processmust assess the basis of the MUX-Identifiers from theBroadcast-Manager message received.
In the example shown (Figure 4), the MUX-mask in byte 0 on0x5F
is set. When receiving RX-frame no message is sent to the user(MUX-identifier is not known). With RX-frame 2 there is a message (MUX-knownidentifier and relevant data have changed at the first receive operation). Byreceiving the RX-Frame 3 (changes in the yellow-marked bits) no message is sent tothe user, because no changes are in any relevant data on the registered identifier MUX.
Message filtering (length of user data - DLC)
When requested, Broadcast-Manager can additionally monitor a change in the CAN messagespecified user data. In addition, the received Data Length Code (DLC) can becompared with the reference message. If a difference is detected an RX_CHANGED messageis sent to the process.To enable this functionality the flagRX_CHECK_DLC
must be set in flags
.
LLCF status in /proc Filesystem
The Low Level CAN Framework supports the /proc file system and provides statistics andinformation about internal structures and states in human-readable form.The information can be queried with:
cat /proc/net/can/stats
Next the other files are explained.
Version information: /proc/net/can/version
The LLCFversion information can be read by opening the file/proc/net/can/version
.These are the first 6 characters from LLCF_VERSION_CODE, copied into a buffer withllcf_version_code = strtoul(mybuffer, (char **)NULL, 16);
, and built with the following rule:
LLCF_VERSION_CODE = (((MAJORVERSION) << 16) + ((MINORVERSION) << 8) + (PATCHLEVEL))
hartko@pplinux1:~> cat /proc/net/can/version 010000 [ Volkswagen AG - Low Level CAN Framework (LLCF) v1.0.0-rc1 ]
Statistics: /proc/net/can/stats
With the statistics offered you can get information such as the currentvolume of data and the proportion of the application's matched CAN framesin the ratio of all the CAN-Bus received CAN frames.
The information is updated by the LLCF once a second.
hartko@pplinux1:~> cat /proc/net/can/stats 811 transmitted frames (TXF) 319427 received frames (RXF) 69504 matched frames (RXMF) 21 % total match ratio (RXMR) 0 frames/s total tx rate (TXR) 0 frames/s total rx rate (RXR) 100 % current match ratio (CRXMR) 2 frames/s current tx rate (CTXR) 166 frames/s current rx rate (CRXR) 100 % max match ratio (MRXMR) 2 frames/s max tx rate (MTXR) 167 frames/s max rx rate (MRXR) 6 current receive list entries (CRCV) 6 maximum receive list entries (MRCV)
Resetting statistics: /proc/net/can/reset_stats
Resetting the statistical information can be internal, for the overflow of counters,or user-initiated. After the reset of the statistical information, an additional line(STR) is output. This example shows the impact in a running system, compared to theone above.
hartko@pplinux1:~> cat /proc/net/can/reset_stats LLCF statistic reset #1 done.hartko@pplinux1:~> cat /proc/net/can/stats 31 transmitted frames (TXF) 2585 received frames (RXF) 2585 matched frames (RXMF) 100 % total match ratio (RXMR) 1 frames/s total tx rate (TXR) 165 frames/s total rx rate (RXR) 100 % current match ratio (CRXMR) 2 frames/s current tx rate (CTXR) 165 frames/s current rx rate (CRXR) 100 % max match ratio (MRXMR) 2 frames/s max tx rate (MTXR) 167 frames/s max rx rate (MRXR) 6 current receive list entries (CRCV) 6 maximum receive list entries (MRCV) 1 statistic resets (STR)
Internal receive lists on the RX dispatcher
LLCFmodules use the LLCFRX dispatcher to receiveeach CAN-IDs (or a range of CAN-IDs) of certain fromCAN network interfaces. This leads to the registrationof an entry in a corresponding receiver list, whereany registered CAN ID is a function with a parameter(E.g. a module specific reference as 'user data' or 'sk').It is called when the CAN Frame with the corresponding CAN-ID is received.Together with the debug functionality it can bethe basis for understanding the operation of the LLCF.
For fast processing of received CAN frames, the RX-dispatchermaintains various receive lists (for each CAN Network Interface):
- rcvlist_all
- This list receives all CAN frames, typically this is for RAW socketswithout filters (see chapter4).
- rcvlist_fil
- This list receives frames that match a simple bitmask-defined range (e.g. 0x200 - 0x2FF).
- rcvlist_inv
- This list receives frames that do not match a simple bitmask-defined range (the inverse of rcvlist_fil).
- rcvlist_eff
- This list receives frames that have an Extended Frame Format (29 bit identifier)
- rcvlist_sff
- This list receives frames that have a Standard Frame Format (11 bit identifier)
By dividing the receiving lists, the effort to findand comparing the received CAN frames with the registered receive filters is minimized.
Thus, for example the list 'rcvlist_sff' is an array with 2048 entries(11 bits CAN-ID) with a singly linked list for each CAN-IDsreceived. The content filter can be easily applied and pass on a matching message.
Currently the functionality of the extended CAN frames is not used in currentprojects, because the registration of individual EFF frames in a singly-linked listcan be slow. For intensive use, 'rcvlist_eff' should be implemented as an hash table(analogous to 'rcvlist_sff'), to ensure efficient processing.
If you want to watch all the receive lists at once, you can type:
hartko@pplinux1:~> cat /proc/net/can/rcvlist_*receive list 'rx_all': device can_id can_mask function userdata matches ident can1 000 00000000 f8c995ac f0e59280 42726 raw device can_id can_mask function userdata matches ident can0 000 00000000 f8c995ac f0e59800 55240 rawreceive list 'rx_eff': (can1: no entry) (can0: no entry)receive list 'rx_fil': device can_id can_mask function userdata matches ident can1 200 00000700 f8c995ac f0e5b380 0 raw (can0: no entry)receive list 'rx_inv': (can1: no entry) (can0: no entry)receive list 'rx_sff': (can1: no entry) device can_id can_mask function userdata matches ident can0 123 000007ff f8c86bec e2e14380 29 bcm can0 456 000007ff f8c86bec ea954880 0 bcm can0 789 000007ff f8c86bec e30e6200 130 bcm can0 3FF 000007ff f8c86bec deaf2580 14 bcm can0 740 000007ff f8c93680 e48322c4 178 tp20
You can also do this:
hartko@pplinux1:~> cat /proc/net/can/rcvlist_sffreceive list 'rx_sff': (can1: no entry) device can_id can_mask function userdata matches ident can0 123 000007ff f8c86bec e2e14380 29 bcm can0 456 000007ff f8c86bec ea954880 0 bcm can0 789 000007ff f8c86bec e30e6200 130 bcm can0 3FF 000007ff f8c86bec deaf2580 14 bcm can0 740 000007ff f8c93680 e48322c4 178 tp20
CAN network devices in the directory /proc/net/drivers
In this directory there are CAN network drivers with theirProc file system entries. Currently this is only for theSJA1000 driver supplied insrc/drivers/sja1000
,whose details are briefly described.
Driver status: /proc/net/drivers/sja1000-xxx
Here, the state of the CAN controllers and their associatedCAN bus is shown (see the documentation for the PhilipsSJA1000).
hartko@pplinux1:~> cat /proc/net/drivers/sja1000-gw2CAN bus device statistics: errwarn overrun wakeup buserr errpass arbitr restarts clock baudcan0: 0 0 0 0 0 0 0 20000000 500can0: bus status: OK, RXERR: 0, TXERR: 0can1: 0 0 0 0 0 0 0 20000000 100can1: bus status: OK, RXERR: 0, TXERR: 0can2: 0 0 0 0 0 0 0 20000000 100can2: bus status: OK, RXERR: 0, TXERR: 0can3: 0 0 0 0 0 0 0 20000000 500can3: bus status: OK, RXERR: 0, TXERR: 0
Registers: /proc/net/drivers/sja1000-xxx_regs
Here are how the 32 registers of the SJA1000 CAN controller appear.(See the documentation for the Philips SJA1000).
hartko@pplinux1:~> cat /proc/net/drivers/sja1000-gw2_regs SJA1000 registers:can0 SJA1000 registers:00: 02 00 0c 00 05 00 40 4d 1a 1a 00 00 00 60 00 0010: 65 ef d3 5f a2 08 01 05 fa ff 0e 7f 0c 00 00 cfcan1 SJA1000 registers:00: 02 00 0c 00 05 00 43 ff 1a 1a 00 00 00 60 00 0010: 61 ff de 3d 80 00 10 45 d7 ef fb 4a 06 00 00 cfcan2 SJA1000 registers:00: 02 00 0c 00 05 00 43 ff 1a 1a 00 00 00 60 00 0010: 61 fb ee 87 a0 4a 80 10 76 ff da bd 00 00 00 cfcan3 SJA1000 registers:00: 02 00 0c 00 05 00 40 4d 1a 1a 00 00 00 60 00 0010: 61 ef 7f ff 21 1c 42 08 32 df 57 6f a1 00 00 cf
Driver reset: /proc/net/drivers/sja1000-xxx_reset
Reading this entry performs a reset of the SJA1000 CAN controller.As can be seen in the example, the number of 'restarts' is increased by 1.
hartko@pplinux1:~> cat /proc/net/drivers/sja1000-gw2_reset resetting can0 can1 can2 can3 donehartko@pplinux1:~> cat /proc/net/drivers/sja1000-gw2CAN bus device statistics: errwarn overrun wakeup buserr errpass arbitr restarts clock baudcan0: 0 0 0 0 0 0 1 20000000 500can0: bus status: OK, RXERR: 0, TXERR: 0can1: 0 0 0 0 0 0 1 20000000 100can1: bus status: OK, RXERR: 0, TXERR: 0can2: 0 0 0 0 0 0 1 20000000 100can2: bus status: OK, RXERR: 0, TXERR: 0can3: 0 0 0 0 0 0 1 20000000 500can3: bus status: OK, RXERR: 0, TXERR: 0
Test programs
- tst-proc
- Opens up to 800 raw sockets to provoke an overflow of the output of
/proc/net/can/rcvlist_all
.
Contact
This document should be read together with the test programs insrc/test
as a comprehensive introduction to theLow Level CAN Framework.
For questions, bug reports and suggestions the authors arealways open and grateful. Therefore, the Group ResearchVolkswagen AG set up a special email address where thethe authors can be reached:contact email: socketcan-users@lists.berlios.dePostal address:
Volkswagen AG
Oliver Hartkopp
Brieffach 1776
D-38426 WolfsburgOliver Hartkopp oliver.hartkopp@volkswagen.de
Dr. Urs Thürmann urs.thuermann@volkswagen.de
English translation from German: Daniele Venzano venza@brownhat.org
- Low Level CAN Framework Application Programmers Interface
- Low-level Native Plugin Interface
- Low-level I/O 和 File System Interface
- Low-level I/O 和 File System Interface
- 史陶比尔机器人的 LLI (Low Level Interface)
- 17.2. socket — Low-level networking interface Python
- Unity低级本地插件接口--Low-level Native Plugin Interface
- Low Level MIDI API
- Low-level text rendering
- RPi Low-level peripherals
- python low level thread
- Low-level GPU programming
- Interface-Oriented Design (Pragmatic Programmers)
- User Interface Design for Programmers
- Low Power Design Framework
- Why Can't Programmers.. Program?
- Low Level Digital Audio API
- Linux kernel Low Level debug
- 数据库内置函数——关于字符串的操作
- Java(28):基础语法(2):修饰符的理解和使用
- MYSQL目录文件迁移
- Quartz-DateBuilder解读
- c++ primer 笔记,第十一章(关联容器)
- Low Level CAN Framework Application Programmers Interface
- JUnit4的简单使用
- VS2017初用体验
- vim 寄存器复制
- QScrollBar样式表总结
- 分布式锁-基于数据库实现
- No module named win32api问题解决
- Java(29):基础:JVM的理解和使用(收集自网上资源)
- 企业员工考勤管理子系统