vxWorks6.9 vxbIntDynaCtlrLib的匹配bug

vxWorks6.9 vxbIntDynaCtlrLib的匹配bug

问题描述

在使用vxWorks6.9的vxbIntDynaCtlrLib库时,发现调用_func_vxbIntDynaConnect链接的isr没有挂接到指定的中断控制器的中断向量结构体上,而是挂接到了同名的unitNumber为0的中断控制器上

问题定位

STATUS (* _func_vxbIntDynaConnect) (VXB_DEVICE_ID, int, struct vxbIntDynaVecInfo *);

_func_vxbIntDynaConnect为一个函数指针,指向函数vxbIntDynaConnect

STATUS vxbIntDynaConnect(VXB_DEVICE_ID pDev,int vecCount, struct vxbIntDynaVecInfo * pDynaVecIntr);

第一个参数指向设备结构体,第二个参数需要挂接的中断向量个数,第三个参数为指向的中断向量信息结构体指针

struct vxbIntDynaVecInfo
    {
    void (*isr)(void *  ISR);
    void *              pArg;
    UINT64              vecAddr;
    UINT32              vecVal;
    UINT32              inputPin;
    UINT32              vecType;
    UINT32              index;
    UINT32              count;
    };

发现在struct vxbIntDynaVecInfo中有一个为index的成员,但是实际上并没有使用这个成员,通过下面可以看出

info.found    = FALSE;
info.pIntCtlr = NULL;
info.inputPin = VXB_INTR_DYNAMIC;
info.pDev     = pDev;
info.index    = 0;
info.pIsr     = pDynaVecIntr->isr;
info.pArg     = pDynaVecIntr->pArg;

vxbDevIterate (vxbDynaIntCtlrMatch, &info, VXB_ITERATE_INSTANCES);

在通过vxBus进行中断控制器的匹配时,index参数直接赋值为0,我们再看vxbDynaIntCtlrMatch函数

LOCAL STATUS vxbDynaIntCtlrMatch
    (
    struct vxbDev *	pInst,
    void *		pArg
    )
    {
    struct vxbintCtlrMgmt * pInfo = (struct vxbintCtlrMgmt *) pArg;
    FUNCPTR func;

    if (pInfo->found)
        return (OK);

    func = vxbDevMethodGet (pInst, DEVMETHOD_CALL(vxbIntDynaVecConnect));

    if (func == NULL)
        return (OK);

    pInfo->found = TRUE;

    pInfo->pIntCtlr = pInst;

    return (OK);
    }

该函数直接获取vxbIntDynaVecConnect方法,如果获取到pInfo->found = TRUE,直接返回,因此,如果有两个同名中断控制器,但是unitNumber不同的情况下,总是会将第一个返回

解决思路

1. 可以把vxbIntDynaVecInfo.index参数带入unitNumber信息,修改vxbIntDynaConnect函数

info.found    = FALSE;
info.pIntCtlr = NULL;
info.inputPin = VXB_INTR_DYNAMIC;
info.pDev     = pDev;
info.index    = pDynaVecIntr->index;
info.pIsr     = pDynaVecIntr->isr;
info.pArg     = pDynaVecIntr->pArg;

在vxbDynaIntCtlrMatch函数中进行匹配

func = vxbDevMethodGet (pInst, DEVMETHOD_CALL(vxbIntDynaVecConnect));

if (func == NULL)
return (OK);

if(pInst->unitNumber != pInfo->index)
return (Ok);

pInfo->found = TRUE;

pInfo->pIntCtlr = pInst;

这样虽然能解决问题,但是确需要在PCI总线控制器中指定中断控制器unitNumber,不符合分层的概念,修改不方便

2. 在vxbDynaIntCtlrMatch函数中调用中断控制器的MatchCallBack方法(属于自定义方法),由中断控制器自己判断是否匹配

func = vxbDevMethodGet (pInst, DEVMETHOD_CALL(vxbIntDynaVecConnect));

if (func == NULL)
return (OK);

func = vxbDevMethodGet (pInst, DEVMETHOD_CALL(vxbIntDynaVecMatchCallBack));

if (func != NULL)
{
    if((*func)(pInst, pArg) == OK)
    {
        pInfo->found = TRUE;
		pInfo->pIntCtlr = pInst;
    }
    return (ok);
}

pInfo->found = TRUE;

pInfo->pIntCtlr = pInst;

在vxbIntDynaVecConnect.c中添加:

DEVMETHOD_DEF(vxbIntDynaVecMatchCallBack, "Dynamic Vector Match Call Back");

在中断控制器中添加一个方法:

METHOD_DECL(vxbIntDynaVecMatchCallBack)

LOCAL device_method_t xxIntCtlr_methods[] =
{
  ...
      DEVMETHOD(vxbIntDynaVecMatchCallBack, vxbxxIntDynaVecMatchCallBack),
  ...
};
LOCAL STATUS vxbxxIntDynaVecMatchCallBack(VXB_DEVICE_ID pIntCtlr, void * pArg)
{
    pVXB_xx_INT_DRV_CTLR pDrvCtlr = pIntCtlr->pDrvCtrl;
    
    /*该处采用驱动中的msiEnable进行判断,该变量在instinit时通过获取hwconf赋值*/
    return (pDrvCtlr->msiEnable?OK:ERROR);
}

hwconf.c

const struct hcfResource xxx[] = {
    ...
    {"msiEnable", HCF_RES_INT, {(void *) TRUE}},
    /* {"msiEnable", HCF_RES_INT, {(void *) FALSE}},*/
    ...
}

通过修改hwconf,可以很方便的进行配置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值