📄 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 + -