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

📄 sja1000funcs.c

📁 can4linux-3.5.3.gz can4 linux
💻 C
📖 第 1 页 / 共 2 页
字号:
	    #else	    if( need_resched ) schedule();	    #endif    }    DBGprint(DBG_DATA,(    		"CAN[%d]: tx.flags=%d tx.id=0x%lx tx.length=%d stat=0x%x",		minor, tx->flags, tx->id, tx->length, stat));    tx->length %= 9;			/* limit CAN message length to 8 */    ext = (tx->flags & MSG_EXT);	/* read message format */    /* fill the frame info and identifier fields */    tx2reg = tx->length;    if( tx->flags & MSG_RTR) {	    tx2reg |= CAN_RTR;    }    if(ext) {    DBGprint(DBG_DATA, ("---> send ext message"));	CANout(minor, frameinfo, CAN_EFF + tx2reg);	CANout(minor, frame.extframe.canid1, (u8)(tx->id >> 21));	CANout(minor, frame.extframe.canid2, (u8)(tx->id >> 13));	CANout(minor, frame.extframe.canid3, (u8)(tx->id >> 5));	CANout(minor, frame.extframe.canid4, (u8)(tx->id << 3) & 0xff);    } else {	DBGprint(DBG_DATA, ("---> send std message"));	CANout(minor, frameinfo, CAN_SFF + tx2reg);	CANout(minor, frame.stdframe.canid1, (u8)((tx->id) >> 3) );	CANout(minor, frame.stdframe.canid2, (u8)(tx->id << 5 ) & 0xe0);    }    /* - fill data ---------------------------------------------------- */    if(ext) {	for( i=0; i < tx->length ; i++) {	    CANout( minor, frame.extframe.canxdata[R_OFF * i], tx->data[i]);	    	/* SLOW_DOWN_IO; SLOW_DOWN_IO; */	}    } else {	for( i=0; i < tx->length ; i++) {	    CANout( minor, frame.stdframe.candata[R_OFF * i], tx->data[i]);	    	/* SLOW_DOWN_IO; SLOW_DOWN_IO; */	}    }    /* - /end --------------------------------------------------------- */    CANout(minor, cancmd, CAN_TRANSMISSION_REQUEST );    /*      * Save last message that was sent.     * Since can4linux 3.5 multiple processes can access     * one CAN interface. On a CAN interrupt this message is copied into      * the receive queue of each process that opened this same CAN interface.     */    memcpy(	(void *)&last_Tx_object[minor],	(void *)tx,	sizeof(canmsg_t));  DBGout();return i;}/* * The plain SJA1000 interrupt * *				RX ISR           TX ISR *                              8/0 byte *                               _____            _   ___ *                         _____|     |____   ___| |_|   |__ *--------------------------------------------------------------------------- * 1) CPUPentium 75 - 200 *  75 MHz, 149.91 bogomips *  AT-CAN-MINI                 42/27祍            50 祍 *  CPC-PCI		        35/26祍		    * --------------------------------------------------------------------------- * 2) AMD Athlon(tm) Processor 1M *    2011.95 bogomips *  AT-CAN-MINI  std            24/12祍            ?? 祍 *               ext id           /14祍 * *  * 1) 1Byte = (42-27)/8 = 1.87 祍 * 2) 1Byte = (24-12)/8 = 1.5  祍 * * * * RX Int with to Receive channels: * 1)                _____   ___ *             _____|     |_|   |__ *                   30    5  20  祍 *   first ISR normal length, *   time between the two ISR -- short *   sec. ISR shorter than first, why? it's the same message */#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) irqreturn_t CAN_Interrupt( int irq, void *dev_id)#elseirqreturn_t CAN_Interrupt( int irq, void *dev_id, struct pt_regs *notused)#endif{int minor;int i = 0;int rx_fifo;struct timeval  timestamp;unsigned long flags;int ext;			/* flag for extended message format */int irqsrc, dummy;msg_fifo_t   *RxFifo; msg_fifo_t   *TxFifo;#if CAN_USE_FILTERmsg_filter_t *RxPass;unsigned int id;#endif #if 1int first = 0;#endif #if CONFIG_TIME_MEASURE    outb(0xff, 0x378);  #endif    minor = *(int *)dev_id;    /* printk("CAN - ISR ; minor = %d\n", *(int *)dev_id); */    RxFifo = &Rx_Buf[minor][0];     TxFifo = &Tx_Buf[minor];#if CAN_USE_FILTER    RxPass = &Rx_Filter[minor];#endif     /* Disable PITA Interrupt */    /* writel(0x00000000, Can_pitapci_control[minor] + 0x0); */    irqsrc = CANin(minor, canirq);    if(irqsrc == 0) {         /* first call to ISR, it's not for me ! */#if LINUX_VERSION_CODE >= 0x020500 	return IRQ_RETVAL(IRQ_NONE);#else	goto IRQdone_doneNothing;#endif    }#if defined(CCPC104)	pc104_irqack();#endif    do {    /* loop as long as the CAN controller shows interrupts */    DBGprint(DBG_DATA, (" => got IRQ[%d]: 0x%0x", minor, irqsrc));    /* can_dump(minor); */    /* fill timestamp as first action.      * Getting a precises time takes a lot of time     * (additional 7 祍 of ISR time )     * if a time stamp is not needed, it can be switched of     * by ioctl() */    if (use_timestamp[minor]) {	do_gettimeofday(&timestamp);    } else {	timestamp.tv_sec  = 0;	timestamp.tv_usec = 0;    }    for(rx_fifo = 0; rx_fifo < CAN_MAX_OPEN; rx_fifo++) {	RxFifo = &Rx_Buf[minor][rx_fifo];	RxFifo->data[RxFifo->head].timestamp = timestamp;	/* preset flags */	(RxFifo->data[RxFifo->head]).flags =        		(RxFifo->status & BUF_OVERRUN ? MSG_BOVR : 0);    }#if 1    /* how often do we loop through the ISR ? */    /* if(first) printk("n = %d\n", first); */    first++;    if (first > 10) return IRQ_RETVAL(IRQ_HANDLED);#endif    /*========== receive interrupt */    if( irqsrc & CAN_RECEIVE_INT ) {    	int length;        /* printk(" CAN RX %d\n", minor); */	dummy  = CANin(minor, frameinfo );/* ---------- fill frame data -------------------------------- */    /* handle all subscribed rx fifos */    for(rx_fifo = 0; rx_fifo < CAN_MAX_OPEN; rx_fifo++) {	/* for every rx fifo */	/* printk(KERN_INFO " used fifos [%d][%d] = %d\n", minor, rx_fifo, */	    /* CanWaitFlag[minor][rx_fifo]); */	if (CanWaitFlag[minor][rx_fifo] == 1) {	    /* this FIFO is in use */	    RxFifo = &Rx_Buf[minor][rx_fifo]; /* prepare buffer to be used *//* printk(KERN_INFO "> filling buffer [%d][%d]\n", minor, rx_fifo);  */	    if( dummy & CAN_RTR ) {		(RxFifo->data[RxFifo->head]).flags |= MSG_RTR;	    }	    if( dummy & CAN_EFF ) {		(RxFifo->data[RxFifo->head]).flags |= MSG_EXT;	    }	    ext = (dummy & CAN_EFF);	    if(ext) {	        (RxFifo->data[RxFifo->head]).id =	          ((unsigned int)(CANin(minor, frame.extframe.canid1)) << 21)		+ ((unsigned int)(CANin(minor, frame.extframe.canid2)) << 13)		+ ((unsigned int)(CANin(minor, frame.extframe.canid3)) << 5)		+ ((unsigned int)(CANin(minor, frame.extframe.canid4)) >> 3);	    } else {	        (RxFifo->data[RxFifo->head]).id =        	  ((unsigned int)(CANin(minor, frame.stdframe.canid1 )) << 3)         	+ ((unsigned int)(CANin(minor, frame.stdframe.canid2 )) >> 5);	}	    /* get message length */	    length = dummy  & 0x0f;			/* strip length code */ 	    (RxFifo->data[RxFifo->head]).length = length;	    length %= 9;	/* limit count to 8 bytes */	    for( i = 0; i < length; i++) {		/* SLOW_DOWN_IO;SLOW_DOWN_IO; */		if(ext) {		    (RxFifo->data[RxFifo->head]).data[i] =			    CANin(minor, frame.extframe.canxdata[R_OFF * i]);		} else {		    (RxFifo->data[RxFifo->head]).data[i] =			    CANin(minor, frame.stdframe.candata[R_OFF * i]);		}	    }	    /* mark just written entry as OK and full */	    RxFifo->status = BUF_OK;	    /* Handle buffer wrap-around */	    RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;	    if(RxFifo->head == RxFifo->tail) {		    printk("CAN[%d][%d] RX: FIFO overrun\n", minor, rx_fifo);		    RxFifo->status = BUF_OVERRUN;	    } 	    /*---------- kick the select() call  -*/	    /* This function will wake up all processes	       that are waiting on this event queue,	       that are in interruptible sleep	    */	/* printk(KERN_INFO " should wake [%d][%d]\n", minor, rx_fifo); */	    wake_up_interruptible(&CanWait[minor][rx_fifo]); 	}    }/* ---------- / fill frame data -------------------------------- */        /* release the CAN controller now */        CANout(minor, cancmd, CAN_RELEASE_RECEIVE_BUFFER );        if(CANin(minor, canstat) & CAN_DATA_OVERRUN ) {		 printk("CAN[%d] Rx: Overrun Status \n", minor);		 CANout(minor, cancmd, CAN_CLEAR_OVERRUN_STATUS );	}   }    /*========== transmit interrupt */    if( irqsrc & CAN_TRANSMIT_INT ) {	/* CAN frame successfully sent */	u8 tx2reg;	unsigned int id;	/* use time stamp sampled with last INT */	last_Tx_object[minor].timestamp = timestamp;	/* depending on the number of open processes	 * the TX data has to be copied in different	 * rx fifos	 */	for(rx_fifo = 0; rx_fifo < CAN_MAX_OPEN; rx_fifo++) {	    /* for every rx fifo */	    if (CanWaitFlag[minor][rx_fifo] == 1) {		/* this FIFO is in use */		/* printk(KERN_INFO "self copy to [%d][%d]\n", minor, rx_fifo); */		    		/*		 * Don't copy the message in the receive queue		 * of the process that sent the message unless		 * this process requested selfreception.		 */		if ((last_Tx_object[minor].cob == rx_fifo) && 		    (selfreception[minor][rx_fifo] == 0))		{		    /* printk("CAN[%d][%d] Don't copy message in my queue\n", minor, rx_fifo); */		    continue;		}#ifdef VERBOSE		printk(		"CAN[%d][%d] Copy message from %d in queue id 0x%lx 0x%x\n",		        minor, rx_fifo,			last_Tx_object[minor].cob,			last_Tx_object[minor].id,			last_Tx_object[minor].data[0]);#endif		/* prepare buffer to be used */		RxFifo = &Rx_Buf[minor][rx_fifo];		memcpy(  		    (void *)&RxFifo->data[RxFifo->head],		    (void *)&last_Tx_object[minor],		    sizeof(canmsg_t));				/* Mark message as 'self sent/received' */		RxFifo->data[RxFifo->head].flags |= MSG_SELF;		/* increment write index */		RxFifo->status = BUF_OK;		RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;		if(RxFifo->head == RxFifo->tail) {		    printk("CAN[%d][%d] RX: FIFO overrun\n", minor, rx_fifo);		    RxFifo->status = BUF_OVERRUN;		} 		/*---------- kick the select() call  -*/		/* This function will wake up all processes		   that are waiting on this event queue,		   that are in interruptible sleep		*/		wake_up_interruptible(&CanWait[minor][rx_fifo]); 	    } /* this FIFO is in use */	} /* end for loop filling all rx-fifos */	if( TxFifo->free[TxFifo->tail] == BUF_EMPTY ) {	    /* TX FIFO empty, nothing more to sent */	    /* printk("TXE\n"); */	    TxFifo->status = BUF_EMPTY;            TxFifo->active = 0;	    /* This function will wake up all processes	       that are waiting on this event queue,	       that are in interruptible sleep	    */	    wake_up_interruptible(&CanOutWait[minor]);             goto Tx_done;	}        /* enter critical section */	local_irq_save(flags);	/* The TX message FIFO contains other CAN frames to be sent	 * The next frame in the FIFO is copied into the last_Tx_object	 * and directly into the hardware of the CAN controller	 */	memcpy(		(void *)&last_Tx_object[minor],		(void *)&TxFifo->data[TxFifo->tail],		sizeof(canmsg_t));	tx2reg = (TxFifo->data[TxFifo->tail]).length;	if( (TxFifo->data[TxFifo->tail]).flags & MSG_RTR) {		tx2reg |= CAN_RTR;	}        ext = (TxFifo->data[TxFifo->tail]).flags & MSG_EXT;        id = (TxFifo->data[TxFifo->tail]).id;        if(ext) {	    DBGprint(DBG_DATA, ("---> send ext message"));	    CANout(minor, frameinfo, CAN_EFF + tx2reg);	    CANout(minor, frame.extframe.canid1, (u8)(id >> 21));	    CANout(minor, frame.extframe.canid2, (u8)(id >> 13));	    CANout(minor, frame.extframe.canid3, (u8)(id >> 5));	    CANout(minor, frame.extframe.canid4, (u8)(id << 3) & 0xff);        } else {	    DBGprint(DBG_DATA, ("---> send std message"));	    CANout(minor, frameinfo, CAN_SFF + tx2reg);	    CANout(minor, frame.stdframe.canid1, (u8)((id) >> 3) );	    CANout(minor, frame.stdframe.canid2, (u8)(id << 5 ) & 0xe0);        }	tx2reg &= 0x0f;		/* restore length only */	if(ext) {	    for( i=0; i < tx2reg ; i++) {		CANout(minor, frame.extframe.canxdata[R_OFF * i],		    (TxFifo->data[TxFifo->tail]).data[i]);	    }        } else {	    for( i=0; i < tx2reg ; i++) {		CANout(minor, frame.stdframe.candata[R_OFF * i],		    (TxFifo->data[TxFifo->tail]).data[i]);	    }        }        CANout(minor, cancmd, CAN_TRANSMISSION_REQUEST );	TxFifo->free[TxFifo->tail] = BUF_EMPTY; /* now this entry is EMPTY */	TxFifo->tail = ++(TxFifo->tail) % MAX_BUFSIZE;        /* leave critical section */	local_irq_restore(flags);   }Tx_done:   /*========== error status */   if( irqsrc & CAN_ERROR_INT ) {   int status;   int flags = 0;	/* printk("CAN[%d]: error interrupt!\n", minor); */        TxErr[minor]++;        /* insert error */        status = CANin(minor,canstat);        if(status & CAN_BUS_STATUS ) {	    flags += MSG_BUSOFF;	    (RxFifo->data[RxFifo->head]).flags += MSG_BUSOFF; 	    /* printk(" MSG_BUSOF\n"); */        }        if(status & CAN_ERROR_STATUS) {	    flags += MSG_PASSIVE;	    (RxFifo->data[RxFifo->head]).flags += MSG_PASSIVE; 	    /* printk(" MSG_PASSIVE\n"); */        }	for(rx_fifo = 0; rx_fifo < CAN_MAX_OPEN; rx_fifo++) {	    /* for every rx fifo */	    if (CanWaitFlag[minor][rx_fifo] == 1) {		/* this FIFO is in use */		RxFifo = &Rx_Buf[minor][rx_fifo]; /* prepare buffer to be used */		(RxFifo->data[RxFifo->head]).flags += flags; 		(RxFifo->data[RxFifo->head]).id = CANDRIVERERROR;        	(RxFifo->data[RxFifo->head]).length = 0;		RxFifo->status = BUF_OK;		/* handle fifo wrap around */		RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;		if(RxFifo->head == RxFifo->tail) {		    printk("CAN[%d][%d] RX: FIFO overrun\n", minor, rx_fifo);		    RxFifo->status = BUF_OVERRUN;		} 		/* tell someone that there is a new error message */		wake_up_interruptible(&CanWait[minor][rx_fifo]); 	    }	}   }   if( irqsrc & CAN_OVERRUN_INT ) {   int status;	printk("CAN[%d]: controller overrun!\n", minor);        Overrun[minor]++;        /* insert error */        status = CANin(minor,canstat);	for(rx_fifo = 0; rx_fifo < CAN_MAX_OPEN; rx_fifo++) {	    /* for every rx fifo */	    if (CanWaitFlag[minor][rx_fifo] == 1) {		/* this FIFO is in use */		if(status & CAN_DATA_OVERRUN)		    (RxFifo->data[RxFifo->head]).flags += MSG_OVR; 		(RxFifo->data[RxFifo->head]).id = 0xFFFFFFFF;		(RxFifo->data[RxFifo->head]).length = 0;		RxFifo->status = BUF_OK;		RxFifo->head = ++(RxFifo->head) % MAX_BUFSIZE;		if(RxFifo->head == RxFifo->tail) {		    printk("CAN[%d][%d] RX: FIFO overrun\n", minor, rx_fifo);		    RxFifo->status = BUF_OVERRUN;		} 		/* tell someone that there is a new error message */		wake_up_interruptible(&CanWait[minor][rx_fifo]); 	    }	}        CANout(minor, cancmd, CAN_CLEAR_OVERRUN_STATUS );   }    } while( (irqsrc = CANin(minor, canirq)) != 0);/* IRQdone: */    DBGprint(DBG_DATA, (" => leave IRQ[%d]", minor));    board_clear_interrupts(minor);#if LINUX_VERSION_CODE < 0x020500 IRQdone_doneNothing:#endif#if CONFIG_TIME_MEASURE    outb(0x00, 0x378);  #endif    return IRQ_RETVAL(IRQ_HANDLED);}

⌨️ 快捷键说明

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