Included interfacing code for LinCAN driver.
authorppavel
Tue, 30 May 2006 23:13:59 +0200
changeset 26 8340a591acf3
parent 25 3b40e2100d96
child 27 c16a00df5621
Included interfacing code for LinCAN driver.
The driver is selected at configure time by

./configure --can=lincan
drivers/can_lincan/Makefile.in
drivers/can_lincan/can_lincan.c
include/can_lincan/cancfg.h
include/can_lincan/canmsg.h
include/can_lincan/lincan.h
--- /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*/