Included interfacing code for LinCAN driver.
The driver is selected at configure time by
./configure --can=lincan
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_lincan/Makefile.in Tue May 30 23:13:59 2006 +0200
@@ -0,0 +1,58 @@
+#! gmake
+
+#
+# Copyright (C) 2006 Laurent Bessard
+#
+# This file is part of canfestival, a library implementing the canopen
+# stack
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+CC = SUB_CC
+OPT_CFLAGS = -O2
+CFLAGS = SUB_OPT_CFLAGS
+PROG_CFLAGS = SUB_PROG_CFLAGS
+PREFIX = SUB_PREFIX
+TARGET = SUB_TARGET
+CAN_DRIVER = SUB_CAN_DRIVER
+TIMERS_DRIVER = SUB_TIMERS_DRIVER
+
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER)
+
+OBJS = $(CAN_DRIVER).o
+
+SRC_HFILES = ../../include/$(CAN_DRIVER)/cancfg.h
+
+TARGET_HFILES = $(PREFIX)/include/canfestival/cancfg.h
+
+all: driver
+
+driver: $(OBJS)
+
+%o: %c
+ $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
+
+install:
+ mkdir -p $(PREFIX)/include/canfestival
+ cp $(SRC_HFILES) $(PREFIX)/include/canfestival
+
+uninstall:
+ rm -f $(TARGET_HFILES)
+
+clean:
+ -\rm $(OBJS)
+
+mrproper: clean
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_lincan/can_lincan.c Tue May 30 23:13:59 2006 +0200
@@ -0,0 +1,176 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+
+See COPYING file for copyrights details.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stddef.h> /* for NULL */
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "canmsg.h"
+#include "lincan.h"
+
+struct CANPort;
+#define CAN_HANDLE struct CANPort *
+
+#include <applicfg.h>
+
+#include "timer.h"
+#include "can_driver.h"
+#include "timers_driver.h"
+
+typedef struct CANPort {
+ char used;
+ HANDLE fd;
+ TASK_HANDLE receiveTask;
+ CO_Data* d;
+} CANPort;
+
+/*********functions which permit to communicate with the board****************/
+UNS8 canReceive(CAN_HANDLE fd0, Message *m)
+{
+ int res;
+ struct canmsg_t canmsg;
+
+ canmsg.flags = 0; /* Ensure standard receive, not required for LinCAN>=0.3.1 */
+
+ do{
+ res = read(fd0->fd,&canmsg,sizeof(canmsg_t));
+ if((res<0)&&(errno == -EAGAIN)) res = 0;
+ }while(res==0);
+
+ if(res != sizeof(canmsg_t)) // No new message
+ return 1;
+
+ if(canmsg.flags&MSG_EXT){
+ /* There is no mark for extended messages in CanFestival */;
+ }
+
+ m->cob_id.w = canmsg.id;
+ m->len = canmsg.length;
+ if(canmsg.flags&MSG_RTR){
+ m->rtr = 1;
+ }else{
+ m->rtr = 0;
+ memcpy(m->data,canmsg.data,8);
+ }
+
+ return 0;
+}
+
+void canReceiveLoop(CAN_HANDLE fd0)
+{
+ CO_Data* d = fd0->d;
+ Message m;
+ while (fd0->used) {
+ if(!canReceive(fd0, &m))
+ {
+ EnterMutex();
+ canDispatch(d, &m);
+ LeaveMutex();
+ }else{
+ printf("canReceive returned error\n");
+ break;
+ }
+ }
+}
+
+/***************************************************************************/
+UNS8 canSend(CAN_HANDLE fd0, Message *m)
+{
+ int res;
+ struct canmsg_t canmsg;
+
+
+ canmsg.flags = 0;
+ canmsg.id = m->cob_id.w;
+ canmsg.length = m->len;
+ if(m->rtr){
+ canmsg.flags |= MSG_RTR;
+ }else{
+ memcpy(canmsg.data,m->data,8);
+ }
+
+ if(canmsg.id >= 0x800){
+ canmsg.flags |= MSG_EXT;
+ }
+
+ res = write(fd0->fd,&canmsg,sizeof(canmsg_t));
+ if(res!=sizeof(canmsg_t))
+ return 1;
+
+ return 0;
+}
+
+/***************************************************************************/
+static const char lnx_can_dev_prefix[] = "/dev/can";
+
+CAN_HANDLE canOpen(s_BOARD *board)
+{
+ int name_len = strlen(board->busname);
+ int prefix_len = strlen(lnx_can_dev_prefix);
+ char dev_name[prefix_len+name_len+1];
+ int o_flags = 0;
+ CAN_HANDLE fd0;
+
+ fd0=malloc(sizeof(*fd0));
+ if(fd0==NULL)
+ return NULL;
+
+ /*o_flags = O_NONBLOCK;*/
+
+ memcpy(dev_name,lnx_can_dev_prefix,prefix_len);
+ memcpy(dev_name+prefix_len,board->busname,name_len);
+ dev_name[prefix_len+name_len] = 0;
+
+ fd0->fd = open(dev_name, O_RDWR|o_flags);
+ if(fd0->fd < 0){
+ fprintf(stderr,"!!! Board %s is unknown. See can_lincan.c\n", board->busname);
+ goto error_ret;
+ }
+
+ fd0->d = board->d;
+ fd0->used = 1;
+ CreateReceiveTask(fd0, &fd0->receiveTask);
+ return fd0;
+
+ error_ret:
+ free(fd0);
+ return NULL;
+}
+
+/***************************************************************************/
+int canClose(CAN_HANDLE fd0)
+{
+ if(!fd0)
+ return 0;
+ fd0->used = 0;
+ WaitReceiveTaskEnd(&fd0->receiveTask);
+ close(fd0->fd);
+ free(fd0);
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/can_lincan/cancfg.h Tue May 30 23:13:59 2006 +0200
@@ -0,0 +1,31 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+
+See COPYING file for copyrights details.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __CANCFG_H__
+#define __CANCFG_H__
+
+#define HANDLE int
+#ifndef CAN_HANDLE
+#define CAN_HANDLE void*
+#endif /*CAN_HANDLE*/
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/can_lincan/canmsg.h Tue May 30 23:13:59 2006 +0200
@@ -0,0 +1,136 @@
+/* canmsg.h - common kernel-space and user-space CAN message structure
+ * Linux CAN-bus device driver.
+ * Written by Pavel Pisa - OCERA team member
+ * email:pisa@cmp.felk.cvut.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.3 17 Jun 2004
+ */
+
+#ifndef _CANMSG_T_H
+#define _CANMSG_T_H
+
+#ifdef __KERNEL__
+
+#include <linux/time.h>
+#include <linux/types.h>
+
+#else /* __KERNEL__ */
+
+#include <sys/time.h>
+#include <sys/types.h>
+
+#endif /* __KERNEL__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * CAN_MSG_VERSION_2 enables new canmsg_t layout compatible with
+ * can4linux project from http://www.port.de/
+ *
+ */
+#define CAN_MSG_VERSION_2
+
+/* Number of data bytes in one CAN message */
+#define CAN_MSG_LENGTH 8
+
+#ifdef CAN_MSG_VERSION_2
+
+typedef struct timeval canmsg_tstamp_t ;
+
+typedef unsigned long canmsg_id_t;
+
+/**
+ * struct canmsg_t - structure representing CAN message
+ * @flags: message flags
+ * %MSG_RTR .. message is Remote Transmission Request,
+ * %MSG_EXT .. message with extended ID,
+ * %MSG_OVR .. indication of queue overflow condition,
+ * %MSG_LOCAL .. message originates from this node.
+ * @cob: communication object number (not used)
+ * @id: ID of CAN message
+ * @timestamp: not used
+ * @length: length of used data
+ * @data: data bytes buffer
+ *
+ * Header: canmsg.h
+ */
+struct canmsg_t {
+ int flags;
+ int cob;
+ canmsg_id_t id;
+ canmsg_tstamp_t timestamp;
+ unsigned short length;
+ unsigned char data[CAN_MSG_LENGTH];
+};
+
+#else /*CAN_MSG_VERSION_2*/
+#ifndef PACKED
+#define PACKED __attribute__((packed))
+#endif
+/* Old, deprecated version of canmsg_t structure */
+struct canmsg_t {
+ short flags;
+ int cob;
+ canmsg_id_t id;
+ unsigned long timestamp;
+ unsigned int length;
+ unsigned char data[CAN_MSG_LENGTH];
+} PACKED;
+#endif /*CAN_MSG_VERSION_2*/
+
+typedef struct canmsg_t canmsg_t;
+
+/**
+ * struct canfilt_t - structure for acceptance filter setup
+ * @flags: message flags
+ * %MSG_RTR .. message is Remote Transmission Request,
+ * %MSG_EXT .. message with extended ID,
+ * %MSG_OVR .. indication of queue overflow condition,
+ * %MSG_LOCAL .. message originates from this node.
+ * there are corresponding mask bits
+ * %MSG_RTR_MASK, %MSG_EXT_MASK, %MSG_LOCAL_MASK.
+ * %MSG_PROCESSLOCAL enables local messages processing in the
+ * combination with global setting
+ * @queid: CAN queue identification in the case of the multiple
+ * queues per one user (open instance)
+ * @cob: communication object number (not used)
+ * @id: selected required value of cared ID id bits
+ * @mask: select bits significand for the comparation;
+ * 1 .. take care about corresponding ID bit, 0 .. don't care
+ *
+ * Header: canmsg.h
+ */
+struct canfilt_t {
+ int flags;
+ int queid;
+ int cob;
+ canmsg_id_t id;
+ canmsg_id_t mask;
+};
+
+typedef struct canfilt_t canfilt_t;
+
+/* Definitions to use for canmsg_t and canfilt_t flags */
+#define MSG_RTR (1<<0)
+#define MSG_OVR (1<<1)
+#define MSG_EXT (1<<2)
+#define MSG_LOCAL (1<<3)
+/* If you change above lines, check canque_filtid2internal function */
+
+/* Additional definitions used for canfilt_t only */
+#define MSG_FILT_MASK_SHIFT 8
+#define MSG_RTR_MASK (MSG_RTR<<MSG_FILT_MASK_SHIFT)
+#define MSG_EXT_MASK (MSG_EXT<<MSG_FILT_MASK_SHIFT)
+#define MSG_LOCAL_MASK (MSG_LOCAL<<MSG_FILT_MASK_SHIFT)
+#define MSG_PROCESSLOCAL (MSG_OVR<<MSG_FILT_MASK_SHIFT)
+
+/* Can message ID mask */
+#define MSG_ID_MASK ((1l<<29)-1)
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /*_CANMSG_T_H*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/can_lincan/lincan.h Tue May 30 23:13:59 2006 +0200
@@ -0,0 +1,86 @@
+/* can.h
+ * Header file for the Linux CAN-bus driver.
+ * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
+ * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
+ * email:pisa@cmp.felk.cvut.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.3 17 Jun 2004
+ */
+
+#ifndef _CAN_DRVAPI_T_H
+#define _CAN_DRVAPI_T_H
+
+#ifdef __KERNEL__
+
+#include <linux/time.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#else /* __KERNEL__ */
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#endif /* __KERNEL__ */
+
+#include "./canmsg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* CAN ioctl magic number */
+#define CAN_IOC_MAGIC 'd'
+
+typedef unsigned long bittiming_t;
+typedef unsigned short channel_t;
+
+/**
+ * struct can_baudparams_t - datatype for calling CONF_BAUDPARAMS IOCTL
+ * @flags: reserved for additional flags for chip configuration, should be written -1 or 0
+ * @baudrate: baud rate in Hz
+ * @sjw: synchronization jump width (0-3) prescaled clock cycles
+ * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio
+ *
+ * The structure is used to configure new set of parameters into CAN controller chip.
+ * If default value of some field should be preserved, fill field by value -1.
+ */
+struct can_baudparams_t {
+ long flags;
+ long baudrate;
+ long sjw;
+ long sample_pt;
+};
+
+/* CAN ioctl functions */
+#define CAN_DRV_QUERY _IO(CAN_IOC_MAGIC, 0)
+#define CAN_DRV_QRY_BRANCH 0 /* returns driver branch value - "LINC" for LinCAN driver */
+#define CAN_DRV_QRY_VERSION 1 /* returns driver version as (major<<16) | (minor<<8) | patch */
+#define CAN_DRV_QRY_MSGFORMAT 2 /* format of canmsg_t structure */
+
+#define CMD_START _IOW(CAN_IOC_MAGIC, 1, channel_t)
+#define CMD_STOP _IOW(CAN_IOC_MAGIC, 2, channel_t)
+//#define CMD_RESET 3
+
+#define CONF_BAUD _IOW(CAN_IOC_MAGIC, 4, bittiming_t)
+//#define CONF_ACCM
+//#define CONF_XTDACCM
+//#define CONF_TIMING
+//#define CONF_OMODE
+#define CONF_FILTER _IOW(CAN_IOC_MAGIC, 8, unsigned char)
+
+//#define CONF_FENABLE
+//#define CONF_FDISABLE
+
+#define STAT _IO(CAN_IOC_MAGIC, 9)
+#define CANQUE_FILTER _IOW(CAN_IOC_MAGIC, 10, struct canfilt_t)
+#define CANQUE_FLUSH _IO(CAN_IOC_MAGIC, 11)
+#define CONF_BAUDPARAMS _IOW(CAN_IOC_MAGIC, 11, struct can_baudparams_t)
+#define CANRTR_READ _IOWR(CAN_IOC_MAGIC, 12, struct canmsg_t)
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /*_CAN_DRVAPI_T_H*/