/********************************************************************************************************* ** 函数名称: API_SdCoreDevSpiCrcEn ** 功能描述: 在SPI模式下使能设备的CRC校验 ** 输 入: psdcoredevice 设备结构指针 ** bEnable 是否使能.(0:禁止crc 1:使能crc) ** 输 出: NONE ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: ********************************************************************************************************/ INT API_SdCoreDevSpiCrcEn (PLW_SDCORE_DEVICE psdcoredevice, BOOL bEnable) { LW_SD_COMMAND sdcmd; INT iError; lib_bzero(&sdcmd, sizeof(sdcmd)); sdcmd.SDCMD_uiOpcode = SD_SPI_CRC_ON_OFF; sdcmd.SDCMD_uiFlag = SD_RSP_SPI_R1; sdcmd.SDCMD_uiArg = bEnable ? 1 : 0; sdcmd.SDCMD_uiRetry = 0; iError = API_SdCoreDevCmd(psdcoredevice, &sdcmd, 0); if (iError == ERROR_NONE) { if ((sdcmd.SDCMD_uiResp[0] & 0xff) != 0x00) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "set crc failed.\r\n"); return (PX_ERROR); } else { return (ERROR_NONE); } } SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "send cmd error.\r\n"); return (PX_ERROR); }
/********************************************************************************************************* ** 函数名称: if_up ** 功能描述: 打开网卡 ** 输 入 : ifname if name ** 输 出 : 网卡是否打开 ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT if_up (const char *ifname) { INT iError; struct netif *pnetif; LWIP_NETIF_LOCK(); /* 进入临界区 */ pnetif = netif_find((char *)ifname); if (pnetif) { if (!(pnetif->flags & NETIF_FLAG_UP)) { netifapi_netif_set_up(pnetif); #if LWIP_DHCP > 0 if (pnetif->flags2 & NETIF_FLAG2_DHCP) { ip_addr_t inaddrNone; lib_bzero(&inaddrNone, sizeof(ip_addr_t)); netifapi_netif_set_addr(pnetif, &inaddrNone, &inaddrNone, &inaddrNone); netifapi_dhcp_start(pnetif); } #endif /* LWIP_DHCP > 0 */ iError = ERROR_NONE; } else { _ErrorHandle(EALREADY); iError = PX_ERROR; } } else { _ErrorHandle(ENXIO); iError = PX_ERROR; } LWIP_NETIF_UNLOCK(); /* 退出临界区 */ return (iError); }
/********************************************************************************************************* ** 函数名称: getrusage ** 功能描述: shall provide measures of the resources used by the current process or its terminated and waited-for child processes. ** 输 入 : who RUSAGE_SELF or RUSAGE_CHILDREN ** 输 出 : 最大优先级 ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API int getrusage (int who, struct rusage *r_usage) { struct tms tmsBuf; if (!r_usage) { errno = EINVAL; return (PX_ERROR); } lib_bzero(r_usage, sizeof(struct rusage)); times(&tmsBuf); if (who == RUSAGE_SELF) { __tickToTimeval(tmsBuf.tms_utime, &r_usage->ru_utime); __tickToTimeval(tmsBuf.tms_stime, &r_usage->ru_stime); } else if (who == RUSAGE_CHILDREN) { __tickToTimeval(tmsBuf.tms_cutime, &r_usage->ru_utime); __tickToTimeval(tmsBuf.tms_cstime, &r_usage->ru_stime); } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __unix_rmsg_proc ** 功能描述: 处理一个接收到的 msg ** 输 入 : pvMsgEx 扩展消息 ** uiLenEx 扩展消息长度 ** pidSend sender pid ** flags MSG_CMSG_CLOEXEC 支持. ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID __unix_rmsg_proc (PVOID pvMsgEx, socklen_t uiLenEx, pid_t pidSend, INT flags) { INT i; struct cmsghdr *pcmhdr; struct msghdr msghdrBuf; if ((pvMsgEx == LW_NULL) || (uiLenEx < sizeof(struct cmsghdr))) { return; } lib_bzero(&msghdrBuf, sizeof(struct msghdr)); msghdrBuf.msg_control = pvMsgEx; msghdrBuf.msg_controllen = uiLenEx; pcmhdr = CMSG_FIRSTHDR(&msghdrBuf); while (pcmhdr) { if (pcmhdr->cmsg_level == SOL_SOCKET) { if (pcmhdr->cmsg_type == SCM_RIGHTS) { /* 传送文件描述符 */ INT *iFdArry = (INT *)CMSG_DATA(pcmhdr); INT iNum = (pcmhdr->cmsg_len - CMSG_LEN(0)) / sizeof(INT); for (i = 0; i < iNum; i++) { iFdArry[i] = __unix_dup(pidSend, iFdArry[i]); /* 记录 dup 到本进程的 fd */ if ((flags & MSG_CMSG_CLOEXEC) && (iFdArry[i] >= 0)) { API_IosFdSetCloExec(iFdArry[i], FD_CLOEXEC); } } } } pcmhdr = CMSG_NXTHDR(&msghdrBuf, pcmhdr); } }
/********************************************************************************************************* ** 函数名称: archFpuPrimaryInit ** 功能描述: 主核 Fpu 控制器初始化 ** 输 入 : pcMachineName 机器名称 ** pcFpuName fpu 名称 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID archFpuPrimaryInit (CPCHAR pcMachineName, CPCHAR pcFpuName) { _DebugFormat(__LOGMESSAGE_LEVEL, "%s %s FPU pri-core initialization.\r\n", pcMachineName, pcFpuName); if (lib_strcmp(pcFpuName, PPC_FPU_NONE) == 0) { /* 选择 VFP 架构 */ _G_pfpuop = ppcVfpNonePrimaryInit(pcMachineName, pcFpuName); } else if (lib_strcmp(pcFpuName, PPC_FPU_VFP) == 0) { _G_pfpuop = ppcVfpPrimaryInit(pcMachineName, pcFpuName); } else { _DebugHandle(__ERRORMESSAGE_LEVEL, "unknown fpu name.\r\n"); return; } if (_G_pfpuop == LW_NULL) { return; } lib_bzero(&_G_fpuCtxInit, sizeof(LW_FPU_CONTEXT)); PPC_VFP_ENABLE(_G_pfpuop); PPC_VFP_SAVE(_G_pfpuop, (PVOID)&_G_fpuCtxInit); _G_fpuCtxInit.FPUCTX_fpuctxContext.FPUCTX_uiFpscr = 0x00000000; /* Do not enable FPU */ PPC_VFP_DISABLE(_G_pfpuop); }
/********************************************************************************************************* ** 函数名称: __tshellIfUp ** 功能描述: 系统命令 "ifup" ** 输 入 : iArgC 参数个数 ** ppcArgV 参数表 ** 输 出 : 0 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __tshellIfUp (INT iArgC, PCHAR *ppcArgV) { struct netif *netif; BOOL bUseDHCP = LW_FALSE; /* 是否使用自动获取 IP */ BOOL bShutDownDHCP = LW_FALSE; /* 是否强制关闭 DHCP */ if (iArgC < 2) { fprintf(stderr, "argments error!\n"); return (-ERROR_TSHELL_EPARAM); } else if (iArgC > 2) { if (lib_strcmp(ppcArgV[2], "-dhcp") == 0) { bUseDHCP = LW_TRUE; /* 使用 DHCP 启动 */ } else if (lib_strcmp(ppcArgV[2], "-nodhcp") == 0) { bShutDownDHCP = LW_TRUE; } } netif = netif_find(ppcArgV[1]); /* 查询网络接口 */ if (netif == LW_NULL) { fprintf(stderr, "can not find net interface.\n"); return (-ERROR_TSHELL_EPARAM); } if (netif_is_up(netif)) { /* 网卡是否已经启动 */ #if LWIP_DHCP > 0 /* 首先关闭网卡 */ if (netif->dhcp && netif->dhcp->pcb) { netifapi_netif_common(netif, NULL, dhcp_release); /* 解除 DHCP 租约 */ netifapi_dhcp_stop(netif); /* 释放资源 */ } #endif /* LWIP_DHCP > 0 */ netifapi_netif_set_down(netif); /* 禁用网卡 */ } netifapi_netif_set_up(netif); /* 启动网卡 */ #if LWIP_DHCP > 0 if (bUseDHCP) { netif->flags2 |= NETIF_FLAG2_DHCP; /* 使用 DHCP 启动 */ } else if (bShutDownDHCP) { netif->flags2 &= ~NETIF_FLAG2_DHCP; /* 强制关闭 DHCP */ } if (netif->flags2 & NETIF_FLAG2_DHCP) { ip_addr_t inaddrNone; lib_bzero(&inaddrNone, sizeof(ip_addr_t)); netifapi_netif_set_addr(netif, &inaddrNone, &inaddrNone, &inaddrNone); /* 所有地址设置为 0 */ printf("DHCP client starting...\n"); if (netifapi_dhcp_start(netif) < ERR_OK) { printf("DHCP client serious error.\n"); } else { printf("DHCP client start.\n"); } } #endif /* LWIP_DHCP > 0 */ printf("net interface \"%s\" set up.\n", ppcArgV[1]); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_BlkRawCreate ** 功能描述: 通过 /dev/blk/xxx 块设备生成一个 BLOCK 控制块 (只能内核程序调用). ** 输 入 : pcBlkName 块设备名称 ** bRdOnly 只读 ** bLogic 是否为逻辑分区 ** pblkraw 创建的 blk raw 控制块 ** 输 出 : ERROR_NONE or PX_ERROR ** 全局变量: ** 调用模块: ** API 函数 *********************************************************************************************************/ LW_API INT API_BlkRawCreate (CPCHAR pcBlkName, BOOL bRdOnly, BOOL bLogic, PLW_BLK_RAW pblkraw) { INT iFlag; INT iRet; if (!pcBlkName || !pblkraw) { _ErrorHandle(EINVAL); return (PX_ERROR); } iFlag = (bRdOnly) ? O_RDONLY : O_RDWR; lib_bzero(pblkraw, sizeof(LW_BLK_RAW)); pblkraw->BLKRAW_blkd.BLKD_pcName = lib_strdup(pcBlkName); if (pblkraw == LW_NULL) { _ErrorHandle(ENOMEM); return (PX_ERROR); } __KERNEL_SPACE_ENTER(); iRet = __blkRawCreate(pblkraw, iFlag, bLogic); __KERNEL_SPACE_EXIT(); if (iRet < ERROR_NONE) { __SHEAP_FREE(pblkraw); } return (iRet); }
/********************************************************************************************************* ** 函数名称: API_SdCoreDevGetStatus ** 功能描述: 得到卡的状态字 ** 输 入: psdcoredevice 设备结构指针 ** 输 出: puiStatus 状态 ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: ********************************************************************************************************/ INT API_SdCoreDevGetStatus (PLW_SDCORE_DEVICE psdcoredevice, UINT32 *puiStatus) { LW_SD_COMMAND sdcmd; UINT32 uiRca; INT iError; API_SdCoreDevRcaView(psdcoredevice, &uiRca); lib_bzero(&sdcmd, sizeof(sdcmd)); sdcmd.SDCMD_uiOpcode = SD_SEND_STATUS; sdcmd.SDCMD_uiFlag = SD_RSP_SPI_R2 | SD_RSP_R1 | SD_CMD_AC; sdcmd.SDCMD_uiArg = uiRca << 16; sdcmd.SDCMD_uiRetry = 0; iError = API_SdCoreDevCmd(psdcoredevice, &sdcmd, 1); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "send cmd13 failed.\r\n"); return (PX_ERROR); } *puiStatus = sdcmd.SDCMD_uiResp[0]; return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_SdCoreDevMmcSetRelativeAddr ** 功能描述: 设置MMC卡的RCA. ** MMC的本地地址是由用户设置的(SD是由卡获得的). ** 输 入: psdcoredevice 设备结构指针 ** uiRCA MMC的RCA ** 输 出: NONE ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT API_SdCoreDevMmcSetRelativeAddr (PLW_SDCORE_DEVICE psdcoredevice, UINT32 uiRCA) { INT iError; LW_SD_COMMAND sdcmd; if (!COREDEV_IS_SD(psdcoredevice)) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "function just for sd bus.\r\n"); return (PX_ERROR); } lib_bzero(&sdcmd, sizeof(LW_SD_COMMAND)); sdcmd.SDCMD_uiOpcode = SD_SEND_RELATIVE_ADDR; sdcmd.SDCMD_uiArg = uiRCA << 16; sdcmd.SDCMD_uiFlag = SD_RSP_R1 | SD_CMD_AC; iError = API_SdCoreDevCmd(psdcoredevice, &sdcmd, SD_CMD_GEN_RETRY); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "send cmd error.\r\n"); return (PX_ERROR); } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_PciDevInterDisonnect ** 功能描述: 设置 PCI 设备解除中断连接 ** 输 入 : hHandle 设备句柄 ** ulVector 中断向量 ** pfuncIsr 中断服务函数 ** pvArg 中断服务函数参数 ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: ** API 函数 *********************************************************************************************************/ LW_API INT API_PciDevInterDisonnect (PCI_DEV_HANDLE hHandle, ULONG ulVector, PINT_SVR_ROUTINE pfuncIsr, PVOID pvArg) { INT iRet = PX_ERROR; if (hHandle == LW_NULL) { return (PX_ERROR); } if ((hHandle->PDT_ulDevIrqVector != ulVector) || (hHandle->PDT_pfuncDevIrqHandle != pfuncIsr) || (hHandle->PDT_pvDevIrqArg != pvArg )) { return (PX_ERROR); } iRet = API_PciInterDisconnect(ulVector, pfuncIsr, pvArg); if (iRet != ERROR_NONE) { return (PX_ERROR); } lib_bzero(hHandle->PDT_cDevIrqName, PCI_DEV_IRQ_NAME_MAX); hHandle->PDT_pfuncDevIrqHandle = LW_NULL; hHandle->PDT_pvDevIrqArg = LW_NULL; return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __unix_smsg_proc ** 功能描述: 发送的 msg 失败或者消息还没有被接受就被删除了 ** 输 入 : pvMsgEx 扩展消息 ** uiLenEx 扩展消息长度 ** pidSend sender pid ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID __unix_smsg_unproc (PVOID pvMsgEx, socklen_t uiLenEx, pid_t pidSend) { INT i; struct cmsghdr *pcmhdr; struct msghdr msghdrBuf; if ((pvMsgEx == LW_NULL) || (uiLenEx < sizeof(struct cmsghdr))) { return; } lib_bzero(&msghdrBuf, sizeof(struct msghdr)); msghdrBuf.msg_control = pvMsgEx; msghdrBuf.msg_controllen = uiLenEx; pcmhdr = CMSG_FIRSTHDR(&msghdrBuf); while (pcmhdr) { if (pcmhdr->cmsg_level == SOL_SOCKET) { if (pcmhdr->cmsg_type == SCM_RIGHTS) { /* 传送文件描述符 */ INT *iFdArry = (INT *)CMSG_DATA(pcmhdr); INT iNum = (pcmhdr->cmsg_len - CMSG_LEN(0)) / sizeof(INT); for (i = 0; i < iNum; i++) { __unix_unflight(pidSend, iFdArry[i]); } } } pcmhdr = CMSG_NXTHDR(&msghdrBuf, pcmhdr); } }
/********************************************************************************************************* ** 函数名称: times ** 功能描述: shall fill the tms structure pointed to by buffer with time-accounting information. The tms structure is defined in <sys/times.h>. ** 输 入 : tms struct tms 参数 ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API clock_t times (struct tms *ptms) { #if LW_CFG_MODULELOADER_EN > 0 PVOID pvVProc = (PVOID)__LW_VP_GET_CUR_PROC(); if (!ptms) { errno = EINVAL; return (lib_clock()); } if (pvVProc) { API_ModuleTimes(pvVProc, &ptms->tms_utime, &ptms->tms_stime, &ptms->tms_cutime, &ptms->tms_cstime); return (lib_clock()); } #endif /* LW_CFG_MODULELOADER_EN > 0 */ lib_bzero(ptms, sizeof(struct tms)); return (lib_clock()); }
/********************************************************************************************************* ** 函数名称: lib_xzalloc ** 功能描述: 内存分配(清零) ** 输 入 : s 大小 ** 输 出 : 开辟成功返回内存地址, 否则直接退出线程. ** 全局变量: ** 调用模块: *********************************************************************************************************/ void *lib_xzalloc (size_t s) { PVOID pvMem = lib_xmalloc(s); if (pvMem) { lib_bzero(pvMem, s); } return (pvMem); }
/********************************************************************************************************* ** 函数名称: _evtfdOpen ** 功能描述: 打开 eventfd 设备 ** 输 入 : pevtfddev eventfd 设备 ** pcName 名称 ** iFlags 方式 ** iMode 方法 ** 输 出 : ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ static LONG _evtfdOpen (PLW_EVTFD_DEV pevtfddev, PCHAR pcName, INT iFlags, INT iMode) { PLW_EVTFD_FILE pevtfdfil; if (pcName == LW_NULL) { _DebugHandle(__ERRORMESSAGE_LEVEL, "device name invalidate.\r\n"); _ErrorHandle(ERROR_IO_NO_DEVICE_NAME_IN_PATH); return (PX_ERROR); } else { if (iFlags & O_CREAT) { _ErrorHandle(ERROR_IO_FILE_EXIST); return (PX_ERROR); } pevtfdfil = (PLW_EVTFD_FILE)__SHEAP_ALLOC(sizeof(LW_EVTFD_FILE)); if (!pevtfdfil) { _DebugHandle(__ERRORMESSAGE_LEVEL, "system low memory.\r\n"); _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY); return (PX_ERROR); } pevtfdfil->EF_iFlag = iFlags; pevtfdfil->EF_ulReadLock = API_SemaphoreBCreate("evtfd_rlock", LW_FALSE, LW_OPTION_OBJECT_GLOBAL, LW_NULL); if (pevtfdfil->EF_ulReadLock == LW_OBJECT_HANDLE_INVALID) { __SHEAP_FREE(pevtfdfil); return (PX_ERROR); } pevtfdfil->EF_ulWriteLock = API_SemaphoreBCreate("evtfd_wlock", LW_TRUE, LW_OPTION_OBJECT_GLOBAL, LW_NULL); if (pevtfdfil->EF_ulWriteLock == LW_OBJECT_HANDLE_INVALID) { API_SemaphoreBDelete(&pevtfdfil->EF_ulReadLock); __SHEAP_FREE(pevtfdfil); return (PX_ERROR); } pevtfdfil->EF_u64Counter = 0ull; lib_bzero(&pevtfdfil->EF_selwulist, sizeof(LW_SEL_WAKEUPLIST)); pevtfdfil->EF_selwulist.SELWUL_hListLock = _G_hEvtfdSelMutex; LW_SPIN_INIT(&pevtfdfil->EF_slLock); LW_DEV_INC_USE_COUNT(&_G_evtfddev.ED_devhdrHdr); return ((LONG)pevtfdfil); } }
/********************************************************************************************************* ** 函数名称: __ram_automem ** 功能描述: ramfs 根据需要设置文件缓冲区 ** 输 入 : pramn 文件节点 ** ulNBlk 需求缓冲数量 ** stStart 在此范围内不清零 ** stLen ** 输 出 : 增长结果 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __ram_automem (PRAM_NODE pramn, ULONG ulNBlk, size_t stStart, size_t stLen) { ULONG i; ULONG ulNeedAllocBlk; PRAM_VOLUME pramfs = pramn->RAMN_pramfs; size_t stCur; if (ulNBlk <= pramn->RAMN_ulCnt) { /* 实际数目够用 */ return (ERROR_NONE); } else { /* 需要增加块 */ PRAM_BUFFER pramb; ulNeedAllocBlk = ulNBlk - pramn->RAMN_ulCnt; if ((ulNeedAllocBlk + pramfs->RAMFS_ulCurBlk) > pramfs->RAMFS_ulMaxBlk) { /* 超过文件系统大小限制 */ _ErrorHandle(ENOSPC); return (PX_ERROR); } stCur = (size_t)pramn->RAMN_ulCnt * __RAM_BDATASIZE; for (i = 0; i < ulNeedAllocBlk; i++) { pramb = (PRAM_BUFFER)__RAM_BALLOC(__RAM_BSIZE); if (pramb == LW_NULL) { _ErrorHandle(ENOSPC); return (PX_ERROR); } if (((stCur < stStart) && ((stCur + __RAM_BDATASIZE) <= stStart)) || ((stCur > stStart) && (stCur >= (stStart + stLen)))) { /* 判断数据区是否要清零 */ lib_bzero(pramb->RAMB_ucData, __RAM_BDATASIZE); } if (pramn->RAMN_plineBEnd) { /* 存在末尾块 */ _List_Line_Add_Right(&pramb->RAMB_lineManage, pramn->RAMN_plineBEnd); pramn->RAMN_plineBEnd = &pramb->RAMB_lineManage; } else { /* 没有缓冲 */ _List_Line_Add_Ahead(&pramb->RAMB_lineManage, &pramn->RAMN_plineBStart); pramn->RAMN_plineBEnd = pramn->RAMN_plineBStart; } pramfs->RAMFS_ulCurBlk++; pramn->RAMN_ulCnt++; } return (ERROR_NONE); } }
/********************************************************************************************************* ** 函数名称: API_SdCoreDevSendAllCSD ** 功能描述: 获得卡的CSD ** 输 入: psdcoredevice 设备结构指针 ** 输 出: psdcsd 卡应答的CSD(已经解码) ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT API_SdCoreDevSendAllCSD (PLW_SDCORE_DEVICE psdcoredevice, LW_SDDEV_CSD *psdcsd) { INT iError; LW_SD_COMMAND sdcmd; UINT32 uiRca; UINT8 pucCsdBuf[16]; UINT8 ucType; if (!psdcsd) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "parameter error.\r\n"); return (PX_ERROR); } iError = API_SdCoreDevRcaView(psdcoredevice, &uiRca); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "device without rca.\r\n"); return (PX_ERROR); } lib_bzero(&sdcmd, sizeof(LW_SD_COMMAND)); sdcmd.SDCMD_uiOpcode = SD_SEND_CSD; sdcmd.SDCMD_uiArg = COREDEV_IS_SPI(psdcoredevice) ? 0 : uiRca << 16; sdcmd.SDCMD_uiFlag = SD_RSP_SPI_R1 | SD_RSP_R2 | SD_CMD_BCR; iError = API_SdCoreDevCmd(psdcoredevice, &sdcmd, SD_CMD_GEN_RETRY); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "send cmd error.\r\n"); return (PX_ERROR); } /* * SD模式直接从命令的应答中获取 */ API_SdCoreDevTypeView(psdcoredevice, &ucType); if (COREDEV_IS_SD(psdcoredevice)) { API_SdCoreDecodeCSD(psdcsd, sdcmd.SDCMD_uiResp, ucType); return (ERROR_NONE); } /* * SPI 模式 */ API_SdCoreSpiRegisterRead(psdcoredevice, pucCsdBuf, 16); API_SdCoreSpiCxdFormat(sdcmd.SDCMD_uiResp, pucCsdBuf); API_SdCoreDecodeCSD(psdcsd, sdcmd.SDCMD_uiResp, ucType); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_SdCoreDecodeCID ** 功能描述: 解码CID ** 输 入: pRawCID 原始CID数据 ** ucType 卡的类型 ** 输 出: psdcidDec 解码后的CID ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT API_SdCoreDecodeCID (LW_SDDEV_CID *psdcidDec, UINT32 *pRawCID, UINT8 ucType) { if (!psdcidDec || !pRawCID) { _ErrorHandle(EINVAL); return (PX_ERROR); } lib_bzero(psdcidDec, sizeof(LW_SDDEV_CID)); switch (ucType) { case SDDEV_TYPE_MMC: psdcidDec->DEVCID_ucMainFid = __getBits(pRawCID, 120, 8); psdcidDec->DEVCID_usOemId = __getBits(pRawCID, 104, 16); psdcidDec->DEVCID_pucProductName[0] = __getBits(pRawCID, 88, 8); psdcidDec->DEVCID_pucProductName[1] = __getBits(pRawCID, 80, 8); psdcidDec->DEVCID_pucProductName[2] = __getBits(pRawCID, 72, 8); psdcidDec->DEVCID_pucProductName[3] = __getBits(pRawCID, 64, 8); psdcidDec->DEVCID_pucProductName[4] = __getBits(pRawCID, 56, 8); psdcidDec->DEVCID_ucProductVsn = __getBits(pRawCID, 48, 8); psdcidDec->DEVCID_uiSerialNum = __getBits(pRawCID, 16, 32); psdcidDec->DEVCID_ucMonth = __getBits(pRawCID, 12, 4); psdcidDec->DEVCID_uiYear = __getBits(pRawCID, 8, 4); psdcidDec->DEVCID_uiYear += 1997; break; default: psdcidDec->DEVCID_ucMainFid = __getBits(pRawCID, 120, 8); psdcidDec->DEVCID_usOemId = __getBits(pRawCID, 104, 16); psdcidDec->DEVCID_pucProductName[0] = __getBits(pRawCID, 96, 8); psdcidDec->DEVCID_pucProductName[1] = __getBits(pRawCID, 88, 8); psdcidDec->DEVCID_pucProductName[2] = __getBits(pRawCID, 80, 8); psdcidDec->DEVCID_pucProductName[3] = __getBits(pRawCID, 72, 8); psdcidDec->DEVCID_pucProductName[4] = __getBits(pRawCID, 64, 8); psdcidDec->DEVCID_ucProductVsn = __getBits(pRawCID, 56, 8); psdcidDec->DEVCID_uiSerialNum = __getBits(pRawCID, 24, 32); psdcidDec->DEVCID_uiYear = __getBits(pRawCID, 12, 8); psdcidDec->DEVCID_ucMonth = __getBits(pRawCID, 8, 4); psdcidDec->DEVCID_uiYear += 2000; break; } #ifdef __SYLIXOS_DEBUG __printCID(psdcidDec, ucType); #endif /* __SYLIXOS_DEBUG */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_PciDevAdd ** 功能描述: 增加一个设备 ** 输 入 : iBus 总线号 ** iDevice 设备号 ** iFunction 功能号 ** 输 出 : 设备控制句柄 ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API PCI_DEV_HANDLE API_PciDevAdd (INT iBus, INT iDevice, INT iFunction) { PCI_DEV_HANDLE hDevHandle = LW_NULL; PCI_HDR phPciHdr; hDevHandle = API_PciDevHandleGet(iBus, iDevice, iFunction); if (hDevHandle != LW_NULL) { return (hDevHandle); } lib_bzero(&phPciHdr, sizeof(PCI_HDR)); API_PciGetHeader(iBus, iDevice, iFunction, &phPciHdr); switch (phPciHdr.PCIH_ucType & PCI_HEADER_TYPE_MASK) { case PCI_HEADER_TYPE_NORMAL: hDevHandle = (PCI_DEV_HANDLE)__SHEAP_ZALLOC(sizeof(PCI_DEV_TCB)); if (hDevHandle == LW_NULL) { _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY); break; } hDevHandle->PDT_iDevBus = iBus; hDevHandle->PDT_iDevDevice = iDevice; hDevHandle->PDT_iDevFunction = iFunction; lib_memcpy(&hDevHandle->PDT_phDevHdr, &phPciHdr, sizeof(PCI_HDR)); __PCI_DEV_LOCK(); _List_Line_Add_Ahead(&hDevHandle->PDT_lineDevNode, &_GplinePciDevHeader); _GuiPciDevTotalNum += 1; __PCI_DEV_UNLOCK(); break; case PCI_HEADER_TYPE_BRIDGE: case PCI_HEADER_TYPE_CARDBUS: hDevHandle = LW_NULL; break; default: hDevHandle = LW_NULL; break; } return (hDevHandle); }
/********************************************************************************************************* ** 函数名称: __ram_read ** 功能描述: ramfs 读取文件内容 ** 输 入 : pramn 文件节点 ** pvBuffer 缓冲区 ** stSize 缓冲区大小 ** stOft 偏移量 ** 输 出 : 读取的字节数 ** 全局变量: ** 调用模块: *********************************************************************************************************/ ssize_t __ram_read (PRAM_NODE pramn, PVOID pvBuffer, size_t stSize, size_t stOft) { PRAM_BUFFER pramb; UINT8 *pucDest = (UINT8 *)pvBuffer; size_t stDataLeft; size_t stNBytes; size_t stRead = 0; size_t stStart; if (pramn->RAMN_stVSize <= stOft) { /* 已经到文件末尾 */ return (0); } stDataLeft = pramn->RAMN_stVSize - stOft; /* 计算剩余数据量 */ stNBytes = __MIN(stDataLeft, stSize); pramb = __ram_getbuf(pramn, stOft, &stStart); do { if (pramb == LW_NULL) { /* 需要填充 0 (POSIX) */ lib_bzero(pucDest, stNBytes); stRead += stNBytes; break; } else { size_t stBufSize = (__RAM_BDATASIZE - stStart); if (stBufSize >= stNBytes) { lib_memcpy(pucDest, &pramb->RAMB_ucData[stStart], stNBytes); stRead += stNBytes; break; } else { lib_memcpy(pucDest, &pramb->RAMB_ucData[stStart], stBufSize); pucDest += stBufSize; stRead += stBufSize; stNBytes -= stBufSize; stStart = 0; /* 下次拷贝从头开始 */ } } pramb = __ram_getbuf_next(pramn); } while (stNBytes); return ((ssize_t)stRead); }
/********************************************************************************************************* ** 函数名称: API_SdCoreDevSetBusWidth ** 功能描述: 设置总线通信位宽 ** 输 入: psdcoredevice 设备结构指针 ** 输 出: NONE ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: ********************************************************************************************************/ INT API_SdCoreDevSetBusWidth (PLW_SDCORE_DEVICE psdcoredevice, INT iBusWidth) { INT iError = ERROR_NONE; LW_SD_COMMAND sdcmd; iError = API_SdCoreDevSelect(psdcoredevice); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "select device failed.\r\n"); return (PX_ERROR); } if (!psdcoredevice) { API_SdCoreDevDeSelect(psdcoredevice); SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "parameter error.\r\n"); _ErrorHandle(EINVAL); return (PX_ERROR); } if ((iBusWidth != SDBUS_WIDTH_1) && (iBusWidth != SDBUS_WIDTH_4)) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "invalid bus width in current sd version.\r\n"); API_SdCoreDevDeSelect(psdcoredevice); return (PX_ERROR); } /* * 只在SD模式下才设置, SPI模式下忽略 */ if (COREDEV_IS_SD(psdcoredevice)) { lib_bzero(&sdcmd, sizeof(sdcmd)); sdcmd.SDCMD_uiOpcode = APP_SET_BUS_WIDTH; sdcmd.SDCMD_uiFlag = SD_RSP_R1 | SD_CMD_AC; sdcmd.SDCMD_uiArg = iBusWidth; iError = API_SdCoreDevAppCmd(psdcoredevice, &sdcmd, LW_FALSE, 0); } API_SdCoreDevDeSelect(psdcoredevice); return (iError); }
/********************************************************************************************************* ** 函数名称: API_SdCoreDevSendAllCID ** 功能描述: 获得卡的CID ** 输 入: psdcoredevice 设备结构指针 ** 输 出: psdcid 卡应答的CID(已经解码) ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT API_SdCoreDevSendAllCID (PLW_SDCORE_DEVICE psdcoredevice, LW_SDDEV_CID *psdcid) { INT iError; LW_SD_COMMAND sdcmd; UINT8 pucCidBuf[16]; UINT8 ucType; if (!psdcid) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "parameter error.\r\n"); return (PX_ERROR); } lib_bzero(&sdcmd, sizeof(LW_SD_COMMAND)); sdcmd.SDCMD_uiOpcode = COREDEV_IS_SD(psdcoredevice) ? SD_ALL_SEND_CID : SD_SEND_CID; sdcmd.SDCMD_uiArg = 0; sdcmd.SDCMD_uiFlag = SD_RSP_SPI_R1 | SD_RSP_R2 | SD_CMD_BCR; iError = API_SdCoreDevCmd(psdcoredevice, &sdcmd, SD_CMD_GEN_RETRY); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "send cmd error.\r\n"); return (PX_ERROR); } /* * SD模式下直接用命令获取CID */ API_SdCoreDevTypeView(psdcoredevice, &ucType); if (COREDEV_IS_SD(psdcoredevice)) { API_SdCoreDecodeCID(psdcid, sdcmd.SDCMD_uiResp, ucType); return (ERROR_NONE); } /* * SPI模式使用特殊的读CID寄存器方式 */ API_SdCoreSpiRegisterRead(psdcoredevice, pucCidBuf, 16); API_SdCoreSpiCxdFormat(sdcmd.SDCMD_uiResp, pucCidBuf); API_SdCoreDecodeCID(psdcid, sdcmd.SDCMD_uiResp, ucType); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __tshellReadlineInit ** 功能描述: shell 初始化 readline. ** 输 入 : NONE ** 输 出 : 初始化是否成功 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __tshellReadlineInit (VOID) { PLW_CLASS_TCB ptcbCur; __PSHELL_HISTORY_CTX psihc; LW_TCB_GET_CUR_SAFE(ptcbCur); psihc = __TTINY_SHELL_GET_HIS(ptcbCur); if (psihc == LW_NULL) { psihc = (__PSHELL_HISTORY_CTX)__SHEAP_ALLOC(sizeof(__SHELL_HISTORY_CTX)); if (psihc == LW_NULL) { fprintf(stderr, "read line tool no memory!\n"); return (PX_ERROR); } lib_bzero(psihc, sizeof(__SHELL_HISTORY_CTX)); __TTINY_SHELL_SET_HIS(ptcbCur, psihc); } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __sdCoreSelectDev ** 功能描述: 设备选择 ** 输 入: psdcoredevice 设备结构指针 ** bSel 选择\取消 ** 输 出: NONE ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __sdCoreSelectDev (PLW_SDCORE_DEVICE psdcoredevice, BOOL bSel) { INT iError; LW_SD_COMMAND sdcmd; UINT32 uiRca; if (COREDEV_IS_SPI(psdcoredevice)) { /* SPI设备使用物理片选 */ return (ERROR_NONE); } iError = API_SdCoreDevRcaView(psdcoredevice, &uiRca); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "device without rca.\r\n"); return (PX_ERROR); } lib_bzero(&sdcmd, sizeof(LW_SD_COMMAND)); sdcmd.SDCMD_uiOpcode = SD_SELECT_CARD; if (bSel) { sdcmd.SDCMD_uiArg = uiRca << 16; sdcmd.SDCMD_uiFlag = SD_RSP_R1B | SD_CMD_AC; } else { sdcmd.SDCMD_uiArg = 0; sdcmd.SDCMD_uiFlag = SD_RSP_NONE | SD_CMD_BC; } iError = API_SdCoreDevCmd(psdcoredevice, &sdcmd, SD_CMD_GEN_RETRY); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "send cmd error.\r\n"); return (PX_ERROR); } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_SdCoreDevSetPreBlkLen ** 功能描述: 设置预先擦除块计数.在 "<多块写>" 操作中,该功能用于让卡预先擦除指定的块大小,这样可以提高速度. ** 输 入: psdcoredevice 设备结构指针 ** iPreBlkLen 块大小 ** 输 出: NONE ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: ********************************************************************************************************/ INT API_SdCoreDevSetPreBlkLen (PLW_SDCORE_DEVICE psdcoredevice, INT iPreBlkLen) { LW_SD_COMMAND sdcmd; INT iError; lib_bzero(&sdcmd, sizeof(sdcmd)); sdcmd.SDCMD_uiOpcode = SD_SET_BLOCK_COUNT; sdcmd.SDCMD_uiFlag = SD_RSP_SPI_R1 | SD_RSP_R1 | SD_CMD_AC; sdcmd.SDCMD_uiArg = iPreBlkLen; sdcmd.SDCMD_uiRetry = 0; iError = API_SdCoreDevAppCmd(psdcoredevice, &sdcmd, LW_FALSE, 1); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "send acmd23 failed.\r\n"); return (PX_ERROR); } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: __areaSpaceInit ** 功能描述: 初始化地址空间管理块 ** 输 入 : pvmarea 地址空间管理块 ** ulAddr 起始地址 ** stSize 大小 ** 输 出 : ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static ULONG __areaSpaceInit (PLW_VMM_AREA pvmarea, addr_t ulAddr, size_t stSize) { INT i; REGISTER ULONG ulHashSize; for (i = 0; ; i++) { if (_G_ulVmmAreaHashSizeTbl[i][0] == 0) { ulHashSize = _G_ulVmmAreaHashSizeTbl[i][1]; /* 最大表大小 */ break; } else { if (stSize >= _G_ulVmmAreaHashSizeTbl[i][0]) { continue; } else { ulHashSize = _G_ulVmmAreaHashSizeTbl[i][1]; /* 确定 */ break; } } } pvmarea->AREA_ulAreaAddr = ulAddr; pvmarea->AREA_stAreaSize = stSize; pvmarea->AREA_ulHashSize = ulHashSize; pvmarea->AREA_ptrbrHash = (PLW_TREE_RB_ROOT)__KHEAP_ALLOC(sizeof(PLW_TREE_RB_ROOT) * (size_t)ulHashSize); if (pvmarea->AREA_ptrbrHash == LW_NULL) { _DebugHandle(__ERRORMESSAGE_LEVEL, "kernel low memory.\r\n"); _ErrorHandle(ERROR_KERNEL_LOW_MEMORY); /* 缺少内核内存 */ return (ERROR_KERNEL_LOW_MEMORY); } lib_bzero(pvmarea->AREA_ptrbrHash, (size_t)(sizeof(PLW_TREE_RB_ROOT) * ulHashSize)); /* 清空 hash 表 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_RomFsDrvInstall ** 功能描述: 安装 romfs 文件系统驱动程序 ** 输 入 : ** 输 出 : < 0 表示失败 ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT API_RomFsDrvInstall (VOID) { struct file_operations fileop; if (_G_iRomfsDrvNum > 0) { return (ERROR_NONE); } lib_bzero(&fileop, sizeof(struct file_operations)); fileop.owner = THIS_MODULE; fileop.fo_create = __romFsOpen; fileop.fo_release = __romFsRemove; fileop.fo_open = __romFsOpen; fileop.fo_close = __romFsClose; fileop.fo_read = __romFsRead; fileop.fo_read_ex = __romFsPRead; fileop.fo_write = __romFsWrite; fileop.fo_write_ex = __romFsPWrite; fileop.fo_lstat = __romFsLStat; fileop.fo_ioctl = __romFsIoctl; fileop.fo_readlink = __romFsReadlink; _G_iRomfsDrvNum = iosDrvInstallEx2(&fileop, LW_DRV_TYPE_NEW_1); /* 使用 NEW_1 型设备驱动程序 */ DRIVER_LICENSE(_G_iRomfsDrvNum, "GPL->Ver 2.0"); DRIVER_AUTHOR(_G_iRomfsDrvNum, "Han.hui"); DRIVER_DESCRIPTION(_G_iRomfsDrvNum, "romfs driver."); _DebugHandle(__LOGMESSAGE_LEVEL, "rom file system installed.\r\n"); __fsRegister("romfs", API_RomFsDevCreate); /* 注册文件系统 */ return ((_G_iRomfsDrvNum > 0) ? (ERROR_NONE) : (PX_ERROR)); }
/********************************************************************************************************* ** 函数名称: API_SdCoreDevReset ** 功能描述: 复位设备 ** 输 入: psdcoredevice 设备结构指针 ** 输 出: NONE ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT API_SdCoreDevReset (PLW_SDCORE_DEVICE psdcoredevice) { LW_SD_COMMAND sdcmd; INT iError; INT iRetry = 50; /* 重试 50 次复位命令 */ lib_bzero(&sdcmd, sizeof(LW_SD_COMMAND)); sdcmd.SDCMD_uiOpcode = SD_GO_IDLE_STATE; sdcmd.SDCMD_uiArg = 0; sdcmd.SDCMD_uiFlag = SD_RSP_SPI_R1 | SD_RSP_NONE | SD_CMD_BC; do { SD_DELAYMS(1); iError = API_SdCoreDevCmd(psdcoredevice, &sdcmd, 0); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "send reset cmd error.\r\n"); return (PX_ERROR); } if (COREDEV_IS_SD(psdcoredevice)) { /* SD模式下不检查响应 */ return (ERROR_NONE); } if ((sdcmd.SDCMD_uiResp[0] == 0x01)) { return (ERROR_NONE); } } while (iRetry--); if (iRetry <= 0) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "reset timeout.\r\n"); return (PX_ERROR); } return (ERROR_NONE); /* PREVENT WARNING */ }
/********************************************************************************************************* ** 函数名称: __tshellCharTab ** 功能描述: shell 收到一个 tab 按键. ** 输 入 : iFd 文件描述符 ** psicContext 当前输入上下文 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __tshellCharTab (INT iFd, __PSHELL_INPUT_CTX psicContext) { #define __TTINY_SHELL_CMD_ISWHITE(pcCmd) \ ((*(pcCmd) == ' ') || (*(pcCmd) == '\t') || (*(pcCmd) == '\r') || (*(pcCmd) == '\n')) #define __TTINY_SHELL_CMD_ISEND(pcCmd) (*(pcCmd) == PX_EOS) INT i; PCHAR pcCmd; size_t stStrLen; CHAR cCommandBuffer[MAX_FILENAME_LENGTH]; PCHAR pcParamList[LW_CFG_SHELL_MAX_PARAMNUM + 1]; /* 参数列表 */ PCHAR pcDir; PCHAR pcFileName; REGISTER ULONG ulError; if (CTX_CURSOR < CTX_TOTAL) { /* 将光标移动到行末 */ __tshellTtyCursorMoveRight(iFd, CTX_TOTAL - CTX_CURSOR); CTX_CURSOR = CTX_TOTAL; } CTX_BUFFER[CTX_TOTAL] = PX_EOS; /* 假设命令结束 */ pcCmd = CTX_BUFFER; if (!pcCmd || __TTINY_SHELL_CMD_ISEND(pcCmd)) { /* 命令错误 */ return; } while (__TTINY_SHELL_CMD_ISWHITE(pcCmd)) { /* 过滤前面的不可见字符 */ pcCmd++; if (__TTINY_SHELL_CMD_ISEND(pcCmd)) { return; /* 不是有效的命令字 */ } } if (*pcCmd == '#') { /* 注释行直接忽略 */ return; } stStrLen = lib_strnlen(pcCmd, LW_CFG_SHELL_MAX_COMMANDLEN + 1); /* 计算字符串长短 */ if ((stStrLen > LW_CFG_SHELL_MAX_COMMANDLEN - 1) || (stStrLen < 1)) { /* 字符串长度错误 */ return; } lib_bzero(cCommandBuffer, LW_CFG_SHELL_MAX_COMMANDLEN); /* 清空 cCommandBuffer 缓冲区 */ ulError = __tshellStrConvertVar(CTX_BUFFER, cCommandBuffer); /* 变量替换 */ if (ulError) { return; } __tshellStrFormat(cCommandBuffer, cCommandBuffer); /* 整理 shell 命令 */ pcParamList[0] = cCommandBuffer; for (i = 0; i < LW_CFG_SHELL_MAX_PARAMNUM; i++) { /* 开始查询参数 */ __tshellStrGetToken(pcParamList[i], &pcParamList[i + 1]); __tshellStrDelTransChar(pcParamList[i], pcParamList[i]); /* 删除转义字符与非转义引号 */ if (pcParamList[i + 1] == LW_NULL) { /* 参数结束 */ break; } } pcDir = pcParamList[i]; /* 仅分析最后一个字段 */ if (pcDir == LW_NULL) { return; } if (lib_strlen(pcDir) == 0) { /* 没有内容, 当前目录 */ pcDir = "."; pcFileName = ""; __tshellFileMatch(iFd, pcDir, pcFileName, psicContext); /* 显示目录下指定匹配的文件 */ return; } pcFileName = lib_rindex(pcDir, PX_DIVIDER); if (pcFileName == LW_NULL) { /* 当前目录 */ pcFileName = pcDir; pcDir = "."; } else { if (pcFileName == pcDir) { /* 根目录下第一级目录 */ pcDir = PX_STR_DIVIDER; pcFileName++; } else { *pcFileName = PX_EOS; pcFileName++; } } __tshellFileMatch(iFd, pcDir, pcFileName, psicContext); /* 显示目录下指定匹配的文件 */ }
/********************************************************************************************************* ** 函数名称: API_SdCoreDevSendAppOpCond ** 功能描述: 发送ACMD41. ** 当该命令的参数OCR为0,称作"查询ACMD41",效果同CMD8. ** 当该命令的参数OCR不为0,称作"第一个ACMD41",用来启动卡初始化的同时,决定最终的操作电压. ** 该函数为了一次性测出卡的类型(MMC),所以增加了MMC的识别. ** 输 入: psdcoredevice 设备结构指针 ** uiOCR 代表适配器的OCR ** 输 出: psddevocrOut 设备应答的OCR信息 ** pucType 设备的类型 ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT API_SdCoreDevSendAppOpCond (PLW_SDCORE_DEVICE psdcoredevice, UINT32 uiOCR, LW_SDDEV_OCR *psddevocrOut, UINT8 *pucType) { LW_SD_COMMAND sdcmd; INT iError; INT i; BOOL bMmc = LW_FALSE; if (!psddevocrOut) { _ErrorHandle(EINVAL); return (PX_ERROR); } /* * 首先针对SD卡作初始化 */ lib_bzero(&sdcmd, sizeof(LW_SD_COMMAND)); sdcmd.SDCMD_uiOpcode = APP_SD_SEND_OP_COND; /* * 存储卡设备的电压范围为2.7 ~ 3.6 v,如果主控提供的电压有不在这个范围内的,则该函数会失败. */ sdcmd.SDCMD_uiArg = (uiOCR & SD_OCR_HCS) ? (uiOCR & SD_OCR_MEM_VDD_MSK) | SD_OCR_HCS : (uiOCR & SD_OCR_MEM_VDD_MSK); sdcmd.SDCMD_uiFlag = SD_RSP_SPI_R1| SD_RSP_R3 | SD_CMD_BCR; for (i = 0; i < (SD_OPCOND_DELAY_CONTS); i++) { iError = API_SdCoreDevAppCmd(psdcoredevice, &sdcmd, LW_FALSE, SD_CMD_GEN_RETRY); if (iError != ERROR_NONE) { goto __mmc_ident; } /* * 对于查询ACMD41,只需要一次 */ if (uiOCR == 0) { break; } if (COREDEV_IS_SPI(psdcoredevice)) { if (!(sdcmd.SDCMD_uiResp[0] & R1_SPI_IDLE)) { /* spi 模式下,r1 的最低位清零 */ break; } } else { if (sdcmd.SDCMD_uiResp[0] & SD_OCR_BUSY) { /* busy置位,表示完成 */ /* 进入ready 状态 */ break; } } SD_DELAYMS(2); } if (i >= SD_OPCOND_DELAY_CONTS) { /* sd卡识别失败 */ goto __mmc_ident; } else { goto __ident_done; } __mmc_ident: /* mmc 识别 */ /* * 加入MMC的识别 */ API_SdCoreDevReset(psdcoredevice); sdcmd.SDCMD_uiOpcode = SD_SEND_OP_COND; sdcmd.SDCMD_uiArg = COREDEV_IS_SPI(psdcoredevice) ? 0 : (uiOCR | SD_OCR_HCS); sdcmd.SDCMD_uiFlag = SD_RSP_SPI_R1 | SD_RSP_R3 | SD_CMD_BCR; sdcmd.SDCMD_uiRetry = 3; for (i = 0; i < SD_OPCOND_DELAY_CONTS; i++) { iError = API_SdCoreDevCmd(psdcoredevice, &sdcmd, 0); if (iError != ERROR_NONE) { /* 错误退出 */ SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "can't send cmd1.\r\n"); return (iError); } if (uiOCR == 0) { break; } if (COREDEV_IS_SPI(psdcoredevice)) { if (!(sdcmd.SDCMD_uiResp[0] & R1_SPI_IDLE)) { /* spi 模式下,r1 的最低位清零 */ break; } } else { if (sdcmd.SDCMD_uiResp[0] & SD_OCR_BUSY) { /* busy置位,表示完成 */ /* 进入ready 状态 */ break; } } } if (i >= SD_OPCOND_DELAY_CONTS) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "timeout(may device is not sd or mmc card).\r\n"); return (PX_ERROR); } else { bMmc = LW_TRUE; } __ident_done: /* 识别完成 */ if (COREDEV_IS_SD(psdcoredevice)) { *psddevocrOut = sdcmd.SDCMD_uiResp[0]; } else { /* * SPI 模式下使用专有命令读取设备OCR寄存器 */ lib_bzero(&sdcmd, sizeof(LW_SD_COMMAND)); sdcmd.SDCMD_uiOpcode = SD_SPI_READ_OCR; sdcmd.SDCMD_uiArg = 0; /* TODO: 默认支持HIGH CAP */ sdcmd.SDCMD_uiFlag = SD_RSP_SPI_R3; iError = API_SdCoreDevCmd(psdcoredevice, &sdcmd, 1); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "spi read ocr error.\r\n"); return (iError); } *psddevocrOut = sdcmd.SDCMD_uiResp[1]; } /* * 判断设备类型 * TODO:SDXC ? */ if (bMmc) { *pucType = SDDEV_TYPE_MMC; } else if (*psddevocrOut & SD_OCR_HCS) { *pucType = SDDEV_TYPE_SDHC; } else { *pucType = SDDEV_TYPE_SDSC; } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: API_SdCoreDevSendIfCond ** 功能描述: 检查卡操作接口条件(CMD8).在复位之后,主机并不知道卡能支持的电压是多少,或在哪个范围. ** 于是CMD8(SEND_IF_COND)就用来做这个事. ** 输 入: psdcoredevice 设备结构指针 ** 输 出: NONE ** 返 回: ERROR CODE ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT API_SdCoreDevSendIfCond (PLW_SDCORE_DEVICE psdcoredevice) { LW_SD_COMMAND sdcmd; INT iError; UINT8 ucChkPattern = 0xaa; /* 标准建议在Cmd8中使用0xaa校验 */ UINT32 uiOCR; /* * 获得适配器的电源支持情况 */ iError = API_SdCoreDevCtl(psdcoredevice, SDBUS_CTRL_GETOCR, (LONG)&uiOCR); if (iError != ERROR_NONE) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "get adapter ocr failed.\r\n"); return (PX_ERROR); } lib_bzero(&sdcmd, sizeof(LW_SD_COMMAND)); sdcmd.SDCMD_uiOpcode = SD_SEND_IF_COND; sdcmd.SDCMD_uiFlag = SD_RSP_SPI_R7 | SD_RSP_R7 | SD_CMD_BCR; /* * 在SD_SEND_IF_COND(Cmd8)里面的有效参数格式: * ---------------------------------------------------------- * bits: | 4 | 8 | * ......| HVS(host vol support) | check pattern |...... * ---------------------------------------------------------- * 目前版本里面的HVS只定义了一个值1表示适配器支持2.7~3.6V的电压. */ sdcmd.SDCMD_uiArg = (((uiOCR & SD_OCR_MEM_VDD_MSK) != 0) << 8) | ucChkPattern; iError = API_SdCoreDevCmd(psdcoredevice, &sdcmd, 0); /* * 对于Cmd8,如果卡支持参数中的uiOCR信息,那么会回送这些信息, * 否则,不会应答,并且卡自身进入空闲模式. * TODO: 告诉上层具体失败的原因. */ if (iError == ERROR_NONE) { if (COREDEV_IS_SD(psdcoredevice)) { ucChkPattern = sdcmd.SDCMD_uiResp[0] & 0xff; } else if (COREDEV_IS_SPI(psdcoredevice)) { ucChkPattern = sdcmd.SDCMD_uiResp[1] & 0xff; } else { return (PX_ERROR); } if (ucChkPattern != 0xaa) { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "the check pattern is not correct, it maybe I/0 error.\r\n"); return (PX_ERROR); } else { return (ERROR_NONE); } } else { SDCARD_DEBUG_MSG(__ERRORMESSAGE_LEVEL, "the device can't supply the voltage.\r\n"); return (PX_ERROR); } }