?? cpcimultiint.c
字號:
/**********************************************************************
chengjy@felab, copyright 2002-2004
cpciMultiInt.c
函數:
void f9656Init();
void f9656IntFunc(int intIndex);
void f9656IntHandle(int boardNum);
void f9656ShutDown();
調用: 無
被調用: 硬件響應底層函數,被命令通道調用
說明: 本文件與硬件關聯緊密,僅為中斷響應的框架,
需要根據實際情況添加中斷響應和處理代碼才能使用
**********************************************************************/
#include "vxWorks.h"
#include "logLib.h"
#include "arch/ppc/ivPpc.h"
#include "intLib.h"
#include "taskLib.h"
#include "semLib.h"
#include "string.h"
#include "cpciMultiInt.h"
#if 0 /*不打印9656中斷信息*/
#define F9656LOG(a,b,c,d,e,f,g) ; /*帶6個參數的logMsg*/
#define F9656PRINT1(x) ; /*沒有參數的printf*/
#define F9656PRINT2(x,y) ; /*帶一個參數的printf*/
#else
#define F9656LOG(a,b,c,d,e,f,g) ; /*logMsg((a),(b),(c),(d),(e),(f),(g))*/
#define F9656PRINT1(x) printf(x)
#define F9656PRINT2(x,y) printf((x),(y))
#endif
struct pciBoardIndex pciBoard[MAX_BOARD_SUPPORT];
struct pciIntIndex pciInt[MAX_INT_SUPPORT];
int pciBoardNum; /*實際使用的pci板的數目,從0開始*/
void f9656Init();
void f9656IntFunc(int intIndex);
void f9656IntHandle(int boardNum);
void f9656ShutDown();
/**********************************************************************
void f9656Init()
函數描述: 9656初始化,創建信號燈,發起服務任務,
計算基地址,掛接中斷。
參數: 無
返回: 無
調用: void f9656IntFunc(int intIndex);
void f9656IntHandle(int boardNum);
被調用: 用戶程序初始化部分
命令通道的命令
**********************************************************************/
void f9656Init()
{
int busNo,deviceNo,funcNo;
int intIndex;
int intNum;
int i,j;
STATUS state;
char taskName[30];
/*需要避免重入的控制*/
/*初始化每塊插板信息*/
for(i=0;i<MAX_BOARD_SUPPORT;i++)
{
/*首先全部設置為0*/
pciBoard[i].pcimem0 = 0;
pciBoard[i].pcimem1 = 0;
pciBoard[i].intNum = 0xFF;
pciBoard[i].intTimes = 0;
}
/*初始化*/
for(pciBoardNum=0;pciBoardNum<MAX_BOARD_SUPPORT;pciBoardNum++)
{
/*尋找9656*/
if(pciFindDevice(PCI_F9656_VENDOR_ID,PCI_F9656_DEVICE_ID,pciBoardNum,&busNo,&deviceNo,&funcNo)!=OK)
{
break;
}
logMsg("f9656Init: pci device, vendor 0x%x,device 0x%x, index 0x%x\n",PCI_F9656_VENDOR_ID,PCI_F9656_DEVICE_ID,pciBoardNum,0,0,0);
/*mem基地址*/
pciConfigInLong(busNo,deviceNo,funcNo,0x10,&(pciBoard[pciBoardNum].pcimem0));
pciBoard[pciBoardNum].pcimem0 = (UINT)PCIMEM2CPU(pciBoard[pciBoardNum].pcimem0&(~0xf));
pciConfigInLong(busNo,deviceNo,funcNo,0x18,&(pciBoard[pciBoardNum].pcimem1));
pciBoard[pciBoardNum].pcimem1 = (UINT)PCIMEM2CPU(pciBoard[pciBoardNum].pcimem1&(~0xf));
/*中斷號*/
pciConfigInByte(busNo,deviceNo,funcNo,0x3C,&(pciBoard[pciBoardNum].intNum));
pciBoard[pciBoardNum].intNum = CPCIINT2CPU(pciBoard[pciBoardNum].intNum);
/*板號,可以通過9656的首部寄存器或者memory 1 某個地址的值不同來區分,
這里為了簡便直接賦值為pciBoardNum+1*/
pciBoard[pciBoardNum].index = pciBoardNum+1;
logMsg("f9656Init: memBase: 0x%8x,0x%8x,intNum 0x%x\n",
pciBoard[pciBoardNum].pcimem0,pciBoard[pciBoardNum].pcimem1,pciBoard[pciBoardNum].intNum,0,0,0);
}
/*如果沒有找到任何cpci 器件,退出*/
if(pciBoardNum==0)
{
logMsg("f9656Init: no cpci board found, now exit\n",0,0,0,0,0,0);
return;
}
/*沒有找到cpci器件的中斷index,對應的enable全部為0*/
for(i=0;i<MAX_INT_SUPPORT;i++)
{
pciInt[i].enable = 0;
}
for(i=0;i<pciBoardNum;i++)
{
/*某個中斷相應位上的1表示對應有插板使用此中斷*/
intIndex = INT_NUM2INDEX(pciBoard[pciBoardNum].intNum);
pciInt[intIndex].enable = (pciInt[intIndex].enable | (0x01<<i));
}
/*逐個使能中斷*/
for(intIndex=0;intIndex<MAX_INT_SUPPORT;intIndex++)
{
if(pciInt[intIndex].enable!=0)
{
intNum = INT_INDEX2NUM(intIndex);
F9656LOG("f9656Init: int number: 0x%x connected\n",intNum,0,0,0,0,0);
state = intConnect((INUM_TO_IVEC(intNum)),f9656IntFunc,intIndex);
if(state!=OK)
logMsg("f9656Init: error in intConnect\n",0,0,0,0,0,0);
intEnable(intNum);
}
}
/*逐個初始化插板*/
for(i=0;i<pciBoardNum;i++)
{
/*創建信號燈*/
pciBoard[i].semPci = semCCreate(SEM_Q_FIFO,SEM_EMPTY);
if(pciBoard[i].semPci == NULL)
{
logMsg("f9656Init: unable to create semF9656\n",0,0,0,0,0,0);
exit(-1);
}
/*發起相應的處理函數*/
sprintf(taskName,TNAME_F9656INTHDL,"%d",i);
taskSpawn(taskName,TPRI_F9656INTHDL,0,USER_STACK_SIZE,(FUNCPTR)f9656IntHandle,i,0,0,0,0,0,0,0,0,0);
}
}
/**********************************************************************
void f9656IntFunc(int intIndex)
函數描述: 中斷服務程序,掛接到9656中斷,中斷時自動被
調用。具體工作由f9656IntHandle() 完成,使用各板的
semPci 同步。此函數中的清中斷機制直接針對硬件,
如果使用9656之外的其它pci橋片,請參閱芯片的datasheet.
參數: index, 產生的中斷的index,取值范圍從0 到3.
返回: 無
調用: 無
被調用: void f9656Init()
**********************************************************************/
void f9656IntFunc(int intIndex)
{
int intNum;
UINT regValue;
int pciIndex;
intNum = INT_INDEX2NUM(intIndex);
/*屏蔽中斷*/
intDisable(intNum);
F9656LOG("f9656IntFunc: interrupt received\n",0,0,0,0,0,0);
/*獲取中斷的板號*/
for(pciIndex=0;pciIndex<MAX_BOARD_SUPPORT;pciIndex++)
{
if((pciInt[intIndex].enable&(0x01<<pciIndex))!=0)
{
/*逐個判斷可能產生此中斷的cpci 插板是否已經產生了中斷*/
regValue = *F9656MEM2CPU0(0x68,pciIndex);
if((regValue&0x00002000)!=0)
{
/*清 單板的中斷標志*/
*F9656MEM2CPU0(0xA8,pciIndex) = 0x18000000;
/*釋放信號燈,通知f9656IntHandle 開始處理*/
semGive(pciBoard[pciIndex].semPci);
}
}
}
/*允許響應其它使用此中斷號的插板的中斷*/
intEnable(intNum);
}
/**********************************************************************
void f9656IntHandle(int boardNum)
函數描述: 中斷后的實際任務處理函數,中斷服務程序
并不執行大量工作,只是通知此函數。
參數: boardNum, 產生中斷的板的cpci 號,取值范圍0~7
返回: 無
調用: void f9656ShutDown()
被調用: void f9656Init()
**********************************************************************/
void f9656IntHandle(int boardNum)
{
while(1)
{
if(semTake(pciBoard[boardNum].semPci,WAIT_FOREVER)!=OK)
{
logMsg("f9656IntHandle: error in semTake %d\n",boardNum,0,0,0,0,0);
break;
}
/*成功獲取信號燈,說明該板產生了一次中斷*/
pciBoard[boardNum].intTimes++;
/*防止過界*/
if(pciBoard[boardNum].intTimes==0x1000000)
pciBoard[boardNum].intTimes = 0;
/*允許9656 再次傳送數據到零槽*/
}
/*出錯退出*/
logMsg("f9656IntHandle: something wrong, now exit\n",0,0,0,0,0,0);
f9656ShutDown();
}
/**********************************************************************
void f9656ShutDown()
函數描述: 關閉9656 的操作,主要是解決一些在SHELL 下重復
使用F9656Init()的信號燈沒有刪除的問題,在這里
刪除信號燈以及中斷后的處理函數。
參數: 無
返回: 無
調用: 無
被調用: void f9656IntHandle(int boardNum)
用戶在shell下調用
命令通道的某個命令
**********************************************************************/
void f9656ShutDown()
{
int i;
int intIndex;
char taskName[30];
/*需要添加避免重入的判斷*/
/*按中斷index 0~3 關閉中斷*/
for(intIndex=0;intIndex<4;intIndex++)
{
intDisable(INT_INDEX2NUM(intIndex));
}
/*按插板index 0~7結束任務*/
for(i=0;i<pciBoardNum;i++)
{
/*刪除中斷服務任務*/
sprintf(taskName,TNAME_F9656INTHDL,"%d",i);
/*如果是被f9656IntHandle()調用,自己會退出,否則必須刪除任務*/
if(taskNameToId(taskName)!=taskIdSelf())
{
taskDelete(taskNameToId(taskName));
F9656LOG("f9656ShutDown:%d deleted\n",i,0,0,0,0,0);
}
/*刪除信號燈*/
semDelete(pciBoard[i].semPci);
}
logMsg("f9656ShutDown:9656 shut down now\n",0,0,0,0,0,0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -