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

📄 pcan_fifo.c

📁 CAN 驱动编程
💻 C
字号:
//****************************************************************************// Copyright (C) 2001,2002,2003  PEAK System-Technik GmbH//// linux@peak-system.com// www.peak-system.com//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.//// Maintainer(s): Klaus Hitschler (klaus.hitschler@gmx.de)//****************************************************************************//****************************************************************************//// pcan_fifo.c - manages the ringbuffers for read and write data//// $Log: pcan_fifo.c,v $// Revision 1.12  2003/03/02 10:58:07  klaus// merged USB thread into main path//// Revision 1.11  2003/03/02 10:58:07  klaus// merged USB thread into main path//// Revision 1.10.2.7  2003/02/09 13:18:09  klaus// modifications to support linux 2.2.19 kernels//// Revision 1.10.2.6  2003/02/09 13:18:09  klaus// modifications to support linux 2.2.19 kernels//// Revision 1.10.2.5  2003/01/29 20:34:20  klaus// release_20030129_a and release_20030129_u released//// Revision 1.10.2.4  2003/01/29 20:34:20  klaus// release_20030129_a and release_20030129_u released//// Revision 1.10.2.3  2003/01/28 23:28:26  klaus// reorderd pcan_usb.c and pcan_usb_kernel.c, tidied up//// Revision 1.10.2.2  2003/01/08 22:21:48  klaus// fixed version 1.3 problem, write has still a deadlock////****************************************************************************//****************************************************************************// INCLUDES#include <src/pcan_common.h> #include <linux/types.h>#include <linux/errno.h>    // error codes#ifdef LINUX_22#include <asm/system.h>     // cli(), save_flags(), restore_flags()#endif#include <linux/spinlock.h> // <asm/spinlock.h>, where are the diffs?#include <src/pcan_fifo.h> //****************************************************************************// DEFINES//****************************************************************************// GLOBALS//****************************************************************************// LOCALS//****************************************************************************// CODE  int pcan_fifo_reset(register FIFO_MANAGER *anchor){  spin_lock_irqsave(&anchor->lock, anchor->flags);	anchor->dwTotal       = 0; 	anchor->nStored       = 0; 	anchor->r = anchor->w = anchor->bufferBegin; // nothing to read  anchor->bPutClaimed   = 0;  anchor->bGetClaimed   = 0;	spin_unlock_irqrestore(&anchor->lock, anchor->flags);  // DPRINTK(KERN_DEBUG "%s: pcan_fifo_reset() %d %p %p %d\n", DEVICE_NAME, anchor->nStored, anchor->r, anchor->w, anchor->bGetClaimed);  return 0;}int pcan_fifo_init(register FIFO_MANAGER *anchor, void *bufferBegin, void *bufferEnd, int nCount, u16 wCopySize){	anchor->wCopySize   = wCopySize;	anchor->wStepSize   = (bufferBegin == bufferEnd) ? 0 : ((bufferEnd - bufferBegin) / (nCount - 1));	anchor->nCount      = nCount;	anchor->bufferBegin = bufferBegin;	anchor->bufferEnd   = bufferEnd;	anchor->flags       = 0;		// check for fatal program errors	if ((anchor->wStepSize < anchor->wCopySize) || (anchor->bufferBegin > anchor->bufferEnd) || (nCount <= 1))	  return -EINVAL;		spin_lock_init(&anchor->lock);  return pcan_fifo_reset(anchor);}//----------------------------------------------------------------------------// the functiony claim and ..put or ..get are always a timingly narrow related// pair. Never there should be a .._claim_.. without a .._put or .._get! int pcan_fifo_claim_for_put(register FIFO_MANAGER *anchor, void **pvPutData){  int err = 0;    if (anchor->bPutClaimed)    err = EAGAIN;  else  {    spin_lock_irqsave(&anchor->lock, anchor->flags);      if (anchor->nStored < anchor->nCount)    {      anchor->bPutClaimed = 1;      *pvPutData = anchor->w;    }    else    {	    spin_unlock_irqrestore(&anchor->lock, anchor->flags);        *pvPutData = NULL;      err = -ENOSPC;    }  }    return err;}int pcan_fifo_put(register FIFO_MANAGER *anchor){  // DPRINTK(KERN_DEBUG "%s: pcan_fifo_put() %d %p %p %d\n", DEVICE_NAME, anchor->nStored, anchor->r, anchor->w, anchor->bPutClaimed);  if (!anchor->bPutClaimed)    return -EDEADLOCK;  anchor->nStored++;  anchor->dwTotal++;  if (anchor->w < anchor->bufferEnd)    anchor->w += anchor->wStepSize;   // increment to next  else    anchor->w = anchor->bufferBegin;  // start from begin  	anchor->bPutClaimed = 0; 	spin_unlock_irqrestore(&anchor->lock, anchor->flags); 	  return 0;}int pcan_fifo_put_reject(register FIFO_MANAGER *anchor){  // DPRINTK(KERN_DEBUG "%s: pcan_fifo_put_reject() %d %p %p %d\n", DEVICE_NAME, anchor->nStored, anchor->r, anchor->w, anchor->bPutClaimed);  if (!anchor->bPutClaimed)    return -EDEADLOCK;	anchor->bPutClaimed = 0; 	spin_unlock_irqrestore(&anchor->lock, anchor->flags); 	  return 0;}//----------------------------------------------------------------------------// the functiony claim and ..put or ..get are always a timingly narrow related// pair. There should never be a .._claim_.. without a .._put or .._get! int pcan_fifo_claim_for_get(register FIFO_MANAGER *anchor, void **pvGetData){  int err = 0;    if (anchor->bGetClaimed)    err = EAGAIN;  else  {    spin_lock_irqsave(&anchor->lock, anchor->flags);      if (anchor->nStored > 0)    {       anchor->bGetClaimed = 1;       *pvGetData = anchor->r;    }    else    {	    spin_unlock_irqrestore(&anchor->lock, anchor->flags);      *pvGetData = NULL;	    err = -ENODATA;    }  }    return err;}int pcan_fifo_get(register FIFO_MANAGER *anchor){  // DPRINTK(KERN_DEBUG "%s: pcan_fifo_get() %d %p %p %d\n", DEVICE_NAME, anchor->nStored, anchor->r, anchor->w, anchor->bGetClaimed);  if (!anchor->bGetClaimed)    return -EDEADLOCK;      anchor->nStored--;  if (anchor->r < anchor->bufferEnd)    anchor->r += anchor->wStepSize;  // increment to next     else    anchor->r = anchor->bufferBegin; // start from begin  	anchor->bGetClaimed = 0; 	spin_unlock_irqrestore(&anchor->lock, anchor->flags);	  return 0;}int pcan_fifo_get_reject(register FIFO_MANAGER *anchor){  // DPRINTK(KERN_DEBUG "%s: pcan_fifo_get_reject() %d %p %p %d\n", DEVICE_NAME, anchor->nStored, anchor->r, anchor->w, anchor->bGetClaimed);  if (!anchor->bGetClaimed)    return -EDEADLOCK;    	anchor->bGetClaimed = 0; 	spin_unlock_irqrestore(&anchor->lock, anchor->flags);	  return 0;}//----------------------------------------------------------------------------// returns the current count of elements in fifoint pcan_fifo_status(FIFO_MANAGER *anchor){  return anchor->nStored;}//----------------------------------------------------------------------------// returns 0 if the fifo is fullint pcan_fifo_near_full(FIFO_MANAGER *anchor){  return (anchor->nStored < (anchor->nCount - 1));} //----------------------------------------------------------------------------// returns 0 if the fifo is emptyint pcan_fifo_empty(FIFO_MANAGER *anchor){  return anchor->nStored;}

⌨️ 快捷键说明

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