vxworks求助(关于pci配置和存储器映射)
刚学vxworks不久,用的开发环境是tornado5.5,最近想使用一个pci的8串口板,设备是映射到存储器空间的而不是IO空间,硬件环境是PC104+,pci配置方式是动态配置,代码如下:
#include "vxworks.h"
#include "tasklib.h"
#include "syslib.h"
#include "config.h"
#include "vmlib.h"
#include "drv/pci/pciConfigLib.h"
#define xxx_DEBUG /*这里定义每一个VID和DID*/
#define xxx_VENDOR_ID 0x13A8
#define xxx_DEV_ID 0x0158
#define xxxUNKNOWN 0
#define xxx_MAX_UNITS 1 /*每一个板卡的资源*/
typedef struct xxxResource /* xxx_RESOURCE */
{
int BoardVID;
int BoardDID;
int unitInx;
} xxx_RESOURCE;
/*板卡资源的定义,这里以相同的板卡为例子
板卡如果相同的话unitInx逐次递增,如果不同
的话则从零开始*/
LOCAL xxx_RESOURCE xxxRes [xxx_MAX_UNITS] =
{
{xxx_VENDOR_ID, xxx_DEV_ID, 0},
};
/*这里就是PCI初始化部分了*/
void xxxPciInit (void)
{
xxx_RESOURCE *pReso;
int pciBus;
int pciDevice;
int pciFunc;
int unit;
int iCommand;
BOOL duplicate;
UINT32 membaseCsr;
UINT32 r_membase;/*用于计算地址映射的空间*/
char irq;
int ix;
for (unit = 0; unit < xxx_MAX_UNITS; unit++)
{
/*寻找板卡*/
if (pciFindDevice (xxxRes[unit].BoardVID, xxxRes[unit].BoardDID,
xxxRes[unit].unitInx, &pciBus, &pciDevice, &pciFunc) != OK)
break;
pReso = &xxxRes [unit];
/* PCI_CFG_TYPE can be defined to PCI_CFG_NONE,PC_CFG_AUTO,or PCI_CFG_FORCE.*/
/* 在X86下,BIOS会分配好资源的,所以不需要再配置了*/
for(ix=0; ix<6; ix++)/*总共是6个地址*/
{
pciConfigInLong (pciBus, pciDevice, pciFunc,
PCI_CFG_BASE_ADDRESS_0 + 0x04 * ix, &membaseCsr); /*读回地址内容*/
/*首先需要判断是内存还是端口,如果不是端口就映射*/
if(!(membaseCsr&PCI_BAR_SPACE_IO))
{
/*首先,需要判断所需内存的大小
根据PCI的规范,将内容写回就可以得到大小*/
pciConfigOutLong (pciBus, pciDevice, pciFunc,
PCI_CFG_BASE_ADDRESS_0 + 0x04 * ix, 0xffffffff);
pciConfigInLong (pciBus, pciDevice, pciFunc,
PCI_CFG_BASE_ADDRESS_0 + 0x04 * ix, &r_membase);
r_membase &= PCI_MEMBASE_MASK; /*现在r_membase就是长度了*/
/*再把地址写回去*/
pciConfigOutLong (pciBus, pciDevice, pciFunc,
PCI_CFG_BASE_ADDRESS_0 + 0x04 * ix, membaseCsr);
membaseCsr &= PCI_MEMBASE_MASK;
#ifdef xxx_DEBUG
/*如果现在是调试阶段,则不用映射,继续下一个*/
printf("\nmemory space is : 0x%x", membaseCsr);
printf("\nlength is : 0x%x", r_membase);
continue;
#endif
/*此时就可以将内存映射过去了*/
if (sysMmuMapAdd((void *)membaseCsr, r_membase,
VM_STATE_MASK_FOR_ALL,
VM_STATE_FOR_PCI) == ERROR)
break;
}
}
}
}
将这个文件保存在bsp目录下,然后在syslib.c里包含,在函数sysHwInit()里调用,
该代码来自所买的参考书,现在的问题是:
1、如果配置成功,和pc104连接的显示器上会打印出memory is 。。。和length is。。,可是屏幕上没有出现
2、如果对pci设备存储器空间进行地址映射后,如何使用这个地址,配置函数没有显示哪里可以将指针传出去?
3、如果屏幕上没有打印出配置结果,是不是打印到别的地方了?
4、我把这个函数放到usrAppInit()中运行,显示能够找到设备,读出pci的基地址是0xffeb1f000,地址长度为0xfffff000,地址超出了我的pc104实际内存,显然不对,这是为什么?
请高手帮忙解答,很纠结。。。。。
还有,如何配置pci设备,配置后如何使用?
[解决办法]
sysHwInit中STD都还没有初始化,肯定是打印不出来的。
要等到串口或者PCCONSOLE初始化之后,打印才会出来。
[解决办法]
楼上正解!
sysMmuMapAdd必须在MMU初始化前调用(也就sysHwInit()内调用),你调用的位置是对的,但那时候printf不好用。
可以在vxworks启动后,再打印看一下。通过全局变量就可以使用基地址。(定义在驱动文件的初始处)