请教各位关于RESOURCE MANAGER的问题

我先在注册好RESOURCE MANAGER之后,用open打开的时候返回值总是-1;
不知道是哪里出了问题。

还有一个问题是call back函数,io_ctl怎么写,谢谢大家了!


写下是程序
main(int argc, char *argv)
{
/
declare variables we’ll be using */
thread_pool_attr_t pool_attr;
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
thread_pool_t *tpp;
dispatch_context_t *ctp;
int id;

///////////////////////////
initpci();

///////////////////////////

/* initialize dispatch interface */
if((dpp = dispatch_create()) == NULL) {
fprintf(stderr, “%s: Unable to allocate dispatch handle.\n”,
argv[0]);
return EXIT_FAILURE;
}

/* initialize resource manager attributes */
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;

/* initialize functions for handling messages */
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);
io_funcs.devctl= io_devctl;

/* initialize attribute structure used by the device */
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

/* attach our device name /
id = resmgr_attach( dpp, /
dispatch handle /
&resmgr_attr, /
resource manager attrs /
“/dev/c429”, /
device name /
_FTYPE_ANY, /
open type /
0, /
flags /
&connect_funcs, /
connect routines /
&io_funcs, /
I/O routines /
&attr); /
handle */
if(id == -1) {
fprintf(stderr, “%s: Unable to attach name.\n”, argv[0]);
return EXIT_FAILURE;
}

/* initialize thread pool attributes */
memset(&pool_attr, 0, sizeof pool_attr);
pool_attr.handle = dpp;
pool_attr.context_alloc = (void *) dispatch_context_alloc;
pool_attr.block_func = (void *)dispatch_block;
pool_attr.handler_func = (void *)dispatch_handler;
pool_attr.context_free = (void *)dispatch_context_free;
pool_attr.lo_water = 2;
pool_attr.hi_water = 4;
pool_attr.increment = 1;
pool_attr.maximum = 50;

/* allocate a thread pool handle */
if((tpp = thread_pool_create(&pool_attr,
POOL_FLAG_EXIT_SELF)) == NULL) {
fprintf(stderr, “%s: Unable to initialize thread pool.\n”,
argv[0]);
return EXIT_FAILURE;
}

/* start the threads, will not return */
thread_pool_start(tpp);
}
//可以确定初始化pci这部分得到的结果是正确的
int initpci(){
///////init Yo pci find resource and irq ;
///////
unsigned did, vid, busnum, devfuncnum ;
int phdl;
int iRet, index;
int pidx;
int count ;

void* hdl;
char* buff;
//int irq;
uint64_t port;
uint64_t mem;
c429pcic_t c429pcip;

phdl=pci_attach(0);

if( phdl == -1 ){
printf( “Unable to initialize PCI\n”);
exit(0);
}
ghC429Server = phdl;
index=0;
do{
iRet = pci_find_device(C429Deviceid,C429Vendorid, index++, &busnum, &devfuncnum);
if(iRet == PCI_SUCCESS)
{
// printf( “Found our device\n”);
break;
}
} while(iRet != PCI_DEVICE_NOT_FOUND);

if(iRet != PCI_SUCCESS){
printf(“Couldn’t find the device\n”);
/* Disconnect from the PCI server */
pci_detach( phdl );
exit(0);
}

/* Initialize the pci_dev_info structure */
memset(&c429pcip,0,sizeof(c429pcip));
memset(&gC429DevInfo, 0, sizeof(gC429DevInfo));
pidx = 0;
gC429DevInfo.VendorId = C429Vendorid;
gC429DevInfo.DeviceId = C429Deviceid;
hdl = pci_attach_device( NULL, PCI_SHARE, pidx, &gC429DevInfo );

if (hdl == NULL){
printf(“unable to locate adapter\n”);
pci_detach(phdl);
ghC429Server=0;
exit(0);
}
else{
ghC429Device = hdl;
}

//do something i like ,show the ioport and memport

for(count=0;count <6;count++){
// printf ("count =%d ",count);
if(PCI_IS_MEM(gC429DevInfo.PciBaseAddress[count])){
mem = PCI_MEM_ADDR(gC429DevInfo.PciBaseAddress[count]);
// printf( “Mem addr 0x%x, 0x%x\n”,(int)mem,gC429DevInfo.BaseAddressSize[count]);

}
else if(PCI_IS_IO(gC429DevInfo.PciBaseAddress[count])){
port = (PCI_IO_ADDR(gC429DevInfo.PciBaseAddress[count]));
// printf(“IoPort : 0x%x, 0x%x\n”, port,gC429DevInfo.BaseAddressSize[count]);
ioport = mmap_device_io(gPciDevInfo.BaseAddressSize[count], port);
if(ioport == (unsigned long) MAP_FAILED)
{
printf( “Error: failed to map dev io\n”);
}
// else printf(“io is %x\n”,ioport);

}
}//for
iRet = ThreadCtl(_NTO_TCTL_IO, 0);

//printf(“value: %x \n”,in32(ioport+0));





irq=gC429DevInfo.Irq;
// printf(“interrupt; 0x%x\n” ,irq);
// printf(“vendor:%x”,gC429DevInfo.VendorId);


if(iRet == -1){
printf(“Failed to gain IO privilege\n”);
}
// else printf(“gain IO privelege\n”);

}


int closepci(){

pci_detach_device(ghC429Device);
ghC429Device = NULL;
// Disconnect from the PCI server
pci_detach( ghC429Server );
ghC429Server = 0;
}



//这就是回调函数,它应该怎么写
int io_devctl(resmgr_context_t *ctp,io_devctl_t *msg,RESMGR_OCB_T *ocb)
{
long dcmd ,cmd;
int error;
pctl_c429 pctlc429= _DEVCTL_DATA(msg->i);
unsigned char *addrmem, *addrio;
int iRet;
int nbytes,status;

printf(“io_devctl in \n”);

iRet=ThreadCtl(_NTO_TCTL_IO,0);
if(iRet==-1){
printf(“no privati \n”);
}

if ((status = iofunc_devctl_default(ctp, msg, ocb)) != _RESMGR_DEFAULT) {
return(status);
}
status = nbytes = 0;
if ( ( error = iofunc_devctl(ctp, msg, ocb, ocb->attr ) ) != _RESMGR_DEFAULT )
return error;
resmgr_msgread(ctp, pctlc429, sizeof(Ctl_c429), sizeof(msg->i));
addrmem = mmap_device_memory(NULL, 0x1f,PROT_READ|PROT_WRITE|PROT_NOCACHE, 0,mem_base_addr);
dcmd = msg->i.dcmd;
printf(" what 's your command: %d \n",pctlc429->cmd );
switch( dcmd ) {
case DCMD_C429:
printf(“DCMD_C429”);
cmd=pctlc429->cmd;
switch(cmd)
{ case IOCTL_C429_READ_REGISTER_ULONG:
pctlc429->longdata=in32(ioport+pctlc429->offset);
nbytes=sizeof (Ctl_c429);
resmgr_msgwrite(ctp,pctlc429,sizeof(Ctl_c429),sizeof(msg->o));
break;
case IOCTL_C429_WRITE_REGISTER_ULONG:
out32(ioport+pctlc429->offset,pctlc429->longdata);
nbytes=0;
break;

default: printf(“c429 default\n”);
}
}

addrmem=NULL;
addrio=NULL;

memset(&msg->o, 0, sizeof(msg->o));
munmap_device_memory(addrmem,0x1f);
msg->o.nbytes = nbytes ;
return _RESMGR_PTR(ctp, &msg->o, sizeof(msg->o) + nbytes);
}

我用
h429=open("/dev/c429",O_RDWR | O_NONBLOCK);
printf("%d",h429);(h429打印出来是-1);
现在我搞不清出可能是哪错了,无从下手,请各位大侠帮忙!

下次如果贴源码的话,请在前后加 (用方括号代替尖括号),或者直接按那个“Code“按钮。

要查错的第一步,是看看出错代码是什么。

if ((h429=open("/dev/c429",O_RDWR | O_NONBLOCK)) == -1) {
    perror("open");
}

然后看你这个是什么设备,可以用S_IFCHR, S_IFBLK, 或者至少用S_IFREG来代替S_IFNAM。IFNAM是有特殊意义的。

那个 POOL_FLAG_EXIT_SELF,恐怕要改成POOL_FLAG_USE_SELF,否则,你的程序会自动退出吧。

在资源管理器启动后,可以ls /dev/看一下,有没有看到你的 /dev/c429?

谢谢xtang先生,我照你说的把代码改了,运行结果是not find device,请问有可能是在哪里出了问题,还有您说的指令我运行了,但是太长没看全,怎么能把运行结果放到一个文本里看呢,thanx a lot!

谢谢xtang先生,我照你说的把代码改了,运行结果是not find device,请问有可能是在哪里出了问题,还有您说的指令我运行了,但是太长没看全,怎么能把运行结果放到一个文本里看呢,thanx a lot!

ls /dev > /tmp/lsoutput.txt

或者:ls /dev/c429

你把那个 POOL_FLAG_EXIT_SELF改掉了吗?

还有,你的 open()的程序跟你的资源管理器,不是同一个进程吧。

POOL_FLAG_EXIT_SELF我看了,但是没有改,那个函数是当你调用thread_pool_start(tpp)时,就return。
您的意思是open()和资源管理器不能在一个进程里么?
那我再试试!谢谢!

我试了,txt文档中没有我注册的设备c429,我写了个test.c程序,在这个程序中写了个open()函数,在原程序中删除了open()函数,在终端运行程序的时候,我先运行了原程序,然后又运行了test.c这个程序,open()函数的返回值同样是-1.在qnx系统中是否是在配置resmgr——attach()函数在第三个参数写出device name后,就可以用open()打开,获得控制这个设备的句柄么?

xtang先生,我根据您所说的改了,现在问题解决了,请问qnx是怎么样找到pci设备的,是qnx系统枚举,根据deviceid和venderid找到的么?

不是,文档的这段不容易看清。我也上过当。

如果是 “USE_SELF”,很好理解,pool_start()就不返回了。如果是 _EXIT_SELF,是说调用后,调用线程会exit(不是return,是exit)。如果你在main()里调用 pool_start()的话,你的程序就退出了。

如果希望调用 pool_start()并返回,这个标志就写个0就可以了。

PCI服务器是负责PCI设备的枚举与资源分配的。在x86上,这是由pci-bios进程完成的。(实际的资源分配由BIOS做)

一般驱动,应用,通过pci_*函数,同PCI服务器通讯来得到具体设备的资源。

在pci_attach_device()之后,
在pci_dev_info这个结构体中无法读出pci板卡的信息,请问可能是哪里出的问题。
xtang先生您的回复我看了,再次谢谢!