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

📄 mcpcan.c

📁 武汉创维特公司的2410arm9开发办的can linux源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}

/* * Atomicly increment an index into shortp_in_buffer */static inline void incr_buffer_pointer(volatile unsigned long*index, int delta, int i){	unsigned long newvalue = *index + delta;	barrier ();  /* Don't optimize these two together */	*index = (newvalue >= (Device[i]->RecvBuf + BUF_SIZE)) ? Device[i]->RecvBuf : newvalue;}static void mcpcan0_handler(int irq, void *dev_id, struct pt_regs *regs){	struct MCP_device *dev = dev_id;	struct mcpcan_data datagram;	int written;	char regvalue, regvalue2;	//struct mcpcan_data *datagramptr;	printk("\rextern irq 5 handled\n");	regvalue = CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->CANINTE)), ARG_UNUSED, ARG_UNUSED );	printk("CANINTE = 0x%02x\n",regvalue);	regvalue = CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->CANINTF)), ARG_UNUSED, ARG_UNUSED );	printk("CANINTF = 0x%02x\n",regvalue);	if(regvalue & 0x01){		datagram.BufNo = RXBUF0;		MCP2510_RX(datagram.BufNo, &(datagram.IdType), &(datagram.id), &(datagram.DataLen), datagram.data );		printk("RXBUF0\n");        //printk("datagram.BufNo = %d\n",datagram.BufNo);        //printk("datagram.IdType = %d\n",datagram.IdType);        //printk("datagram.id = %d\n",datagram.id);        //printk("datagram.DataLen = %d\n",datagram.DataLen);        //printk("datagram.data = %s\n",datagram.data);	    /* Write a 16 byte record. Assume BUF_SIZE is a multiple of 16 */		memcpy((void *)dev->RecvHead, &datagram, sizeof(struct mcpcan_data));		//datagramptr = (struct mcpcan_data *)dev->RecvHead;		//printk("RecvHead->BufNo = %d\n",datagramptr->BufNo);		//printk("RecvHead->IdType = %d\n",datagramptr->IdType);		//printk("RecvHead->id = %d\n",datagramptr->id);		//printk("RecvHead->DataLen = %d\n",datagramptr->DataLen);		//printk("RecvHead->data = %s\n",datagramptr->data);		incr_buffer_pointer(&(dev->RecvHead), sizeof(struct mcpcan_data), dev->MinorNum);		wake_up_interruptible(&(dev->inq)); /* awake any reading process */		CAN_SPI_CMD( SPI_CMD_BITMOD, TOLONG(&(MCP2510_MAP->CANINTF)), 0x01, 0x00 );     //in fact already clear interrupt bit in RX 	}	if(regvalue & 0x02){		datagram.BufNo = RXBUF1;		//this function should be rewritten to receive datagram from RXB1??????????????????		MCP2510_RX(datagram.BufNo, &(datagram.IdType), &(datagram.id), &(datagram.DataLen), datagram.data );		printk("RXBUF1\n");	    /* Write a 16 byte record. Assume BUF_SIZE is a multiple of 16 */		memcpy((void *)dev->RecvHead, &datagram, sizeof(struct mcpcan_data));				incr_buffer_pointer(&(dev->RecvHead), sizeof(struct mcpcan_data), dev->MinorNum);		wake_up_interruptible(&dev->inq); /* awake any reading process */		CAN_SPI_CMD( SPI_CMD_BITMOD, TOLONG(&(MCP2510_MAP->CANINTF)), 0x02, 0x00 );     //in fact already clear interrupt bit in RX	}	if(regvalue & 0xe0){		printk("CAN error with CANINTF = 0x%02x.\n", regvalue);		if(regvalue & 0x80)printk("MERRF:message error.\n");		if(regvalue & 0x40)printk("WAKIF:wake up interrupt.\n");		if(regvalue & 0x20)printk("ERRIF:CAN bus error interrupt.\n");				regvalue2 = CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->EFLG)), ARG_UNUSED, ARG_UNUSED );		printk("EFLG = 0x%02x.\n", regvalue2);                regvalue2 = CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->TEC)), ARG_UNUSED, ARG_UNUSED );                printk("TEC = 0x%02x.\n", regvalue2);                regvalue2 = CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->REC)), ARG_UNUSED, ARG_UNUSED );                printk("REC = 0x%02x.\n", regvalue2);		CAN_SPI_CMD( SPI_CMD_BITMOD, TOLONG(&(MCP2510_MAP->CANINTF)), 0xe0, 0x00 );	}	if(CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->CANINTF)), ARG_UNUSED, ARG_UNUSED ) & 0x1c){  //didn't open the 3 send interrupts		CAN_SPI_CMD( SPI_CMD_BITMOD, TOLONG(&(MCP2510_MAP->CANINTF)), 0x1c, 0x00 ); //clear TX bits directly(it will set 1,but no int)	}        regvalue = CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->CANINTF)), ARG_UNUSED, ARG_UNUSED );	printk("after interrupt processing, CANINTF = 0x%02x\n",regvalue);}static void mcpcan1_handler(int irq, void *dev_id, struct pt_regs *regs){	//printk("\rextern irq ? handled");}/*****************************MCPCAN open**********************************/static int device_open(struct inode *inode,struct file *filp){    int MinorNum;	int eint_irq;	int ret_val;    struct MCP_device *dev;	static int irqcount0=0, irqcount1=0;    MinorNum = MINOR(inode->i_rdev);    if(MinorNum >= MCP_NUM) return(-ENODEV);            dev = Device[MinorNum];    filp->private_data = dev;        //save to private_data	request_region(0x59000000,0x38,"MCPCAN");    //SPI interface	request_region(0x56000000,0x94,"MCPCAN");  //I/O port	request_region(0x4c00000c,4,"MCPCAN");  //clock 	/* register the eint5 irq */	if(irqcount0 == 0){		eint_irq = IRQ_EINT5;		set_external_irq(eint_irq, EXT_FALLING_EDGE, GPIO_PULLUP_DIS);		ret_val = request_irq(eint_irq, mcpcan0_handler, SA_INTERRUPT | SA_SHIRQ, MCP_name[dev->MinorNum], dev);		if (ret_val < 0) {			return ret_val;		}		irqcount0++;	}	MCP2510_Init(MinorNum);	MOD_INC_USE_COUNT;    return 0;}/*****************************Functin MCP_release**************************/static int device_release(struct inode *inode,struct file *filp){	struct MCP_device *dev = filp->private_data;	release_region(0x59000000,0x38);	release_region(0x56000000,0x94);	release_region(0x4c00000c,4);	free_irq(dev->IrqNum,dev);    //shared irq	MOD_DEC_USE_COUNT;	return 0;}ssize_t device_read (struct file *filp, char *buf, size_t count, loff_t *f_pos){	int count0;		struct MCP_device *dev = filp->private_data;		if (down_interruptible(&dev->sem))		return -ERESTARTSYS;	while (dev->RecvHead == dev->RecvTail) { /* nothing to read */		up(&dev->sem); /* release the lock */		if (filp->f_flags & O_NONBLOCK)			return -EAGAIN;		if (wait_event_interruptible(dev->inq, (dev->RecvHead != dev->RecvTail)))			return -ERESTARTSYS; /* signal: tell the fs layer to handle it */		/* otherwise loop, but first reacquire the lock */		if (down_interruptible(&dev->sem))			return -ERESTARTSYS;	}	/* ok, data is there, return something */	/* count0 is the number of readable data bytes */	count0 = dev->RecvHead - dev->RecvTail;	if (count0 < 0) /* wrapped */		count0 = dev->RecvBuf + BUF_SIZE - dev->RecvTail;	if (count0 < count) count = count0;	if (copy_to_user(buf, (char *)dev->RecvTail, count)){		up (&dev->sem);		return -EFAULT;	}	incr_buffer_pointer(&(dev->RecvTail), count, dev->MinorNum);	up (&dev->sem);	return count;}ssize_t device_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos){	mcpcan_data     temp;	struct MCP_device *dev = filp->private_data;	if(down_interruptible(&dev->sem))		return -ERESTARTSYS;	copy_from_user(&temp, buf, sizeof(struct mcpcan_data));	MCP2510_TX(temp.BufNo,temp.IdType,temp.id,temp.DataLen,temp.data );	up(&dev->sem);	return count;}/* This function is called whenever a process tries to  * do an ioctl on our device file. We get two extra  * parameters (additional to the inode and file  * structures, which all device functions get): the number * of the ioctl called and the parameter given to the  * ioctl function. * * If the ioctl is write or read/write (meaning output  * is returned to the calling process), the ioctl call  * returns the output of this function. *//*int device_ioctl(    struct inode *inode,    struct file *file,    unsigned int ioctl_num,// The number of the ioctl     unsigned long ioctl_param) // The parameter to it {}*//*****************************File operations define************************/struct file_operations Fops = {    .open = device_open,    //open    .release = device_release,    //release	.read = device_read,	.write = device_write};
/****************************Module initialize******************************/static int __init mcpcan_init_module(void){        int res;        //EXPORT_NO_SYMBOLS;        /* Register the character device (atleast try) */        res = register_chrdev(MCP_major,"MCPCAN",&Fops);        if(res < 0) {               printk("device register failed with %d.\n",res);               return res;        }        if(MCP_major == 0) MCP_major = res;	    MCP_device_init();		printk ("%s The major device number is %d.\n",				"Registeration is a success", 				MCP_major);		          		printk ("If you want to talk to the device driver,\n");		printk ("you'll have to create a device file. \n");		printk ("We suggest you use:\n");		printk ("mknod /dev/%s c %d 0\n", "can",MCP_major);		printk ("The device file name is important, because\n");		printk ("the ioctl program assumes that's the\n");		printk ("file you'll use.\n");        return 0;}/****************************Module release********************************/static void __exit mcpcan_cleanup_module(void){	int i;    unregister_chrdev(MCP_major,"MCPCAN");	for(i=0; i<2; i++){		kfree((void *)Device[i]->RecvBuf);		kfree(Device[i]->SendBuf);		kfree(Device[i]);	}    printk("MCPCAN release success.\n");}module_init(mcpcan_init_module);module_exit(mcpcan_cleanup_module);

⌨️ 快捷键说明

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