Can4Linux/Pcd-E12/CanOpen integration

Nathan Z. Gustavson
ngustavson@emacinc.com

1/06/03
Emac.inc
www.emacinc.com



GOAL

An integration of the CanFestival CanOpen layer and 
the Can4Linux hardware layer. The CanOpen layer will provide an 
Asychronous notification scheme above and beyond that provided by
CanFestival. As of 1/06/03 The CanFestival layer has also been fully
integrated over the pcde12 hardware driver.  



IMPLEMENTATION-CAN4OPEN

By changing the API of the CanOpen layer to use read and write calls rather 
than the Ioctl call of the original CanFestival driver, CanOpen applications 
can be developed that utilize the CanOpenMatic object file.

The modified API is built into wrapper functions in Can4Open. 
These wrappers do stadard linux read/write/open/close operations and 
perform the translation between the message structures of CanFestival 
and Can4Linux.

Can4Open consists of the following functions:

f_can_receive
	This function is the hardware call made by CanOpenMatic to read in a 
message from the hardware. It's prototype hasn't changed from the original 
CanFestival specification. f_can_receive calls read to get 1 message from a 
specified can device. It then calls msgtoMessage to translate the message into 
a form CanOpenMatic will understand. 
	f_can_receive provides a hook to a logging function, which can be used to keep track of transmitted messages, as is done in Can4Opener.The Can4Open 
module declares a global function pointer, logfunc rxloggingfunc, which can be 
hooked by declaring it extern and pointing it to an appropriate function.
ex.
extern logfunc rxloggingfunc;
rxloggingfunc = can_log;
The function returns 0 on success.

Remember that this data is received asychronously from the data being sent.
Therefore if the same logging function is used for both f_can_send and f_can_recieve, some locking mechanism will need to be implemented.
See Can4Opener for an example of this.

f_can_send
	This is the hardware call made by CanOpenMatic to write a message to 
the hardware.It's prototype hasn't changed from the original CanFestival
specification.f_can_send calls Messagetomsg to translate the CanOpenMatic 
structure, and then calls write to send 1 message to a specified can device. 
	f_can_send provides a hook to a logging function, which can be used 
to keep track of transmitted messages, as is done in Can4Opener.The Can4Open 
module declares a global function pointer, logfunc loggingfunc, which can be 
hooked by declaring it extern and pointing it to an appropriate function.
ex.
extern logfunc txloggingfunc;
txloggingfunc = can_log;

The function returns 0 on success.


f_can_callback
	This function provides an asynchronous reception of data.
It's arguements are a pointer to a function of type void (function)(Message *)
and a pointer to a can Message.
	When a can message is received the function that has been passed to 
f_can_callback will be called, with the received Message as it's arguement.
the AsyncRx provides an example of this.

	The callback is actually a function pointer called by f_can_receive
	Since no data enters the system without f_can_receive the callback is
	guarenteed.  



This function returns a positive number(the child pid) on success.








f_can_open
	Opens a can device and installs a callback message handler.
	This handler is a asychronous signal handler, set up by a fcntl system 
	call to the hardware layer.  When data is received it is passed to the
	message handler which will respond accordingly for SDO transfers 
	and such.

f_can_close
	Closes a can device.

Messagetomsg
	Translates a CanOpenMatic message into a can4linux message.


msgtoMessage
	Translates a can4linux message into a CanOpenMatic message.



MessPickup
	A synchronous cleaning function for picking up any lost messages.
	Messages could become lost if they are transmitted at to high a rate.
	(greater than 1ms between messages) or if the asyncronyous handler
	is disabled.This is a hack and shouldn't have to be used
	in a commercial system.
	

	


	Can4Open also declares a global variable "wait" which can be used to 
make f_can_send and f_can_receive blocking by setting it to 1.
	This variable is legacy is is redundant in the new asychronous method.




DRIVER AND LIBRARY MODIFICATION


CAN4LINUX

The can4linux driver here has an added target, EMACCAN.
This provides the appropriate flags to build a PCM-3680 driver.
Also some new flags have been added to make the interrupt handler 
work correctly; 
IRQMSKR - masks off the top bits of the IRQ register, which are undefined in 
the SJA1000. 
TX_IRQ - turns on the tx irq for non-pelican ISA boards.

CANREAL - this adds RTAI realtime extensions to the can4linux layer.
currently it is only supported on emacs 3680 and 3681 boards.
Although the 3680 is currently supported, future revs may support only the
3681. Customers are encouraged to migrate to this next generation board if
possible.

PCD-E12
The pcd-e12 driver now supports asychronous notification for it's can
hardware. Therefore is is now fully compatible with the CanOpen layers.



CANOPENMATIC

CanOpenMatic.o provides CanOpen function calls.
It was originally developed by Edouard Tisserant 
(edouard.tisserant@esstin.u-nancy.fr) as part of the CanFestival package.
CanFestival provided a physical layer, but it was inflexable and irregular. 
Not lending itself well to new hardware. Therefore the Open Source CanOpen 
software was largely unusable. Here we have ported the CanOpenMatic layer
(CanOpen) to the robust and living Can4Linux project.
 


MODIFICATIONS 
from the original CanFestival library

CanOpenMatic.h, has some added function prototypes. 

CanOpenMatic.c, Send_SDO now always sends a message length of 8, Since SDO's by
definition always have a length of 8.



TESTED FUNCTIONALITY:
NMTs,SDOs, and DictionaryEntry calls have been tested in asychronous 
enviornments. Full integration testing of the PDO's for this project has not 
yet been done, however the layer it's built on (CanOpenMatic) has had it's 
PDO calls tested, so everything should be in place. Please report any bugs
directly to ngustavson@emacinc.com.




EXAMPLES

CAN4OPENER

Can4Opener is a modified CanOpener program that uses the new API.
The origianl CanOpener program contained calls to the hardware that the 
CanOpen layer hooked.

This ran against the idea of layers, so the hardware calls have been moved 
into a seperate module, Can4Open, which is linked in by the Makefile.

CAN4OPENER has recently had it's transmit callback removed, so it no longer
displays transmit information. This is because it was originally written for
a synchronous CanOpen layer and it's logging callbacks are not threadsafe.



ODEDIT

ODedit is a command prompt program that reads and writes to the 
Object Dictionary of a CanOpen device. It was designed for scripts, allowing
the user to jump completely over can and write his application with direct 
access to the OD.

both of these programs can be found in the CanOpener directory.


ASYNCRX

AsyncRx is a command prompt based can receiving program.
It is hardcoded to work on /dev/can0 and provides an example of asychronous 
data reception using the f_can_callback function.


ASYNCRT

AsyncRT is a test program which reads an object dictionary entry and
prints the latencies between transfers. This only works for RTAI distro's 
with RTAI enabled hardware layers.


TRANSMITB
a low level trasmit program that sends 2 messages by making calls directly
to the hardware layer.


ASYNC2

A test program that sets up an asychronous handler independent of the
Can4Open layer. This is generally not recommended as it would interfere with
the Can4Open functionality.


USING THE CANOPEN LIBRARIES WITH CAN4LINUX

To use CanOpen, first load the driver, Can.o. This provides the hardware layer of the system.  

The driver can be loaded directly 
ie insmod ./Can.o

or by putting it into the kernels path.

cp Can.o /lib/modules/(kernel name)/kernel/drivers/char/
insmod Can.o

uname -a will pass the "kernel name" to the command prompt as the third 
argument

Please note that this is a kernel driver. And as such MUST! be compiled against
the kernel source that it is to be used on.

RE-COMPILING driver

The pre-compiled drivers are built against 2.4.18-rthal5.
This is an RTAI patched 2.4.18 kernel.
If this isn't the kernel your using(and it probably isn't) you will need to 
recompile the driver. 
This can be done using the top level Makefile.
"make" will compile the driver against whatever is in /usr/src/linux/
some warnings will be generated.
This is normal, they are there for backwards compatiblitly with older kernels.
When the make is complete a new Can.o should be generated in the top directory.



CONFIGURING THE DRIVER

CAN4LINUX
Next, the driver has to be configured. This can be done easily with the 
cansetup utility. To set the driver up to use a 3680 Advantech can board,
use the emac.conf configuration file.
ex.
utils/cansetup etc/emac.conf

PCD-E12
No configuration nescessary


Now the driver is ready to run applications.
Can4Opener will give you a list of commands.
ex.
Can4Opener

CanOpen libraries are statically linked into applications by including 
CanOpenMatic.o into the build. For CanOpenMatic to access the hardware, 
functions have to be provided to access the Can.o driver. These are located in
Can4Open and can be linked in by including Can4Open.o.

See the Makefile in CanOpener for an example.









