今天和大家谈谈vx7SD卡的vxbus挂接,及文件系统格式化流程,vx7的vxbus基于设备树,首先必须增加设备树节点,如下:

 sdhc0: sdhc@E0100000{compatible = "zynq,sdhc";reg = <0xE0100000 0x1000>;clock-frequency = <100000000>;interrupts = <56 0 4>;interrupt-parent = <&intc>;embedded = <0>;bus-width = <4>;max-dev-clock-frequency = <52000000>;card-status-check = <0>; };
```

了解清楚vxbus设备SD卡的挂接流程,对于我们设备驱动的开发至关重要,具体流程如下:
1、设备初始化时会自动加载并识别设备树的节点配置,并匹配相应的驱动程序,首先匹配到SDHC主控制器设备compatible = "zynq,sdhc";在这个驱动中会调用attach去初始化相应的设备,具体代码如下:

LOCAL STATUS zynqSdhcCtrlAttach(struct vxbDev * pDev /* Device information */){ZYNQSDHC_CFG * pCfg;STATUS rc;SDHC_DEV_CTRL * pDrvCtrl;VXB_FDT_DEV * pFdtDev;const void * pValue;int len;rc = vxbClkEnableAll (pDev);if (rc == ERROR){return ERROR;}rc = sdhcCtrlAttach (pDev);if (rc == ERROR)return (rc);pDrvCtrl = (SDHC_DEV_CTRL *)GET_DRVCTRL(pDev);if (pDrvCtrl == NULL)return ERROR;pFdtDev = vxbFdtDevGet(pDev);if (pFdtDev == NULL)return ERROR;(void)vxbPinMuxEnable(pDev);/* retrieve embedded information if provided */pValue = vxFdtPropGet(pFdtDev->offset, "embedded", &len);if(pValue != NULL){pDrvCtrl->embedded = vxFdt32ToCpu(*(UINT32 *)pValue);}/* retrieve max-dev-clock-frequency information if provided */pValue = vxFdtPropGet(pFdtDev->offset, "max-dev-clock-frequency", &len);if(pValue != NULL)pDrvCtrl->maxDevClkFreq = vxFdt32ToCpu(*(UINT32 *)pValue);elsepDrvCtrl->maxDevClkFreq = 0;/* retrieve user-set-clock-frequency information if provided */pValue = vxFdtPropGet(pFdtDev->offset, "user-set-clock-frequency", &len);if(pValue != NULL)pDrvCtrl->userSetClkFreq = vxFdt32ToCpu(*(UINT32 *)pValue);elsepDrvCtrl->userSetClkFreq = 0;pCfg = (ZYNQSDHC_CFG *)vxbDevDrvDataGet(pDev);pDrvCtrl->flags = pCfg->flag;pDrvCtrl->sdHostCtrl.sdHostOps.vxbSdHostCtrlInit = zynqSdhcInit;if (pDrvCtrl->embedded == FALSE){pDrvCtrl->sdHostCtrl.sdHostOps.vxbSdVddSetup = zynqSdhcVddSetup;}else{pDrvCtrl->sdHostCtrl.sdHostOps.vxbSdVddSetup = NULL;}pDrvCtrl->flags |= SDHC_MANUAL_SDMA_ADDRESS;rc = zynqSdhcInstConnect (pDev);return (rc);}

2、在attach函数最后会调用 zynqSdhcInstConnect,在zynqSdhcInstConnect函数中会创建线程sdBusMonitor,此线程会自动识别卡的插入和拔出,在卡插入时在其父节点下创建新的子节点,并增加的vxbus上去

LOCAL STATUS zynqSdhcInstConnect(VXB_DEV_HANDLE pDev){UINT32 val;STATUS rc;SDHC_DEV_CTRL * pDrvCtrl;SD_HOST_CTRL * pHostCtrl;VXB_FDT_DEV * pFdtDev;const void * pValue;int len;pDrvCtrl = (SDHC_DEV_CTRL *)GET_DRVCTRL(pDev);if (pDrvCtrl == NULL)return ERROR;pHostCtrl = (SD_HOST_CTRL *)pDrvCtrl;rc = sdhcCtrlInstConnect(pHostCtrl);if (rc == ERROR)return ERROR;pFdtDev = vxbFdtDevGet(pDev);if (pFdtDev == NULL)return ERROR;pValue = vxFdtPropGet(pFdtDev->offset, "bus-width", &len);if (pValue != NULL){pHostCtrl->sdHostSpec.busWidth = vxFdt32ToCpu(*(UINT32 *)pValue);}else{pHostCtrl->sdHostSpec.busWidth = 4;}pValue = vxFdtPropGet(pFdtDev->offset, "card-status-check", &len);if (pValue != NULL){pHostCtrl->sdHostSpec.cardCheck = vxFdt32ToCpu(*(UINT32 *)pValue);}else{pHostCtrl->sdHostSpec.cardCheck = 0;}pHostCtrl->sdHostSpec.vxbSdBusWidthSetup = pHostCtrl->sdHostOps.vxbSdBusWidthSetup;pHostCtrl->sdHostSpec.vxbSdCardWpCheck = pHostCtrl->sdHostOps.vxbSdCardWpCheck;pHostCtrl->sdHostSpec.vxbSdClkFreqSetup = pHostCtrl->sdHostOps.vxbSdClkFreqSetup;pHostCtrl->sdHostSpec.vxbSdResumeSet = pHostCtrl->sdHostOps.vxbSdResumeSet;pHostCtrl->sdHostSpec.vxbSdVddSetup =  pHostCtrl->sdHostOps.vxbSdVddSetup;pHostCtrl->sdHostSpec.capbility = pHostCtrl->capbility;pHostCtrl->sdHostSpec.maxTranSpeed = pDrvCtrl->maxDevClkFreq;pHostCtrl->sdHostSpec.userSetTranSpeed = pDrvCtrl->userSetClkFreq;pHostCtrl->sdHostSpec.directBio = pHostCtrl->directBio;pDrvCtrl->monTaskId = taskSpawn ("sdBusMonitor", 100, 0,8192, (FUNCPTR)zynqSdhcCtrlMonitor,(_Vx_usr_arg_t)pDev, 0, 0, 0, 0, 0, 0, 0, 0, 0);if (pDrvCtrl->monTaskId == TASK_ID_ERROR){ZYNQSDHC_DBG (ZYNQSDHC_DBG_ERR, "Create monitor task fault\n",0, 0, 0, 0, 0, 0);return ERROR;}/* setup the interrupt mask */pDrvCtrl->intMask = (IRQ_DATA | IRQ_CMD);pDrvCtrl->intMask |= IRQ_AC12E; if (pDrvCtrl->sdHostCtrl.dmaMode == SDHC_DMA_MODE_PIO)pDrvCtrl->intMask |= (IRQ_BRR | IRQ_BWR);if (pDrvCtrl->embedded == FALSE)pDrvCtrl->intMask |= (IRQ_CINS | IRQ_DINT | IRQ_CRM);elsepDrvCtrl->intMask |= IRQ_DINT;CSR_WRITE_4 (pDev, SDHC_IRQSTATEN, pDrvCtrl->intMask);/* enable SDHC interrupts */if (pDrvCtrl->sdHostCtrl.polling == FALSE){/* connect and enable interrupt */if (pDrvCtrl->sdHostCtrl.sdHostOps.vxbSdIsr == NULL){(void)taskDelete (pDrvCtrl->monTaskId); return ERROR;} rc = vxbIntConnect (pDev,pDrvCtrl->intRes,(VOIDFUNCPTR)pDrvCtrl->sdHostCtrl.sdHostOps.vxbSdIsr,pDev);if (rc == ERROR){(void)taskDelete (pDrvCtrl->monTaskId); return ERROR;} rc = vxbIntEnable (pDev, pDrvCtrl->intRes);if (rc == ERROR){(void)taskDelete (pDrvCtrl->monTaskId); return ERROR;} CSR_WRITE_4 (pDev, SDHC_IRQSIGEN, pDrvCtrl->intMask);}if (pDrvCtrl->embedded == FALSE){/* don't miss an already inserted card */val  = CSR_READ_4(pDev, SDHC_PRSSTAT);if (val & PRSSTAT_CINS){(void)semGive(pDrvCtrl->sdHostCtrl.devChange);}}else{(void)semGive(pDrvCtrl->sdHostCtrl.devChange);}return OK;}

在这个线程 中会调用zynqSdhcDevAdd,增加子节点到vxbus上并设备名为vxbDevNameSet (pDev, MMC_CARD_NAME, TRUE);或者 vxbDevNameSet (pDev, SD_CARD_NAME, TRUE);
vxbDevAdd函数在增加设备节点时会根据devName查找匹配函数并调用相关初始化操作,此时会找到相应的SD卡驱动函数:

LOCAL void zynqSdhcCtrlMonitor(VXB_DEV_HANDLE pDev){STATUS rc;SD_HOST_CTRL * pSdHostCtrl;SDHC_DEV_CTRL * pDrvCtrl; pDrvCtrl = (SDHC_DEV_CTRL *)GET_DRVCTRL(pDev);if (pDrvCtrl == NULL)return;elsepSdHostCtrl = (SD_HOST_CTRL *)(&(pDrvCtrl->sdHostCtrl));while (erfLibInitialized == FALSE)(void)taskDelay (sysClkRateGet ());while(1){rc = pSdHostCtrl->sdHostOps.vxbSdCardInsertSts(pDev);if (rc && (pSdHostCtrl->attached == FALSE)){zynqSdhcDevAdd(pDev);}else if (rc){zynqSdhcDevRemove(pDev);zynqSdhcDevAdd(pDev);}if (!rc && (pSdHostCtrl->attached == TRUE)){zynqSdhcDevRemove (pDev);}}}

相应代码如下:

STATUS sdDeviceCreate(VXB_DEV_HANDLE pInst,void * pArg){VXB_DEV_ID      pDev = NULL;SD_HARDWARE   * pSdHardWare;SD_HOST_SPEC  * pSdHostSpec;STATUS rc;/* initialize generic bus info */rc = vxbDevCreate (&pDev);if (rc != OK){SD_LIB_DBG (SD_LIB_DBG_ERR,"sdDeviceAnnounce() - vxbDevStructAlloc not success\n",0, 0, 0, 0, 0, 0);return(ERROR);}/* initialize bus-specific info */pSdHardWare = (SD_HARDWARE *) vxbMemAlloc(sizeof (SD_HARDWARE));if (pSdHardWare == NULL){SD_LIB_DBG (SD_LIB_DBG_ERR,"sdDeviceAnnounce - hwMemAlloc not success for pSdHardWare\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);return(ERROR);}rc = VXB_SDSPECINFO_GET(pInst, &(pSdHardWare->pHostSpec), &(pSdHardWare->vxbSdCmdIssue));if (rc != OK){SD_LIB_DBG(SD_LIB_DBG_ERR,"sdDeviceAnnounce - VXB_SDSPECINFO_GET not success\n",0, 0, 0, 0, 0 ,0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}vxbDevClassSet(pDev, VXB_BUSID_SDMMC);vxbDevIvarsSet(pDev,pSdHardWare);pSdHostSpec = (SD_HOST_SPEC *)(pSdHardWare->pHostSpec);if (pSdHostSpec == NULL){SD_LIB_DBG(SD_LIB_DBG_ERR, "sdDeviceAnnounce - pSdHostSpec null\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}pSdHostSpec->childDev = pDev;/* get host controller unit number */pSdHostSpec->unitNumber = vxbDevUnitGet(pInst);pSdHardWare->pHostDev = pInst;if (pSdHostSpec->vxbSdGetHostCap){(void)(pSdHostSpec->vxbSdGetHostCap)(pInst, &(pSdHostSpec->hostCap));}return sdDeviceInit(pDev,0);}
STATUS sdDeviceInit(VXB_DEV_HANDLE pDev,UINT32 reInit){VXB_DEV_HANDLE pInst;SD_HARDWARE   * pSdHardWare;SD_HOST_SPEC  * pSdHostSpec;STATUS rc;int i = 0;UINT32  capbility;UINT32 timeOut = 0;pSdHardWare = (SD_HARDWARE *)GET_HARDWAREINFO(pDev);if (pSdHardWare == NULL)return ERROR;pSdHostSpec = (SD_HOST_SPEC *)(pSdHardWare->pHostSpec);if (pSdHostSpec == NULL)return ERROR;capbility = pSdHostSpec->capbility;pInst = pSdHardWare->pHostDev;rc = sdCmdGoIdleState (pDev);if (rc == ERROR){SD_LIB_DBG(SD_LIB_DBG_ERR,"sdDeviceAnnounce - sdCmdGoIdleState not success\n\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}/* CMD8 is required to support SDHC or SDXC */(void)sdCmdSendIfCond (pDev, 0);rc = sdioCmdIoSendOpCond(pDev, capbility & OCR_VDD_VOL_MASK);if ((pSdHardWare->cmdErr & SDMMC_CMD_ERR_TIMEOUT) != 0x0){/* To conform to JEDEC specification */rc = sdMmcCmdSendOpCond(pDev, 0);if ((rc == ERROR) ||((pSdHardWare->cmdErr & SDMMC_CMD_ERR_TIMEOUT) != 0x0))pSdHardWare->isMmc = FALSE;elsepSdHardWare->isMmc = TRUE;if (pSdHardWare->isMmc){sdCmdGoIdleState(pDev);while (timeOut++ < SDMMC_COMMAND_TIMEOUT){rc = sdMmcCmdSendOpCond(pDev,(pSdHardWare->ocrValue |OCR_CARD_CAP_STS));if ((rc == OK) &&((pSdHardWare->ocrValue & (UINT32)OCR_CARD_PWRUP_STS) != 0x0)){pSdHardWare->voltage = (pSdHardWare->ocrValue) & OCR_VDD_VOL_MASK;break;}vxbMsDelay(1);}vxbDevNameSet (pDev, MMC_CARD_NAME, TRUE);}else{(void)sdCmdGoIdleState (pDev);(void)sdCmdSendIfCond (pDev, capbility);if (pSdHardWare->version == SD_VERSION_UNKNOWN){SD_LIB_DBG(SD_LIB_DBG_ERR,"sdDeviceAnnounce - sdCmdGoIdleState not success\n\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}while (timeOut++ < SDMMC_COMMAND_TIMEOUT){rc = sdACmdSendOpCond (pDev, capbility, pSdHardWare->version, reInit);if ((rc == OK) && ((pSdHardWare->ocrValue & (UINT32)OCR_CARD_PWRUP_STS) != 0x0)){pSdHardWare->voltage = (pSdHardWare->ocrValue) & OCR_VDD_VOL_MASK;break;}vxbMsDelay(1);}if (timeOut >= SDMMC_COMMAND_TIMEOUT){SD_LIB_DBG(SD_LIB_DBG_ERR,"sdDeviceAnnounce - sdACmdSendOpCond not success\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}/* Use pSdHostSpec->capbility to record S18A */if (pSdHardWare->ocrValue & OCR_VDD_VOL_S18A){pSdHostSpec->capbility |= OCR_VDD_VOL_S18A;}vxbDevNameSet (pDev, SD_CARD_NAME, TRUE);}pSdHardWare->isComboCard = FALSE;pSdHardWare->isSdio = FALSE;rc = vxbDevAdd (pInst, pDev);if (rc == ERROR){SD_LIB_DBG(SD_LIB_DBG_ERR,"sdDeviceAnnounce - vxbDevAdd not success\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}pSdHardWare->recover = TRUE;/* coverity[leaked_storage] *//** pDev and pSdHardWare are used with vxBus system,* so we can't free it. Set coverity keyword*/return OK;}if (rc == OK){UINT8 funcNum = 0;funcNum = (pSdHardWare->ocrValue >> 28) & 0x07;if (funcNum > 0){rc = sdioCmdIoSendOpCond(pDev, capbility & 0x00FFFFFF);if (rc == ERROR){SD_LIB_DBG (SD_LIB_DBG_ERR,"sdDeviceAnnounce - sdioCmdIoSendOpCond not success\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}do{rc = sdCmdSendRelativeAddr (pDev);if (rc == ERROR){SD_LIB_DBG (SD_LIB_DBG_ERR,"sdDeviceAnnounce - sdCmdSendRelativeAddr not success\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}} while (pSdHardWare->rcaValue == 0);rc = sdCmdSelectCard (pDev);if (rc == ERROR){SD_LIB_DBG (SD_LIB_DBG_ERR,"sdDeviceAnnounce - sdCmdSelectCard not success\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}for (i = 0; i < funcNum; i++){if (pDev == NULL){rc = vxbDevCreate (&pDev);if (rc == ERROR){SD_LIB_DBG (SD_LIB_DBG_ERR,"sdDeviceAnnounce - vxbDevCreate not success\n",0, 0, 0, 0, 0, 0);vxbMemFree(pSdHardWare);return(ERROR);}}if (pSdHardWare == NULL){pSdHardWare = (SD_HARDWARE *) vxbMemAlloc(sizeof (SD_HARDWARE));if (pSdHardWare == NULL){SD_LIB_DBG (SD_LIB_DBG_ERR,"sdDeviceAnnounce - hwMemAlloc not success for pSdHardWare\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);return(ERROR);}rc = VXB_SDSPECINFO_GET(pInst, &(pSdHardWare->pHostSpec), &(pSdHardWare->vxbSdCmdIssue));if (rc != OK){SD_LIB_DBG (SD_LIB_DBG_ERR,"sdDeviceAnnounce - VXB_SDSPECINFO_GET not success\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}vxbDevClassSet(pDev, VXB_BUSID_SDMMC);vxbDevIvarsSet(pDev,pSdHardWare);pSdHostSpec = (SD_HOST_SPEC *)(pSdHardWare->pHostSpec);if (pSdHostSpec == NULL){SD_LIB_DBG (SD_LIB_DBG_ERR,"sdDeviceAnnounce - pSdHostSpec null\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}capbility = pSdHostSpec->capbility;}pSdHardWare->isSdio = TRUE;pSdHardWare->isComboCard = FALSE;pSdHardWare->funcNum = i + 1;/* Need not check return status at here */rc = vxbDevAdd (pInst, pDev);if (rc == ERROR){SD_LIB_DBG (SD_LIB_DBG_ERR,"sdDeviceAnnounce - vxbDevAdd not success\n",0, 0, 0, 0, 0, 0);vxbMemFree(pDev);vxbMemFree(pSdHardWare);return(ERROR);}pDev = NULL;pSdHardWare = NULL;}}}return OK;}

在SD卡的ATTACH函数中会挂接相应的read,write,ioctl等函数并创建xbd包装器

LOCAL STATUS sdIdentify(VXB_DEV_HANDLE pDev){STATUS rc;UINT32 csize, csizeMulti;UINT64 blkNum;SD_CARD_CTRL * pDrvCtrl;SD_HARDWARE * pSdHardware;SD_HOST_SPEC * pHostSpec;SD_INFO * pSdInfo;device_t xbdSts;BLK_XBD_PARAMS blkXbdParams;UINT32 workSpeed;UINT32 i;pDrvCtrl = (SD_CARD_CTRL *)GET_DRVCTRL (pDev);if (pDrvCtrl == NULL)return ERROR;pSdHardware = (SD_HARDWARE *)GET_HARDWAREINFO(pDev);if (pSdHardware == NULL)return ERROR;pHostSpec = (SD_HOST_SPEC *)(pSdHardware->pHostSpec);if (pHostSpec == NULL)return ERROR;#ifdef _WRS_CONFIG_VXBUS_LEGACYpDrvCtrl->pInfo = malloc (sizeof(SD_INFO));
#elsepDrvCtrl->pInfo = vxbMemAlloc(sizeof(SD_INFO));
#endif /* _WRS_CONFIG_VXBUS_LEGACY */if (pDrvCtrl->pInfo == NULL)goto err1;/* apply one card index to system */rc = sdCardIdxAlloc (pDrvCtrl);if (rc != OK){SD_CARD_DBG(SD_CARD_DBG_INIT, "sdIdentify() -  sdCardIdxAlloc fault\n",0, 0, 0, 0, 0, 0);goto err;}pSdInfo = (SD_INFO *)(pDrvCtrl->pInfo);bcopy((char *)(&pSdHardware->cidValue[0]), (char *)(&pSdInfo->cid), CID_SIZE);pDrvCtrl->highCapacity = (((pSdHardware->ocrValue) &OCR_CARD_CAP_STS) != 0x0) ? TRUE : FALSE;SD_CARD_DBG(SD_CARD_DBG_INIT,"sdIdentify() -  pDrvCtrl->highCapacity = 0x%x\n",pDrvCtrl->highCapacity, 0, 0, 0, 0, 0);if ((pHostSpec->capbility & OCR_VDD_VOL_S18A) != 0x0){if ((pSdHardware->ocrValue & OCR_VDD_VOL_S18A) != 0x0)pSdInfo->uhsSupport = TRUE;elsepSdInfo->uhsSupport = FALSE;}elsepSdInfo->uhsSupport = FALSE;if (pSdInfo->uhsSupport){if (pHostSpec->vxbSdSigVolSwitch != NULL){rc = pHostSpec->vxbSdSigVolSwitch (pSdHardware->pHostDev, SD_VOLTAGE_S18);if (rc == ERROR){SD_CARD_DBG(SD_CARD_DBG_ERR,"sdIdentify() -  vxbSdSigVolSwitch error\n",0, 0, 0, 0, 0, 0);pSdInfo->uhsSupport = FALSE;pHostSpec->capbility &= (~OCR_VDD_VOL_S18A);/** If an error occurs during voltage switch procedure, stop providing * the power to the card. In this case, Host Driver should retry * initialization procedure by setting S18R to 0 at step (7) and (21) in* Figure 3-9. (Part A2)*//** AM572X idk board doesn't support power cycle. So retry initialization* is not validated.*/#ifndef _WRS_CONFIG_VXBUS_LEGACYrc = sdPowerCycle(pDev);if (rc == OK){vxbMemFree (pDrvCtrl->pInfo);vxbMemFree (pDrvCtrl);vxbDevSoftcSet(pDev, NULL);return sdDeviceInit(pDev, 1);}else
#endif /* _WRS_CONFIG_VXBUS_LEGACY */goto err;}}else{pSdInfo->uhsSupport = FALSE;pHostSpec->capbility &= (~OCR_VDD_VOL_S18A);goto sendRca;}goto sendRca;}sendRca:/* Need not take care of return value */(void)sdCmdAllSendCid(pDev, (void *) (&pSdHardware->cidValue[0]));/* CMD3: request card to send RCA */i = 0;do{(void)sdCmdSendRelativeAddr (pDev);} while ((pSdHardware->rcaValue == 0) && (i++ < CMD3_RETRY_NUM));if (i >= CMD3_RETRY_NUM){SD_CARD_DBG(SD_CARD_DBG_ERR, "sdIdentify() - failed to get valid RCA.\n",0, 0, 0, 0, 0, 0);goto err;}else{SD_CARD_DBG(SD_CARD_DBG_INIT, "sdIdentify() -  pSdHardware->rcaValue = 0x%x\n",pSdHardware->rcaValue, 0, 0, 0, 0, 0);}/* CMD9: request card to send CSD */rc = sdCmdSendCsd (pDev, &(pSdInfo->csd));if (rc == ERROR)goto err;else{pSdInfo->csd.commClass = (UINT16)be16toh(pSdInfo->csd.commClass);pSdInfo->csd.eraseSize = (UINT16)be16toh(pSdInfo->csd.eraseSize);pSdInfo->csd.r2wFactor = (UINT16)be16toh(pSdInfo->csd.r2wFactor);pSdInfo->csd.fileFormat = (UINT16)be16toh(pSdInfo->csd.fileFormat);SD_CARD_DBG(SD_CARD_DBG_INIT, "sdIdentify() -  pSdInfo->csd.commClass = 0x%x\n""pSdInfo->csd.eraseSize = 0x%x\n""pSdInfo->csd.r2wFactor = 0x%x\n""pSdInfo->csd.fileFormat = 0x%x\n",pSdInfo->csd.commClass, pSdInfo->csd.eraseSize,pSdInfo->csd.r2wFactor, pSdInfo->csd.fileFormat, 0, 0);/* decode CSD fields */pDrvCtrl->tranSpeed = sdCsdTranSpdfUnit[(pSdInfo->csd.tranSpeed & 0x7)] *sdCsdTranSpdTime[((pSdInfo->csd.tranSpeed >> 3) & 0x0f)];SD_CARD_DBG(SD_CARD_DBG_INIT, "sdIdentify() -  pDrvCtrl->tranSpeed = %d\n",pDrvCtrl->tranSpeed, 0, 0, 0, 0, 0);if (pDrvCtrl->tranSpeed == CSD_TRAN_SPD_50MHZ)pDrvCtrl->highSpeed = TRUE;/* maximum read block length */pDrvCtrl->readBlkLen = 1 << (pSdInfo->csd.commClass & 0x0f);SD_CARD_DBG(SD_CARD_DBG_INIT, "sdIdentify() -  pDrvCtrl->readBlkLen = %d\n",pDrvCtrl->readBlkLen, 0, 0, 0, 0, 0);/* per SD spec, the maximum write block length is equal to read block */pDrvCtrl->writeBlkLen = pDrvCtrl->readBlkLen;pSdHardware->blockSize = SDMMC_BLOCK_SIZE;/* calculate user data capacity */if (pDrvCtrl->highCapacity){csize = ((pSdInfo->csd.resvData0[1] & 0x3f) << 16) |(pSdInfo->csd.resvData0[2] << 8) |pSdInfo->csd.resvData0[3];csizeMulti = 8;}else{csize = ((UINT32)(pSdInfo->csd.resvData0[0] & 0x03) << 10) |((UINT32)(pSdInfo->csd.resvData0[1]) << 2) |((pSdInfo->csd.resvData0[2] >> 6) & 0x03);csizeMulti = ((pSdInfo->csd.resvData0[3] & 0x03) << 1) |((pSdInfo->csd.eraseSize >> 7) & 0x01);}blkNum = ((UINT64)(csize + 1)) << (csizeMulti + 2);pDrvCtrl->blkNum = blkNum;pDrvCtrl->capacity = blkNum * pDrvCtrl->readBlkLen;SD_CARD_DBG(SD_CARD_DBG_INIT, "sdIdentify() -  pDrvCtrl->blkNum = %ld\n""pDrvCtrl->capacity = %ld\n",pDrvCtrl->blkNum, pDrvCtrl->capacity, 0, 0, 0, 0);/* write protect model */if ((pSdInfo->csd.fileFormat >> 12) & 0x1)pDrvCtrl->tmpWp = TRUE;if ((pSdInfo->csd.fileFormat >> 13) & 0x1)pDrvCtrl->permWp = TRUE;}/* After Card Identification, the station go into Data Transfer Mode */if (pDrvCtrl->tranSpeed > SDMMC_CLK_FREQ_400KHZ){workSpeed = pDrvCtrl->tranSpeed < SDMMC_CLK_FREQ_25MHZ ?pDrvCtrl->tranSpeed : SDMMC_CLK_FREQ_25MHZ;pHostSpec->vxbSdClkFreqSetup (pSdHardware->pHostDev, workSpeed);}pDrvCtrl->highSpeed = FALSE;/* CMD7: select one card and put it into transfer state */rc = sdCmdSelectCard (pDev);if (rc == ERROR)goto err;/* AMD51: request card to send its SCR */rc = sdACmdSendScr (pDev, &(pSdInfo->scr));if (rc == ERROR)goto err;else{pSdInfo->sdSpec = pSdInfo->scr.spec & 0x0f;SD_CARD_DBG(SD_CARD_DBG_INIT, "sdIdentify() -  pSdInfo->sdSpec = 0x%x\n",pSdInfo->sdSpec, 0, 0, 0, 0, 0);/* update the SD card version */pSdHardware->version = (UINT8)(pSdInfo->sdSpec + 1);if ((pSdInfo->scr.expConfig & SCR_SD_SPEC3_MASK) != 0x0){if (pSdHardware->version == SD_VERSION_200)pSdHardware->version = SD_VERSION_300;}pSdInfo->sdSec = (pSdInfo->scr.config >> 4) & 0x7;if (pSdInfo->scr.config & SCR_SD_BUS_WIDTH_4BIT)pSdInfo->dat4Bit = TRUE;}/* switch to 4 bit mode if needed */if (pSdInfo->dat4Bit){rc = sdACmdSetBusWidth (pDev, SDMMC_BUS_WIDTH_4BIT);if (rc == ERROR)goto err;/* setup host to enable 4-bit bus width */if (pHostSpec->vxbSdBusWidthSetup != NULL){pHostSpec->vxbSdBusWidthSetup(pSdHardware->pHostDev, SDMMC_BUS_WIDTH_4BIT);}}/* ACMD42: clear card detect and set data3 as data line */rc = sdACmdClrCardDetect(pDev, SD_ACMD42_ARG_CLR_CARD_DETECT);if (rc == ERROR)goto err;    /* setup host to enable high speed clock (50 MHz) if needed */if (pSdInfo->uhsSupport){rc = sdInitUhsCard(pDev);if (rc == ERROR)goto err;goto createXbd;}/* setup host to enable high speed clock (50 MHz) if needed */if (pSdHardware->version >= SD_VERSION_110){int rc;rc = sdACmdSetHighSpeed(pDev);if ((pHostSpec->vxbSdClkFreqSetup != NULL)){if ((rc == OK) && (pHostSpec->workFreq == SDMMC_CLK_FREQ_25MHZ))pHostSpec->vxbSdClkFreqSetup(pSdHardware->pHostDev, SDMMC_CLK_FREQ_25MHZ);else if (rc == OK){pHostSpec->vxbSdClkFreqSetup(pSdHardware->pHostDev, SDMMC_CLK_FREQ_50MHZ);pDrvCtrl->highSpeed = TRUE;SD_CARD_DBG(SD_CARD_DBG_INIT, "sdIdentify() -  change to 50MHZ success\n",0, 0, 0, 0, 0, 0);}else if (rc == ENOTSUP){pHostSpec->vxbSdClkFreqSetup(pSdHardware->pHostDev, SDMMC_CLK_FREQ_25MHZ);pDrvCtrl->highSpeed = FALSE;}else if (rc == ERROR)goto err;}}else{if (pHostSpec->vxbSdClkFreqSetup != NULL){pHostSpec->vxbSdClkFreqSetup(pSdHardware->pHostDev, SDMMC_CLK_FREQ_25MHZ);}}/* check if card is write protected */if (pHostSpec->vxbSdCardWpCheck != NULL){pDrvCtrl->isWp = pHostSpec->vxbSdCardWpCheck(pSdHardware->pHostDev);}createXbd:/* set xbd params */blkXbdParams.xbdOps.blkRead = sdStorageBlkRead;blkXbdParams.xbdOps.blkWrite = sdStorageBlkWrite;blkXbdParams.xbdOps.blkDump = NULL;blkXbdParams.xbdOps.blkIoctl = sdStorageIoctl;blkXbdParams.xbdOps.xferReq  = NULL;blkXbdParams.maxActiveReqs = 1;blkXbdParams.maxBiosPerReq = 1;blkXbdParams.maxXferBlks = SDHC_MAX_RW_SECTORS;blkXbdParams.directModeFlag = pHostSpec->directBio;blkXbdParams.numBlks = (sector_t)(pDrvCtrl->capacity / pSdHardware->blockSize);blkXbdParams.blkSize = pSdHardware->blockSize;blkXbdParams.svcTskPri = SDMMC_XBD_SVC_TASK_PRI;blkXbdParams.pDev = (void *)pDev;(void)snprintf ((char *)&(blkXbdParams.devName[0]), sizeof(blkXbdParams.devName),"/sd%d", pHostSpec->unitNumber);pDrvCtrl->attached = TRUE;xbdSts = blkXbdDevCreate (&(pDrvCtrl->xbdDev), &blkXbdParams);if (xbdSts == NULLDEV){pDrvCtrl->attached = FALSE;goto err;}return OK;/** We need to free memories we allocated in this function when we return* ERROR. If we return OK, we don't free these memories and use them in* normal process, until sdStorageInstUnlink() is called to free these* memories from vxbDevRemove() in Monitor task when card removal is detected.*/err:
#ifndef _WRS_CONFIG_VXBUS_LEGACYvxbMemFree (pDrvCtrl->pInfo);
#elsefree (pDrvCtrl->pInfo);
#endif /* _WRS_CONFIG_VXBUS_LEGACY */err1:
#ifndef _WRS_CONFIG_VXBUS_LEGACYvxbMemFree (pDrvCtrl);vxbDevSoftcSet(pDev, NULL);
#elsefree (pDrvCtrl);
#endif /* _WRS_CONFIG_VXBUS_LEGACY */return ERROR;}

至此,设备驱动挂接完成,在shell里面输入devs 查看就可以看到设备/SD0:1,只需要调用文件系统格式化就可以了,dosFsVolFormat(“/sd0:1”,0,0);

vxworks7.0SD卡驱动流程及文件系统格式化相关推荐

  1. Linux格式化sd卡博客,linux设备驱动那点事儿之SD卡驱动理论篇

    一.SD/MMC卡介绍 1.1.什么是MMC卡 MMC:MMC就是MultiMediaCard的缩写,即多媒体卡.它是一种非易失性存储器件,体积小巧(24mm*32mm*1.4mm),容量大,耗电量低 ...

  2. SD/TF卡驱动(二)--------SD卡程序初始化流程以及读写

    说明: ①测试的SD卡为高容量卡,支持SD卡2.0协议,容量为16G ②采用GPIO模拟SPI时序的方式对SD卡进行驱动,很方便移植到没有硬件SPI或者SDIO的MCU,对于这类MCU,只需要将对应的 ...

  3. Exynos4412 移植针对Samsung的Linux-6.1(二)SD卡驱动——解决无法挂载SD卡的根文件系统

    系列文章目录 Exynos4412 移植针对Samsung的Linux-6.1(一)下载.配置.编译Linux-6.1 Exynos4412 移植针对Samsung的Linux-6.1(二)SD卡驱动 ...

  4. 战舰V3适配oneos系列03:添加SD卡驱动及文件系统

    战舰V3系列03:添加SD卡驱动及文件系统 本系列以 oneos2.3.0 提供的 STM32F103ZE 模板为基础,将 oneos 在战舰 V3 上运行起来,并逐步适配相关外设,计划周更 本系列相 ...

  5. linux4 sd卡驱动,在Linux上,如何格式化USB驱动器和SD卡

    在Linux中,你可以使用图形工具,如GParted或命令行工具,例如fdisk或parted,来格式化驱动器和分区. 在本教程中,向你展示如何使用Linux的parted工具格式化USB驱动器或SD ...

  6. S5PV210开发系列五_sd卡驱动实现

    S5PV210开发系列五 sd卡驱动实现 象棋小子    1048272975 SD卡(Secure Digital Memory Card)具有体积小.容量大.数据传输快.可插拔.安全性好等优点,被 ...

  7. S5PV210开发系列五 sd卡驱动实现

    SD卡(Secure Digital Memory Card)具有体积小.容量大.数据传输快.可插拔.安全性好等优点,被广泛应用于便携式设备上.例如作为数码相机的存储卡,作为手机.平板多媒体扩展卡用的 ...

  8. rt-thread SDIO驱动框架分析(SD卡驱动\SD Nand驱动)

    rt-thread SDIO驱动框架分析之SD卡驱动 文章目录 rt-thread SDIO驱动框架分析之SD卡驱动 1. 前言 2. SDIO通用驱动框架介绍 3. 文件架构分析 4. SDIO设备 ...

  9. 卡函数or1200基于simple-spi的SD卡驱动

    每日一贴,天今的内容关键字为卡函数 这篇blog来说说基于simple-spi这个ipcore编写spi模式的SD Card裸机的驱动程序,植移依附分不清什么SD卡啊,micro SD啊,miniSD ...

  10. wince下SD卡驱动开发

    WinCE 5.0下面SD卡驱动的开发.这是我做的第一个项目,当时做这个项目花费了相当的时间和精力,搞的我精疲力尽.几乎可以说当时对WinCE一点都不懂.也不知道从何处下手,就东看西看.东改西改,改的 ...

最新文章

  1. 生态伙伴 | Canva上线飞书应用目录,帮你零门槛轻松做出大师级设计!
  2. ggplot2笔记8:主题设置、存储导出
  3. [文章集合] 在Windows Server 2012上关于Vmware的几点
  4. Linux下两种实用自动交互方法
  5. php 序列化储存和转化 json_encode() json_decode($q,true)
  6. C++设计模式-Prototype原型模式
  7. 拾遗----javascript一些实用方法
  8. 使用管理扩展性框架构建模块化控制台应用程序
  9. Spark SQL实战
  10. html打开软件连接的代码,《前端开发从零学起》Lesson.7 HTML中超链接的使用方法...
  11. java axis2 jar_Java axis2.jar包详解及缺少jar包错误分析
  12. Android10动态权限提前,Unity2019中的android动态申请权限(Permissions)
  13. 端口映射器与端口映射软件的区别及内网发布网站到外网的使用
  14. EndNote20 for Mac 与搭载Apple M1芯片Mac版Word不兼容的解决方案(新发布的EndNote 20.1更新版可适配Apple M1)
  15. 2022年前端还好找工作吗?
  16. 微一案做php,微一案:真正的高效率,都是这么炼成的
  17. 哈希算法(Hash函数)简单介绍
  18. Animation和Animator的区别
  19. Java练习题 类 先创建一个Point类,然后定义Trianglele类。在Trianglele类中定义三个Point的实体来表示一个三角形的三个点,然后定义两个方法求三角形的周长、面积。
  20. 大多数人没听过的FreeEIM飞鸽传书,超炫酷的仿QQ,九零后都爱玩

热门文章

  1. sql2005安装图解
  2. 网络安全05_VMware 虚拟机软件安装_准备Kali- Linux虚拟机_Windows Server 2003 Enterprise 虚拟机下载和安装
  3. 爬取淘宝商家货物简单销售数据(销量,价格,销售地,货物名称)
  4. DSP课设项目(ICETEK-VC5509-EDU)
  5. 常用shell命令归纳总结
  6. [置顶] 原来JAVA对象转JSON格式的字符串如此简单,返回来暂时不会做,留下纪念下
  7. java robot api_用java Robot API 模拟实现类似按键精灵功能
  8. android pickerview 多行,Android PickerView 自定义条件选择器 联动
  9. 数学建模算法python源码_如何使用python完成数学建模常见算法
  10. Matlab 数学建模算法大全