canpie_dev.c.svn-base
来自「canpie 一个can bus的协议栈 - CAN interface fo」· SVN-BASE 代码 · 共 326 行
SVN-BASE
326 行
//****************************************************************************//
// File: canpie_dev.c //
// Description: CANpie interface to /dev //
// Author: Uwe Koppe //
// e-mail: koppe@microcontrol.net //
// //
//============================================================================//
// This program 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. //
//============================================================================//
// //
// Date History //
// ---------- -------------------------------------------------------------- //
// 05.06.2000 Initial version //
// //
//****************************************************************************//
/*----------------------------------------------------------------------------*\
** Include files **
** **
\*----------------------------------------------------------------------------*/
#include <linux/fs.h> // everything...
#include <linux/errno.h> // error codes
#include <linux/types.h> // size_t
#include <linux/fcntl.h> // O_ACCMODE
#include <linux/version.h>
#include <asm/uaccess.h> // user space access
#include "canpie.h"
#include "canpie_dbg.h"
#include "canpie_dev.h"
#include "cpcore.h"
#define CAN_DEV_MAJOR 91
#define CAN_DEV_NAME "can"
/*----------------------------------------------------------------------------*\
** External functions used in this module **
** **
\*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*\
** Functions **
** **
\*----------------------------------------------------------------------------*/
//----------------------------------------------------------------------------//
// cp_open() //
// //
//----------------------------------------------------------------------------//
int cp_open (struct inode *inode, struct file *filp)
{
_U08 ubChannelT;
ubChannelT = MINOR(inode->i_rdev);
//----------------------------------------------------------------
// Startup message
//
PK_INF("cp_open()");
//PDEBUG("cp_open()\n");
//--- init the CAN interface ---------------------------
if(CpCoreDriverInit(ubChannelT) != CpErr_OK) return (-ENODEV);
return 0; /* success */
}
//----------------------------------------------------------------------------//
// cp_close() //
//----------------------------------------------------------------------------//
int cp_close(struct inode *inode, struct file *file)
{
_U08 ubChannelT;
ubChannelT = MINOR(inode->i_rdev);
// PDEBUG("cp_close() on channel %d\n", ubChannelT);
//--- de-init the CAN interface ----------------------------------
if(CpCoreDriverRelease(ubChannelT) != CpErr_OK) return (-ENODEV);
return(0);
}
//----------------------------------------------------------------------------//
// cp_read() //
//----------------------------------------------------------------------------//
ssize_t cp_read( struct file *file, char *buffer,
size_t length, loff_t *offset)
{
_U08 ubChannelT; // the CAN channel
_U08 ubStatusT; // status of operation
_TsCpCanMsg tsCanMsgT;
//----------------------------------------------------------------
// retrieve the channel for operation
//
ubChannelT = MINOR(file->f_dentry->d_inode->i_rdev);
//-----------------------------------------------------------------
// read message from CAN interface
//
// if( CpCoreMsgReceive(ubChannelT) != CpErr_OK) return(0);
//-----------------------------------------------------------------
// pop message from fifo
//
//ubStatusT = CpFifoPop(ubChannelT, CP_FIFO_RCV, &tsCanRcvMsgG);
ubStatusT = CpErr_FIFO_EMPTY;
if(ubStatusT == CpErr_FIFO_EMPTY) return (0);
//----------------------------------------------------------------
// copy data to user space
copy_to_user(buffer, &tsCanMsgT, sizeof(tsCanMsgT) );
return ( sizeof(tsCanMsgT) );
}
//----------------------------------------------------------------------------//
// cp_write() //
//----------------------------------------------------------------------------//
ssize_t cp_write( struct file *file, const char *buffer,
size_t length, loff_t *offset)
{
_U08 ubChannelT; // the CAN channel
_TsCpCanMsg tsCanMsgT;
//----------------------------------------------------------------
// copy data from user space
copy_from_user(&tsCanMsgT, buffer, sizeof(tsCanMsgT) );
//----------------------------------------------------------------
// retrieve the channel for operation
ubChannelT = MINOR(file->f_dentry->d_inode->i_rdev);
//----------------------------------------------------------------
// write it to the CAN interface
//
// CpCoreMsgTransmit(ubChannelT);
return length;
}
//----------------------------------------------------------------------------//
// ioctl() //
//----------------------------------------------------------------------------//
int cp_ioctl ( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long ulArgV)
{
_U08 ubChannelT; // the CAN channel
_U08 ubByteVal1T, ubByteVal2T; // local variables for byte parameters
_U08 ubByteVal3T, ubByteVal4T;
//----------------------------------------------------------------
// DEBUGGING
//PDEBUG("cp_ioctl(): Argument=%lX\n", ulArgV);
//----------------------------------------------------------------
// retrieve the channel for operation
ubChannelT = MINOR(filp->f_dentry->d_inode->i_rdev);
//----------------------------------------------------------------
// extract the type and number bitfields, and don't decode
// wrong cmds: return EINVAL before verify_area()
//
if ( _IOC_TYPE(cmd) != CP_IOC_MAGIC ) return -EINVAL;
if ( _IOC_NR (cmd) > CP_IOC_MAXNR ) return -EINVAL;
//----------------------------------------------------------------
switch(cmd)
{
case CP_IOC_RESET:
break;
//--- setup bittiming -------------------------------
case CP_IOC_BITTIMING:
ubByteVal3T = (_U08) (ulArgV & 0x000000FF);
ulArgV = ulArgV >> 8;
ubByteVal2T = (_U08) (ulArgV & 0x000000FF);
ulArgV = ulArgV >> 8;
ubByteVal1T = (_U08) (ulArgV & 0x000000FF);
CpCoreBaudrate(ubChannelT, ubByteVal1T, ubByteVal2T, ubByteVal3T);
break;
//--- set filter for specific identifier ------------
/*
case CP_IOC_FILTER_MSG_ENABLE:
filterMask = arg;
PDEBUG("filter id=%04X \n", (_U16) filterMask);
if(filterMask & 0x80000000) {
CpCoreFilterMsg(ubChannelT, (_U16) filterMask, 1);
}
else {
CpCoreFilterMsg(ubChannelT, (_U16) filterMask, 0);
}
break;
//--- set filter for all messages -------------------
case CP_IOC_FILTER_ALL_ENABLE:
filterMask = arg;
PDEBUG("filter all=%d \n", (filterMask & 0x80000000));
if(filterMask & 0x80000000) CpCoreFilterAll(ubChannelT, 1);
else CpCoreFilterAll(ubChannelT, 0);
break;
*/
default: // redundant, as cmd was checked against MAXNR
return -EINVAL;
}
return 0;
}
//----------------------------------------------------------------------------//
// File operations structure //
//----------------------------------------------------------------------------//
struct file_operations cp_fops = {
NULL, // module owner
NULL, // llseek
cp_read, // read
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
NULL, // aio_read
#endif
cp_write, // write
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
NULL, // aio_write
#endif
NULL, // readdir
NULL, // poll
cp_ioctl, // ioctrl
NULL, // mmap
cp_open, // open the driver
NULL, // flush
cp_close, // close the driver
NULL, // fsync
NULL, // fasync
NULL, // check_media_change
NULL, // revalidate
NULL // lock
};
//----------------------------------------------------------------------------//
// cp_dev_init() //
//----------------------------------------------------------------------------//
int cp_dev_init(void)
{
int slResultT;
//----------------------------------------------------------------
// Startup message
//
PK_INF("/dev/can support enabled (major=%d)", CAN_DEV_MAJOR);
//----------------------------------------------------------------
// register CANpie with the major "CAN_DEV_MAJOR"
//
slResultT = register_chrdev(CAN_DEV_MAJOR, CAN_DEV_NAME, &cp_fops);
if(slResultT < 0)
{
printk(KERN_WARNING "Failed: CANpie can't get major number %d!\n",
CAN_DEV_MAJOR);
return slResultT;
}
//----------------------------------------------------------------
// print status message
//
return 0;
}
//----------------------------------------------------------------------------//
// cleanup_module //
//----------------------------------------------------------------------------//
void cp_dev_cleanup(void)
{
//----------------------------------------------------------------
// Stop message
PK_INF("Stopping /dev/can support");
unregister_chrdev(CAN_DEV_MAJOR, CAN_DEV_NAME);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?