⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcan_main.c

📁 linux下的CAN BUS驱动代码。适合在arm平台使用。
💻 C
📖 第 1 页 / 共 2 页
字号:
//****************************************************************************// Copyright (C) 2001-2007  PEAK System-Technik GmbH//// linux@peak-system.com// www.peak-system.com//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program 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 General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.//// Maintainer(s): Klaus Hitschler (klaus.hitschler@gmx.de)//// Major contributions by://                Edouard Tisserant (edouard.tisserant@lolitech.fr) XENOMAI//                Laurent Bessard   (laurent.bessard@lolitech.fr)   XENOMAI//                Oliver Hartkopp   (oliver.hartkopp@volkswagen.de) socketCAN//                     // Contributions: Marcel Offermans (marcel.offermans@luminis.nl)//                Philipp Baer     (philipp.baer@informatik.uni-ulm.de)//                Garth Zeglin     (garthz@ri.cmu.edu)//                Harald Koenig    (H.Koenig@science-computing.de)//****************************************************************************//****************************************************************************//// pcan_main.c - the starting point of the driver,//               init and cleanup and proc interface//// $Id: pcan_main.c 526 2007-10-29 21:42:02Z khitschler $////****************************************************************************//****************************************************************************// INCLUDES#include <src/pcan_common.h>     // must always be the 1st include#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)#include <linux/config.h>#else#include <linux/autoconf.h>#endif// #define KBUILD_MODNAME pcan#include <linux/module.h>#include <linux/kernel.h>   // DPRINTK()#include <linux/slab.h>     // kmalloc()#include <linux/fs.h>       // everything...#include <linux/errno.h>    // error codes#include <linux/types.h>    // size_t#include <linux/proc_fs.h>  // proc#include <linux/fcntl.h>    // O_ACCMODE#include <linux/capability.h> // all about restrictions#include <linux/param.h>    // because of HZ#include <asm/system.h>     // cli(), *_flags#include <asm/uaccess.h>    // copy_...#include <src/pcan_main.h>#ifdef PCI_SUPPORT#include <src/pcan_pci.h>   // get support for PCAN-PCI#endif#ifdef ISA_SUPPORT#include <src/pcan_isa.h>   // get support for PCAN-ISA and PCAN-104#endif#ifdef DONGLE_SUPPORT#include <src/pcan_dongle.h> // get support for PCAN-Dongle#endif#ifdef USB_SUPPORT#include <src/pcan_usb.h>   // get support for PCAN-USB#endif#ifdef PCCARD_SUPPORT#include <src/pcan_pccard.h>#endif#ifdef NETDEV_SUPPORT#include <src/pcan_netdev.h>#endif#include <src/pcan_fops.h>#include <src/pcan_fifo.h>#include <src/pcan_filter.h>//****************************************************************************// DEFINES#define DEFAULT_BTR0BTR1    CAN_BAUD_500K  // defaults to 500 kbit/sec#define DEFAULT_EXTENDED    1              // catch all frames#define DEFAULT_LISTENONLY  0//****************************************************************************// GLOBALS// filled by module initialisationchar *type[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};u16  io[8]    = {0, 0, 0, 0, 0, 0, 0, 0};u8   irq[8]   = {0, 0, 0, 0, 0, 0, 0, 0};u16  bitrate  = DEFAULT_BTR0BTR1;char *assign  = NULL;//----------------------------------------------------------------------------// the global driver object, create itstruct driverobj pcan_drv = {};#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)//----------------------------------------------------------------------------// some stuff to support SysFS coming with kernel 2.6#include <linux/device.h>// not yet implemented#endif// build current driver config string for output in kernel log and procfsconst char current_config[] = " "#ifdef DEBUG"[dbg] "#endif#ifdef MODVERSIONS"[mod] "#endif#ifdef ISA_SUPPORT"[isa] "#endif#ifdef PCI_SUPPORT"[pci] "#endif#ifdef DONGLE_SUPPORT"[dng] "#endif#ifdef PARPORT_SUBSYSTEM"[par] "#endif#ifdef USB_SUPPORT"[usb] "#endif#ifdef PCCARD_SUPPORT"[pcc] "#endif#ifdef NETDEV_SUPPORT"[net] "#endif#ifndef NO_RT"[rt] "#endif;// for procfs output the current_config is copied into this string (centered!)char config[] = "*----------------------------------------------------------------------------";//****************************************************************************// LOCALS//****************************************************************************// CODE#ifdef NO_RT  #include "pcan_main_linux.c"#else  #include "pcan_main_rt.c"#endif//****************************************************************************// debug utilityvoid buffer_dump(u8 *pucBuffer, u16 wLineCount){  #ifdef DEBUG  int i, j;  for (i = 0; i < wLineCount; i++)  {    printk(KERN_DEBUG "%s: %04x ", DEVICE_NAME, i * 16);    for (j = 0; j < 8; j++)      printk(" %02x", *pucBuffer++);    printk(" ");    for (j = 0; j < 8; j++)      printk(" %02x", *pucBuffer++);    printk("\n");  }  #endif}//----------------------------------------------------------------------------// convert struct can_frame to struct TPCANMsg// To reduce the complexity (and CPU usage) there are no checks (e.g. for dlc)// here as it is assumed that the creator of the source struct has done this workvoid frame2msg(struct can_frame *cf, TPCANMsg *msg){  if (cf->can_id & CAN_ERR_FLAG)  {    memset(msg, 0, sizeof(*msg));    msg->MSGTYPE = MSGTYPE_STATUS;    msg->LEN     = 4;        if (cf->can_id & CAN_ERR_CRTL)    {      // handle data overrun      if (cf->data[1] & CAN_ERR_CRTL_RX_OVERFLOW)        msg->DATA[3] |= CAN_ERR_OVERRUN;            // handle CAN_ERR_BUSHEAVY      if (cf->data[1] & CAN_ERR_CRTL_RX_WARNING)        msg->DATA[3] |= CAN_ERR_BUSHEAVY;    }        if (cf->can_id & CAN_ERR_BUSOFF_NETDEV)      msg->DATA[3] |= CAN_ERR_BUSOFF;          return;  }    if (cf->can_id & CAN_RTR_FLAG)    msg->MSGTYPE = MSGTYPE_RTR;  else    msg->MSGTYPE = MSGTYPE_STANDARD;        if (cf->can_id & CAN_EFF_FLAG)    msg->MSGTYPE |= MSGTYPE_EXTENDED;  msg->ID  = cf->can_id & CAN_EFF_MASK; /* remove EFF/RTR/ERR flags */  msg->LEN = cf->can_dlc; /* no need to check value range here */  memcpy(&msg->DATA[0], &cf->data[0], 8); /* also copy trailing zeros */}//----------------------------------------------------------------------------// convert struct TPCANMsg to struct can_frame// To reduce the complexity (and CPU usage) there are no checks (e.g. for dlc)// here as it is assumed that the creator of the source struct has done this workvoid msg2frame(struct can_frame *cf, TPCANMsg *msg){  cf->can_id = msg->ID;  if (msg->MSGTYPE & MSGTYPE_RTR)    cf->can_id |= CAN_RTR_FLAG;  if (msg->MSGTYPE & MSGTYPE_EXTENDED)    cf->can_id |= CAN_EFF_FLAG;  // if (msg->MSGTYPE & MSGTYPE_??????)  //   cf->can_id |= CAN_ERR_FLAG;  cf->can_dlc = msg->LEN; /* no need to check value range here */  memcpy(&cf->data[0], &msg->DATA[0], 8); /* also copy trailing zeros */}//----------------------------------------------------------------------------// request time in msec, fastu32 get_mtime(void){      return (jiffies / HZ) * 1000;}// x = (x >= y) ? x - y : 0;static void subtract_timeval(struct timeval *x, struct timeval *y){  if (x->tv_usec >= y->tv_usec)    x->tv_usec -= y->tv_usec;  else  {    if (x->tv_sec)    {      x->tv_sec--;      x->tv_usec += (1000000 - y->tv_usec);    }    else      goto fail;  }      if (x->tv_sec >= y->tv_sec)  {    x->tv_sec -= y->tv_sec;    return;  }      fail:  x->tv_sec = x->tv_usec = 0;} // get relative time to start of drivervoid get_relative_time(struct timeval *tv, struct timeval *tr){  if (!tv)    DO_GETTIMEOFDAY((*tr));  else    memcpy(tr, tv, sizeof(*tr));    subtract_timeval(tr, &pcan_drv.sInitTime);}// convert timeval to pcan used milliseconds / microseconds notationvoid timeval2pcan(struct timeval *tv, u32 *msecs, u16 *usecs){  *msecs = (u32)(tv->tv_sec * 1000 + tv->tv_usec / 1000);  *usecs = (u16)(tv->tv_usec % 1000);  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -