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 + -
显示快捷键?