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

📄 can_sja1000_dev.c

📁 s3c2410 arm实验箱关于Can总线的驱动代码。代码条理清晰
💻 C
字号:
/*
****************************************Copyright (c)**************************************************
**                                  广州致远电子有限公司
**                                        CAN开发组 
**                                 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 控制器设备驱动程序
**                              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数据端口物理地址
#define SJA_SRC_LEN	0x01			//SJA1000数据长度,1字节

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,
		
};
/*
********************************************************************************************************************
**函数原型		:  	int can_open(struct inode *p_inode, struct file *p_file)
**参数说明		:	
**返回值		:	
**说	明		:	CAN驱动的
********************************************************************************************************************
*/
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;           		/* 取得次设备号并保存在filp结构中 */
    //设备初始化
	if(TRUE != SJA1000Init(PELI_CAN,BTR_1000K,0x00000000,0xFFFFFFFF))
	{
		printk("<0>SJA1000Init Err!!.\n");
		return -ENODEV;
	}
	//申请中断
	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);
}
/*
********************************************************************************************************************
**函数原型		:  	int can_release(struct inode *p_inode, struct file *p_flie)
**参数说明		:	
**返回值		:	
**说	明		:	CAN驱动的
********************************************************************************************************************
*/
int can_release(struct inode *p_inode, struct file *p_flie)
{
	MOD_DEC_USE_COUNT;
	free_irq(IRQ_EINT5,NULL);
	return(0);
}
/*
********************************************************************************************************************
**函数原型		:  	ssize_t can_read(struct file *p_flie, char *p_buf, size_t count, loff_t *f_pos)
**参数说明		:	
**返回值		:	
**说	明		:	CAN驱动的
********************************************************************************************************************
*/
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));
}
/*
********************************************************************************************************************
**函数原型		:  	ssize_t can_write(struct file *p_flie, const char *p_buf, size_t count, loff_t *f_pos)
**参数说明		:	
**返回值		:	
**说	明		:	CAN驱动的
********************************************************************************************************************
*/
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));
}
/*
********************************************************************************************************************
**函数原型		:  	int can_ioctl(struct inode *p_inode, struct file *p_flie, unsigned int cmd, unsigned long param)
**参数说明		:	
**返回值		:	
**说	明		:	CAN驱动的
********************************************************************************************************************
*/
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);
}
/*
********************************************************************************************************************
**函数原型		:  	int can_init(void)
**参数说明		:	NULL
**返回值		:	返回赋值表示调用出错
**说	明		:	CAN驱动的初始化函数函数
********************************************************************************************************************
*/
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);
    //测试硬件连接
    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;
		}
    }
    //注册设备
    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); 
    }
    //注册中断
    
    //中断初始化
    
    if (MAJOR_NR == 0)
    {
        MAJOR_NR = result; /* dynamic */
    }

    printk(KERN_INFO DEVICE_NAME ": init OK\n");
    return(0);
}
/*
********************************************************************************************************************
**函数原型		:  	void can_cleanup(void)
**参数说明		:	NULL
**返回值		:	NULL
**说	明		:	CAN驱动的清除函数
********************************************************************************************************************
*/
void can_cleanup(void)
{
	PDEBUG("CAll cleanup_module.\n");
	printk("\tUnloading S3C2410 CAN Device Controller Driver\n");
    //关闭CAN设备控制器     
    if(TRUE != SJA_SoftRst(TRUE))
	{
		printk("<0>" "SJA_SoftRst False!.\n");
	}   
    //取消IO映射
    iounmap(sja1000_ale);
	iounmap(sja1000_dat);
	//注销设备
    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
********************************************************************************************************/

⌨️ 快捷键说明

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