Feature

Making the CAN bus a "can-do" bus

Connect a PC to your proprietary instrument using the CAN bus.

By Will Warner, Peach Mountain Computing -- EDN, 8/21/2003

Sidebars:
CAN-bus basics

When your instrument rests under five feet of snow, on the summit of Greenland's ice cap, at 70 degrees latitude and an altitude of 4000 meters, you'd rather not have to dig it up to get your data out. The Space Physics Research Laboratory at the University of Michigan (www.sprl.umich.edu) recently placed a magnetometer in exactly this situation, so designers of the instrument provided a way to upload its data to a laptop PC.

Earlier versions of the instrument used a serial port to transfer the data. This technique became impractical when designers modified the instrument to log magnetic readings at 10 times the former frequency. Even after compressing the readings, the instrument now produces as much as 400 Mbytes of data in one year of unattended operation. The challenge is uploading that much data in a reasonable amount of time—meaning less than the maximum on-battery time of a laptop PC in cold weather.

Designers briefly considered a 16-bit wide parallel channel for the upload. This approach, however, implied a cable of at least 19 wires (16 for data words, two for handshaking, and one common), with line drivers and perhaps optical isolation for each wire.

Instead, engineers elected to use the CAN (controller-area-network) bus. The CAN bus operates using only two wires and can connect two devices as far as 40m apart while transferring data at 1 Mbps (see sidebar "CAN-bus basics").

The data upload from the magnetometer to the PC proceeds using a custom protocol. The compete magnetometer system includes the instrument buried in the snow and a laptop at the site (Figure 1). The laptop runs a console program that serves as a GUI for the instrument. The console program drives the upload and sends CAN messages to the instrument. It also processes the CAN messages that come from the instrument in response.

The messages to the instrument are commands. The protocol could differentiate commands using bits in the ID field, but instead it uses the first of the message payload bytes to contain a command code. The arbitrary command codes are:

  • 1 SEND_DATA_SIZE, which sends back a message communicating the current number of data bytes;
  • 2 SEND_FREE_SPACE, which sends back a message communicating the amount of unused data storage;
  • 4 ERASE_STORAGE, which erases storage and responds; and
  • 8 SEND DATA, which sends a specified number of bytes beginning at a specified offset.

The first three command messages are complete in the message ID and one byte (containing the command code) of payload. The SEND_DATA command requires seven payload bytes. Table 1 depicts its form.

The instrument sends a CAN message in response to every command from the PC. Each response message includes, in the first of its payload bytes, the command code from the command message that is eliciting the response. The response to the ERASE_STORAGE is complete in the message ID and 1 byte (containing the command code) of payload.

Table 2 shows the form of the response to the SEND_DATA_SIZE command, which requires five payload bytes. Table 3 shows the form of the response to the SEND_FREE_SPACE command, which requires five payload bytes. Table 4 shows the response to the SEND_DATA command requires, which requires five payload bytes.

The response to a SEND_DATA command is typically many messages, each containing 8 data bytes in the message payload. To determine the number of messages, you divide the number of requested data bytes by eight, then round up. The first message includes the first 8 data bytes beginning at the offset that the command specifies. The next message includes the next 8 data bytes, and so on. The console program generally asks for 8 kbytes at a time, resulting in 1024 messages from the instrument.

If the number of requested data bytes is not a multiple of eight, the protocol pads the last response message out to 8 bytes. This step is necessary, because the console program in the PC doesn't know that a response message is a response to a SEND_DATA command unless the response is 8 bytes long. Whenever a response contains fewer than 8 bytes, the console program can check the first payload byte to determine what kind of response message it is. But in the case of a SEND_DATA response, the first byte will be random data.

The aforementioned use of ID bits and payload bytes is completely up to the designer. In retrospect, it would probably have been better to use ID bits to identify command and response messages.

To connect a laptop PC to a CAN bus, you need a CAN-adapter PC card (formerly known as a PCMCIA card). Designers of the magnetometer system chose the CANcardXL from Vector CANTech Inc (www.vector-cantech.com).

The CANcardXL incorporates two CAN controller chips and hence provides two independent CAN channels. Although the magnetometer console program uses only one channel, two-channel cards allow a PC to be an actor on two CAN buses, or to bridge two CAN buses together by recreating the messages from each bus on the other.

Figure 2 is a block diagram of the software in the magnetometer console program. Its scope extends beyond the focus of this article, but the diagram gives you an understanding of the extent of the code involved. The console program reaches the CAN bus through a DLL. An independent thread in the DLL allocates, initializes, and employs an instance of a CANlow object as an API to the CAN bus through the CANcardXL card. Messages, in and out, pass through queues, which the independent thread and the rest of the DLL share.

Listing 1 presents CANlow, the C++ object that serves as an API to the CAN bus through the CANcardXL adapter card. (The zip file containing Listing 1 also contains additional listings that include the header file for the CANlow object and code for several utility objects used by CANlow.) An independent thread in the DLL of Figure 2 allocates, initializes, and employs an instance of CANlow. To join the CAN bus, you initialize the CANlow instance as in Listing 2.

The independent thread should run periodically. Each time it runs, it should dequeue all messages queued for sending and transmit each by invoking CANlow.SendMsg(). The thread should then invoke CANlow.RecvMsgs() to take in and queue for readout all messages that the CAN driver receives. The independent thread for sending and receiving CAN messages might include a loop such as the one in Listing 3.

In general, you can't depend on your thread running more often than every 20 msec. It's best, therefore, to design a protocol that results in a known maximum number of messages elicited by a command message from the PC. That way, you know how big to make your receive queue, and it doesn't matter if your thread is sometimes delayed in reading messages that the driver buffers. One of the things you tell the CANcardXL driver is how big to make its event queue, up to a maximum of 32 kbytes. A 32-kbyte buffer on a bus that is not generating many error events will hold at least 1400 messages.

The ID part of a CAN message comprises either the standard 11 bits or the extended 29 bits. The program always records ID fields as long integers, even though those integers comprise 32 bits. The long integer right-justifies the ID bits. The CANcardXL sets the most significant bit of the 32-bit ID field when the message ID is extended. You do the same when forming a message to send with an extended ID: Set the most significant bit of acceptance-filter masks and codes to indicate that they apply to extended-message IDs.


Author Information
Will Warner is a principal in the consulting firm Peach Mountain Computing in Ann Arbor, MI, a contract systems-design and -development company (www.peachmountaincomputing.com). He has a BS in applied mathematics from Michigan State University and 25 years of experience writing embedded and other real-time software for controls and instruments. Recently, he coded drivers and GUIs for a PC-based system to verify the operation of a mass-spectrometer whose twin is currently on its way to Saturn in the Cassini spacecraft. On the magnetometer project, he worked with engineers Ken Arnett, Steve Musko, and Ryan Miller of the Space Physics Research Laboratory at the University of Michigan, under the direction of Robert Clauer, with support from National Science Foundation Grant OPP-0220735. You can reach Warner at wwarner@peachmountaincomputing.com.

 

CAN-bus basics

CAN has been around for a few years. You'll find it in factories, inside cars, and embedded in medical instruments. It is a popular backbone for any kind of "fly-by-wire" system. Like any ring network (Ethernet, Arcnet, and others), the CAN bus connects two or more devices, not with dedicated wires, but logically, using messages carried by the pair of wires that chain together all the devices, or nodes, on the bus.

The basic unit of traffic on a CAN bus is a message. A CAN message comprises an 11- bit (standard) or 29-bit (extended) ID field and as much as 8 bytes of payload. A CAN-bus controller chip in each node handles the low-level work—arbitration, error detection, and other tasks—that accomplishes the error-free transfer of messages. This setup frees the system designer to implement a high-level protocol using the ID and payload bytes of CAN messages.

Some standard protocols of communication over the CAN bus achieve a classic peer-to-peer connection between two nodes, whereby the contents of a range of memory in one node appear in the corresponding range of memory of another node. But a designer has complete freedom to define a high-level protocol by determining the content and meaning of the messages appearing on the bus. The only requirement is that all nodes be on the same page.

The definition of a protocol begins by giving meaning to the bits of the message ID field. In systems of more than two nodes, some bits in the ID field generally identify the node that is the intended recipient of the message. For example, the designer might use the lowest 4 bits of the ID field to indicate the target node. Typically, other bits in the ID field will name the node that sent the message. Commonly, DIP-switch settings tell a node its own node number. Another bit could, when set, mark a message as a broadcast message, meaning that all nodes should take a look at it.

Nodes use acceptance filters to decide which messages they will look at. An acceptance filter is a pair of numbers: an acceptance mask and an acceptance code.

The acceptance mask includes a 1 in every bit position of the ID field that is relevant. The acceptance code includes a 1 in every bit position of the ID field that should be 1 and a 0 in every bit position of the ID field that should be 0. Software writes one or more acceptance filters into the CAN-bus controller chip and then does not hear from the chip about messages that don't pass the filter. A message passes a filter when:

((ID-field XOR acceptance-code) AND acceptance-mask)=0.

For a node to see messages sent to it or broadcast, it uses two filters: one that passes messages containing its node number in the ID field, and another that passes messages with the broadcast bit set.

 



ADVERTISEMENT

ADVERTISEMENT

Feedback Loop


Post a CommentPost a Comment

There are no comments posted for this article.

Related Content

 

By This Author

There are no additional articles written by this author.


ADVERTISEMENT

Knowledge Center



Technology Quick Links

EDN Marketplace


©1997-2008 Reed Business Information, a division of Reed Elsevier Inc. All rights reserved.
Use of this Web site is subject to its Terms of Use | Privacy Policy

Please visit these other Reed Business sites

ADVERTISEMENT
You will be redirected to your destination in few seconds.