VXWORKS vxbResource 资源管理

文章详细介绍了VXWORKS7.0中设备驱动开发的过程,特别是如何通过vxbResourceAlloc函数获取硬件资源。在vxbFdtChildScan函数中,遍历设备树并初始化资源表,获取寄存器和中断信息。vxbResourceAlloc函数用于从父设备VXBUS获取资源,通过VXB_RESOURCE_ALLOC匹配资源。最后,文章提到了特定驱动如fslI2cResAlloc如何分配资源。
摘要由CSDN通过智能技术生成

VXWORKS7.0版本里经常在某某驱动里看到vxbXXXAttach函数调用

  pRes = vxbResourceAlloc (pDev, VXB_RES_MEMORY, 0);

该函数的作用主要是获取硬件资源参数。

STATUS vxbFdtChildScan
    (
    VXB_DEV_ID pDev              /* device to scan */
    )
    {
    VXB_FDT_BUS_DEV_INFO * pFdtHardware;
    VXB_FDT_DEV * pFdtDev;
    VXB_FDT_DEV * pNewFdtDev;
    int offset;
    VXB_DEV_ID   pCur;
    char name[MAX_DEV_NAME_LEN];
    char * pUnitAddr;

    pFdtDev = vxbFdtDevGet (pDev);                  /* req: VX7-13978 */

    if (pFdtDev == NULL)
        return (ERROR);

    offset = pFdtDev->offset;

                                                    /* req: VX7-13979 */
    for (offset = VX_FDT_CHILD(offset); offset > 0;
         offset = VX_FDT_PEER(offset))
        {                                          /* req: VX7-13980 */
        if (vxFdtIsEnabled (offset) == FALSE)
            continue;
                                                  /* req: VX7-13981 */
        pFdtHardware = (VXB_FDT_BUS_DEV_INFO *)vxbMemAlloc (sizeof(*pFdtHardware));

        if (pFdtHardware == NULL)               /* req: VX7-13982 */
            continue;

        pNewFdtDev = &pFdtHardware->vxbFdtDev;

        /* Get the device basic information  */   /* req: VX7-13983 */

        vxbFdtDevSetup (offset, pNewFdtDev);

        /* Get the device register and interrupt information  */
                                                  /* req: VX7-13984 */
        if (vxbResourceInit(&pFdtHardware->vxbResList) != OK)
            {                                   /* req: VX7-13985 */
            vxbMemFree (pFdtHardware);
            continue;
            }
                                                  /* req: VX7-13986 */
        if (vxbFdtRegGet(&pFdtHardware->vxbResList, pNewFdtDev) != OK)
            {                                   /* req: VX7-13987 */
            vxbFdtResFree (&pFdtHardware->vxbResList);
            vxbMemFree(pFdtHardware);
            continue;
            }
                                                  /* req: VX7-13988 */
        if (vxbFdtIntGet(&pFdtHardware->vxbResList, pNewFdtDev) != OK)
            {                                   /* req: VX7-13989 */
            vxbFdtResFree (&pFdtHardware->vxbResList);
            vxbMemFree(pFdtHardware);
            continue;
            }

        pCur = NULL;                              /* req: VX7-13990 */

        if (vxbDevCreate (&pCur) != OK)
            {                                   /* req: VX7-13991 */
            vxbFdtResFree (&pFdtHardware->vxbResList);
            vxbMemFree (pFdtHardware);
            continue;
            }
                                                    /* req: VX7-13992 */
        vxbDevNameSet (pCur, pNewFdtDev->name, FALSE);

        /*
         * FDT nodes names are usually specified in the form
         * "name@unit-address". If the name contains a unit
         * address, then we should use that, otherwise use 0.
         */

        pUnitAddr = vxbFdtUnitAddrGet ((UINT32)offset, name, MAX_DEV_NAME_LEN);
        if (pUnitAddr == NULL)
            {
            (void) snprintf (name, MAX_DEV_NAME_LEN, "0");
            }
        else
            {
            (void) snprintf (name, MAX_DEV_NAME_LEN, "%s", pUnitAddr);
            }

        vxbDevNameAddrSet (pCur, name, TRUE);

在设备树vxbFdtChildScan函数库里,可以看到该函数初始化一个资源表(vxbResourceInit(&pFdtHardware->vxbResList),调用vxbFdtRegGet(&pFdtHardware->vxbResList, pNewFdtDev)获取寄存器地址参数,调用vxbFdtIntGet(&pFdtHardware->vxbResList, pNewFdtDev)获取中断参数。假设设备树某个设备描述如下:

        qdma0: dma-controller@8380000
            {
            compatible = "fsl,qdma";
            reg = <0x0 0x8380000 0x0 0x10000>,  /* Privileged registers */
                  <0x0 0x8390000 0x0 0x10000>,  /* Manager registers */
                  <0x0 0x83A0000 0x0 0x10000>;  /* Block registers */
            interrupt-parent = <&intc>;
            interrupts = <71 0 4>;
            clocks = <&dma1_en>;
            dma-channels = <64>;
            big-endian = <1>;
            status = "disabled";      /* set "okay" to enable access */
            };

其中vxbFdtRegGet 获取reg =参数节点,vxbFdtIntGet获取interrupts节点。

最后调用vxbDevAdd,把资源添加到VXBUS列表里。

有了资源列表后,接下来查看vxbResourceAlloc怎么实现的,在该函数里首先调用vxbDevParent获取父设备VXBUS指针,为啥需要调用这个指针呢?看如下设备树结构:

    &i2c0
        {
        clocks = <&i2c1_en>;
        interrupts = <88 0 4>;
        status = "okay";

  

  }

如果我们需要使用I2C下的驱动,这时候首先需要知道I2C0的父类硬件资源参数,这个资源其实就是设备树解析时,调用fdtBusResAlloc创建的,所有寄存器参数信息保存在pFdtBusDevInfo列表里,所以通过vxbDevParent获取I2C寄存器相关参数。

VXB_RESOURCE * vxbResourceAlloc
    (
    VXB_DEV_ID     pDev,        /* device from which to allocate resource */
    UINT16         type,        /* type of resource to allocate */
    UINT16         idx          /* identifier of resource to allocate */
    )
    {
    VXB_DEV_ID     pBus;
    VXB_RESOURCE * pRes;

    if (pDev == NULL)
        {
        return NULL;                             /* req: VX7-19825 */
        }
                                                 /* req: VX7-13768 */
    pBus = vxbDevParent(pDev);

    if (pBus == NULL)
        {
                                                 /* req: VX7-13769 */
        return NULL;
        }
                                                 /* req: VX7-13770 */
    pRes = VXB_RESOURCE_ALLOC(pBus, pDev, (UINT32)(VXB_RES_ID_CREATE(type, idx)));

    if (pRes != NULL)
        pRes->owner = pDev;                    /* req: VX7-13771 */

    return (pRes);
    }

找到父类VXBUS指针后,调用VXB_RESOURCE_ALLOC 获取资源,这个是一个匹配通用方法的函数。找到对应的vxbResourceAlloc函数 ,如fslI2cResAlloc函数。

LOCAL VXB_RESOURCE * fslI2cResAlloc
    (
    VXB_DEV_ID pDev,
    VXB_DEV_ID pChild,
    UINT32     id
    )
    {
    I2C_DEV_INFO * pFslI2cDevInfo;
    VXB_RESOURCE * vxbRes;
    VXB_RESOURCE_ADR * vxbAdrRes;

    pFslI2cDevInfo = (I2C_DEV_INFO *) vxbDevIvarsGet (pChild);

    if (pFslI2cDevInfo == NULL)
        {
        return NULL;
        }

    vxbRes = vxbResourceFind (&pFslI2cDevInfo->vxbResList, id);

    if (vxbRes == NULL)
        {
        return NULL;
        }

    if ((VXB_RES_TYPE (vxbRes->id) == VXB_RES_MEMORY) ||
        (VXB_RES_TYPE (vxbRes->id) == VXB_RES_IO))
        {
        vxbAdrRes = vxbRes->pRes;
        vxbAdrRes->virtual = (VIRT_ADDR) vxbAdrRes->start;
        return vxbRes;
        }
    else if ((VXB_RES_TYPE (vxbRes->id) == VXB_RES_IRQ) &&
             (vxbIntMap (vxbRes) == OK))
        {
        return vxbRes;
        }
    else
        {
        return NULL;
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值