?? can_sja1000_dev.c
字號(hào):
/*
****************************************Copyright (c)**************************************************
** 廣州致遠(yuǎn)電子有限公司
** CAN開(kāi)發(fā)組
** http://www.zyinside.com
**
**
**--------------File Info-------------------------------------------------------------------------------
** File name: can_sja1000-dev.c
** Last modified Date: 2006-02-16
** Last Version: V1.0
** Descriptions: can_sja1000-dev.c, S3C2410 SJA1000 CAN 控制器設(shè)備驅(qū)動(dòng)程序
** can_sja1000-dev.c, S3C2410 SJA1000 CAN-bus controller driver
**------------------------------------------------------------------------------------------------------
** Created by: 滕欣欣 Xingxing Teng
** Created date: 2006-02-16
** Version: V1.0
** Descriptions: 初始版本 The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#include "config.h"
#include "Print_DEBUG.h"
#define SJA_ALE_PADR 0x20000008 //SJA1000鎖存器端口物理地址
#define SJA_DAT_PADR 0x20000004 //SJA1000數(shù)據(jù)端口物理地址
#define SJA_SRC_LEN 0x01 //SJA1000數(shù)據(jù)長(zhǎng)度,1字節(jié)
static int major = CAN_MAJOR_NR;
stcSJA1000_BufInfo SJA1000_RxBuf;
void *sja1000_ale;
void *sja1000_dat;
static DECLARE_WAIT_QUEUE_HEAD(can_wait);
EXPORT_SYMBOL(sja1000_ale);
EXPORT_SYMBOL(sja1000_dat);
static int can_init(void);
static void can_cleanup(void);
static int can_open(struct inode *p_inode, struct file *p_file);
static int can_release(struct inode *p_inode, struct file *p_flie);
static ssize_t can_read(struct file *p_flie, char *p_buf, size_t count, loff_t *f_pos);
static ssize_t can_write(struct file *p_flie, const char *p_buf, size_t count, loff_t *f_pos);
static int can_ioctl(struct inode *p_inode, struct file *p_flie, unsigned int cmd, unsigned long param);
static void can_interrupt(int irq , void* dev_id, struct pt_regs *regs);
MODULE_PARM(major, "i");
MODULE_DESCRIPTION("Guangzhou Zhiyuan Electronic Co.,LTD.\ngraduate school\nhttp://www.zyinside.com");
MODULE_SUPPORTED_DEVICE("Linux 2.4.18 & MagicARM2410");
MODULE_AUTHOR("Xinxin Teng");
#define MAJOR_NR major
struct file_operations sja1000_can_fops =
{
owner: THIS_MODULE,
ioctl: can_ioctl,
open : can_open,
write: can_write,
read: can_read,
release : can_release,
};
/*
********************************************************************************************************************
**函數(shù)原型 : int can_open(struct inode *p_inode, struct file *p_file)
**參數(shù)說(shuō)明 :
**返回值 :
**說(shuō) 明 : CAN驅(qū)動(dòng)的
********************************************************************************************************************
*/
int can_open(struct inode *p_inode, struct file *p_file)
{
uint8 num;
int result;
/* get the device minor and save into filp structure */
num = MINOR(p_inode->i_rdev);
//p_file->private_data = (void *)num; /* 取得次設(shè)備號(hào)并保存在filp結(jié)構(gòu)中 */
//設(shè)備初始化
if(TRUE != SJA1000Init(PELI_CAN,BTR_1000K,0x00000000,0xFFFFFFFF))
{
printk("<0>SJA1000Init Err!!.\n");
return -ENODEV;
}
//申請(qǐng)中斷
set_external_irq(IRQ_EINT5,EXT_FALLING_EDGE,GPIO_PULLUP_DIS);
result = request_irq(IRQ_EINT5, can_interrupt, SA_INTERRUPT, "SJA1000", NULL);
if(result == 0)
{
printk("<0> Interrupt Set OK!.\n");
}
else
{
printk("<0> Interrupt Set Err! ErrCose = %d.\n", result);
return result;
}
MOD_INC_USE_COUNT;
printk("<0>" DEVICE_NAME " Opened!.\n");
return(0);
}
/*
********************************************************************************************************************
**函數(shù)原型 : int can_release(struct inode *p_inode, struct file *p_flie)
**參數(shù)說(shuō)明 :
**返回值 :
**說(shuō) 明 : CAN驅(qū)動(dòng)的
********************************************************************************************************************
*/
int can_release(struct inode *p_inode, struct file *p_flie)
{
MOD_DEC_USE_COUNT;
free_irq(IRQ_EINT5,NULL);
return(0);
}
/*
********************************************************************************************************************
**函數(shù)原型 : ssize_t can_read(struct file *p_flie, char *p_buf, size_t count, loff_t *f_pos)
**參數(shù)說(shuō)明 :
**返回值 :
**說(shuō) 明 : CAN驅(qū)動(dòng)的
********************************************************************************************************************
*/
ssize_t can_read(struct file *p_flie, char *p_buf, size_t count, loff_t *f_pos)
{
interruptible_sleep_on(&can_wait);
if(count != sizeof(stcSJA1000_BufInfo))
{
return (-EINVAL);
}
if(copy_to_user(p_buf,(void*)(&SJA1000_RxBuf),sizeof(stcSJA1000_BufInfo)))
{
printk("Coyp to usr Err!.\n");
return -EFAULT;
}
return(sizeof(SJA1000_RxBuf));
}
/*
********************************************************************************************************************
**函數(shù)原型 : ssize_t can_write(struct file *p_flie, const char *p_buf, size_t count, loff_t *f_pos)
**參數(shù)說(shuō)明 :
**返回值 :
**說(shuō) 明 : CAN驅(qū)動(dòng)的
********************************************************************************************************************
*/
ssize_t can_write(struct file *p_flie, const char *p_buf, size_t count, loff_t *f_pos)
{
stcSJA1000_BufInfo TxBuf;
if(count != sizeof(stcSJA1000_BufInfo))
{
printk("count = %d not %d\n",count,sizeof(stcSJA1000_BufInfo));
return (-EINVAL);
}
if(copy_from_user((void*)&TxBuf,(void*)p_buf,sizeof(stcSJA1000_BufInfo)))
{
printk("copy_from_user Err.\n");
return -EFAULT;
}
SetTxBuf(&TxBuf);
SetCommand(CMR_NOM_SD);
return(sizeof(SJA1000_RxBuf));
}
/*
********************************************************************************************************************
**函數(shù)原型 : int can_ioctl(struct inode *p_inode, struct file *p_flie, unsigned int cmd, unsigned long param)
**參數(shù)說(shuō)明 :
**返回值 :
**說(shuō) 明 : CAN驅(qū)動(dòng)的
********************************************************************************************************************
*/
int can_ioctl(struct inode *p_inode, struct file *p_flie, unsigned int cmd, unsigned long param)
{
int val = 0;
switch(cmd)
{
case IOCTL_BAUD:
SJA_SoftRst(TRUE);
if(TRUE != SetBaudRate((uint16)param))
{
val = -ENOTTY;
}
SJA_SoftRst(FALSE);
break;
case IOCTL_ACR:
SJA_SoftRst(TRUE);
if(TRUE != ACRCode(param))
{
val = -ENOTTY;
}
SJA_SoftRst(FALSE);
break;
case IOCTL_AMR:
SJA_SoftRst(TRUE);
if(TRUE != AMRCode(param))
{
val = -ENOTTY;
}
SJA_SoftRst(FALSE);
break;
default:
val = -ENOTTY;
break;
}
return(val);
}
/*
********************************************************************************************************************
**函數(shù)原型 : int can_init(void)
**參數(shù)說(shuō)明 : NULL
**返回值 : 返回賦值表示調(diào)用出錯(cuò)
**說(shuō) 明 : CAN驅(qū)動(dòng)的初始化函數(shù)函數(shù)
********************************************************************************************************************
*/
int can_init(void)
{
int i,result;
PDEBUG("CAll init_module.\n");
//映射IO
sja1000_dat = ioremap(SJA_DAT_PADR,SJA_SRC_LEN);
sja1000_ale = ioremap(SJA_ALE_PADR,SJA_SRC_LEN);
//測(cè)試硬件連接
for (i=0 ; i<0x8; i++)
{
writeb(0x09,sja1000_ale);
writeb(1<<i,sja1000_dat);
writeb(0x09,sja1000_ale);
if(readb(sja1000_dat) != 1<<i)
{
iounmap(sja1000_ale);
iounmap(sja1000_dat);
printk("SJA_1000 Hare Ware Connected Err!!");
return -ENODEV;
}
}
//注冊(cè)設(shè)備
result = register_chrdev(MAJOR_NR, DEVICE_NAME, &sja1000_can_fops);
if (result < 0)
{
printk("<0>" DEVICE_NAME ": Unable to get major %d\n", MAJOR_NR );
return(result);
}
//注冊(cè)中斷
//中斷初始化
if (MAJOR_NR == 0)
{
MAJOR_NR = result; /* dynamic */
}
printk(KERN_INFO DEVICE_NAME ": init OK\n");
return(0);
}
/*
********************************************************************************************************************
**函數(shù)原型 : void can_cleanup(void)
**參數(shù)說(shuō)明 : NULL
**返回值 : NULL
**說(shuō) 明 : CAN驅(qū)動(dòng)的清除函數(shù)
********************************************************************************************************************
*/
void can_cleanup(void)
{
PDEBUG("CAll cleanup_module.\n");
printk("\tUnloading S3C2410 CAN Device Controller Driver\n");
//關(guān)閉CAN設(shè)備控制器
if(TRUE != SJA_SoftRst(TRUE))
{
printk("<0>" "SJA_SoftRst False!.\n");
}
//取消IO映射
iounmap(sja1000_ale);
iounmap(sja1000_dat);
//注銷設(shè)備
unregister_chrdev(MAJOR_NR, DEVICE_NAME);
}
void can_interrupt(int irq , void* dev_id, struct pt_regs *regs)
{
IntEnty();
wake_up_interruptible(&can_wait);
}
module_init(can_init);
module_exit(can_cleanup);
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -