void Write_To_SD_Card(const char* fileName, const char* pMode, const void* pData, U32 NumBytes) { // Remember to add line below to rtcCallBack Function // Write_To_SD_Card("myData.txt","a",sendBuffer,strlen(sendBuffer)); NEOMOTE_1_SD_Card_Power_Write(0u); // Power on the SD Card FS_FILE * pFile; char sdVolName[10]; // Buffer that will hold SD card Volume name if (0 != FS_GetVolumeName(0, &sdVolName[0], 9)) { pFile = FS_FOpen(fileName, pMode); if (pFile == 0){ FS_DeInit(); FS_Init(); //poipoi debug error pFile = FS_FOpen(fileName, pMode); } FS_Write(pFile, pData, NumBytes); FS_FClose(pFile); } NEOMOTE_1_SD_Card_Power_Write(1u); // Power off the SD Card }
void MainTask(void) { unsigned i; U32 Space; U32 NumLoops; U32 NumBytes; U32 NumBytesAtOnce; FS_FILE * pFile; I32 t; FS_Init(); _TestNo = -1; // // Check if we need to low-level format the volume // if (FS_IsLLFormatted(VOLUME_NAME) == 0) { FS_X_Log("Low level formatting\n"); FS_FormatLow(VOLUME_NAME); /* Erase & Low-level format the flash */ } // // Volume is always high level formatted // before doing any performance tests. // FS_X_Log("High level formatting\n"); #if FS_SUPPORT_FAT if (FS_FormatSD(VOLUME_NAME) == 0) { #else if (FS_Format(VOLUME_NAME, NULL) == 0) { #endif // // Disable that the directory entry is every time // updated after a write operation // FS_ConfigUpdateDirOnWrite(0); // // Fill the buffer with data // FS_MEMSET((void*)_aBuffer, 'a', sizeof(_aBuffer)); // // Get some general info // Space = FS_GetVolumeFreeSpace(VOLUME_NAME); Space = MIN(Space, FILE_SIZE); NumBytes = BLOCK_SIZE * NUM_BLOCKS_MEASURE; NumBytesAtOnce = BLOCK_SIZE; NumLoops = Space / NumBytes; // // Create file of full size // _StartTest("W", NumBytes); pFile = FS_FOpen(FILE_NAME, "w"); // // Preallocate the file, setting the file pointer to the highest position // and declare it as the end of the file. // FS_SetFilePos(pFile, Space, FS_FILE_BEGIN); FS_SetEndOfFile(pFile); // // Set file position to the beginning // FS_SetFilePos(pFile, 0, FS_FILE_BEGIN); // // Check write performance with clusters/file size preallocated // sprintf(_ac, "Writing %lu chunks of %lu Bytes: ", NumLoops, NumBytes); FS_X_Log(_ac); for (i = 0; i < NumLoops ; i++) { t = _WriteFile(pFile, &_aBuffer[0], NumBytesAtOnce); _StoreResult(t); FS_X_Log("."); } FS_X_Log("OK\n"); FS_FClose(pFile); // // Check read performance // _StartTest("R", NumBytes); sprintf(_ac, "Reading %lu chunks of %lu Bytes: " , NumLoops, NumBytes); FS_X_Log(_ac); pFile = FS_FOpen(FILE_NAME, "r"); for (i = 0; i < NumLoops; i++) { t = _ReadFile(pFile, _aBuffer, NumBytesAtOnce); _StoreResult(t); FS_X_Log("."); } FS_X_Log("OK\n\n"); FS_FClose(pFile); // // Show results for performance list // for (i = 0; i <= (unsigned)_TestNo; i++) { sprintf(_ac, "%s Speed: %f kByte/s\n", _aResult[i].sName, _GetAverage(i)); FS_X_Log(_ac); } FS_X_Log("Finished\n"); FS_Unmount(VOLUME_NAME); } else { FS_X_Log("Volume could not be formatted!\n"); } while (1) { ; } }
void SpiFlashDownFromSD(bool ForceDownload,const u8 *CfgPath,u8 *FileBuf,u8 *PageBuf) { u8 Buffer2[16]; u8 *pTmp; u8 *pSecStart[MaxSecItem]; u8 *pSecEnd[MaxSecItem]; u8 *pAddr[MaxDownItem]; u8 *pBinPath[MaxDownItem]; u8 EarseSecFlag; //存储每个文件的匹配结果 u8 CurSecItem=0;//当前解析的扇区配置项 u8 CurDownItemNum=0;//当前扇区项下面的下载项个数 u8 *pCfg; int i,j; UINT ReadByte; u32 SecStart,SecEnd; FS_FILE *pFileObj; //打开配置文件 if((CfgPath[0]==0)||(CfgPath==NULL)) return; if ((pFileObj=FS_FOpen((void *)CfgPath, FA_OPEN_EXISTING | FA_READ)) == 0 ) { Debug("Cannot open file \"%s\"\n\r",CfgPath); return; } //读取配置文件 if((ReadByte=FS_FRead((void *)FileBuf, CfgFileSize,1,pFileObj ))==0) { Debug("Read cfg file error!\n\r"); FS_FClose(pFileObj); return; } //Debug("Cfg content:\n\r%s\n\r",Cfg); //关闭配置文件 if( FS_FClose(pFileObj) == -1 ) { Debug("Close file error\n"); return; } pCfg=FileBuf; //检查配置文件版本 if((pTmp=(void *)strstr((void *)pCfg,"#"))==NULL) return; if((pCfg=(void *)strstr((void *)pTmp,";"))==NULL) return; pTmp++; *pCfg++=0; if(strcmp((void *)pTmp,"m25p16 1.0")) { Debug("Cfg file %s version is error!(%s!=%s)\n\r",CfgPath,"m25p16 1.0",pTmp); return; } //检查配置项完整性 if((pTmp=(void *)strstr((void *)pCfg,"$"))==NULL) return; *pTmp++=0; //开始提取配置文件内容 while(1) { *pTmp='%';//恢复上一个扇区项 //先获取扇区项 if((pSecStart[CurSecItem]=(void *)strstr((void *)pCfg,"%"))==NULL) return; if((pSecEnd[CurSecItem]=(void *)strstr((void *)pSecStart[CurSecItem],"-"))==NULL) return; if((pCfg=(void *)strstr((void *)pSecEnd[CurSecItem],";"))==NULL) return; *pSecStart[CurSecItem]++=0; *pSecEnd[CurSecItem]++=0; *pCfg++=0; Debug("Current SectorItem:%d,SecStart:%s,SecEnd:%s\n\r",CurSecItem,pSecStart[CurSecItem],pSecEnd[CurSecItem]); SecStart=StrToUint((void *)pSecStart[CurSecItem]); SecEnd=StrToUint((void *)pSecEnd[CurSecItem]); if(SecStart>SecEnd) return;//扇区错误 if(SecEnd>31) return;//扇区错误 EarseSecFlag=0;//置0擦除标志 if((pTmp=(void *)strstr((void *)pCfg,"%"))!=NULL) *pTmp=0;//先屏蔽下一个扇区项 else pTmp=FileBuf; //再获取下载项 for(i=0; i<MaxDownItem; i++) { if((pBinPath[i]=(void *)strstr((void *)pCfg,"="))==NULL) return;//找到文件路径 if((pAddr[i]=(void *)strstr((void *)pBinPath[i],"@"))==NULL) return;//找到起始页数 if((pCfg=(void *)strstr((void *)pAddr[i],";"))==NULL) return;//找到本条结尾位置 *pBinPath[i]++=0; *pAddr[i]++=0; *pCfg++=0; Debug("=%s download to page %s\n\r",pBinPath[i],pAddr[i]); if(strstr((void *)pCfg,"=")==NULL) //也没有下一个下载项了 { i++; break; } } CurDownItemNum=i; Debug("Current DownItem Max Num:%d\n\r",CurDownItemNum); if(!ForceDownload) { for(i=0; i<CurDownItemNum; i++) { //打开bin文件 if ((pFileObj=FS_FOpen((void *)pBinPath[i], FA_OPEN_EXISTING | FA_READ)) ==0 ) { Debug("Cannot open file %s,Cancle download\n\r",pBinPath[i]); return; } //对比每个下载项文件和flash page的头16字节内容 if((ReadByte=FS_FRead((void *)PageBuf, sizeof(Buffer2), 1,pFileObj)) != 0) { if(ReadByte) { //读取spi flash内容进行匹配 Q_SpiFlashSync(FlashRead,SPI_FLASH_PAGE_SIZE*StrToUint((void *)pAddr[i]),sizeof(Buffer2),Buffer2); for(j=0; j<sizeof(Buffer2); j++) { //Debug("%x?=%x\n\r",Buffer2[j],Buffer[j]); if(Buffer2[j]!=PageBuf[j]) { EarseSecFlag=1; Debug("We need erase sectors becase of file %s first %d bytes.\n\r",pBinPath[i],sizeof(Buffer2)); if( FS_FClose(pFileObj) == -1 ) Debug("Close file %s error\n",pBinPath[i]); goto Erase; } } //if(j==sizeof(Buffer2)) //{ // Debug("We needn't download file %s to spi flash\n\r",pBinPath[i]); //} } else //没有读到内容 { Debug("File %s is NULL,cancle download\n\r",pBinPath[i]); return; } } //对比每个下载项文件和flash page的尾16字节内容 FS_FSeek(pFileObj,-sizeof(Buffer2),FS_SEEK_END); if((ReadByte=FS_FRead((void *)PageBuf, sizeof(Buffer2), 1,pFileObj)) != 0) { if(ReadByte) { //读取spi flash内容进行匹配 Q_SpiFlashSync(FlashRead, SPI_FLASH_PAGE_SIZE*StrToUint((void *)pAddr[i])+FS_GetFileSize(pFileObj)-sizeof(Buffer2), sizeof(Buffer2),Buffer2); for(j=0; j<sizeof(Buffer2); j++) { //Debug("%x?=%x\n\r",Buffer2[j],Buffer[j]); if(Buffer2[j]!=PageBuf[j]) { EarseSecFlag=1; Debug("We need erase sectors becase of file %s last %d byte.\n\r",pBinPath[i],sizeof(Buffer2)); if( FS_FClose(pFileObj) == -1 ) Debug("Close file %s error\n",pBinPath[i]); goto Erase; } } if(j==sizeof(Buffer2)) { Debug("We needn't download file %s to spi flash\n\r",pBinPath[i]); } } else //没有读到内容 { Debug("File %s is NULL,cancle download\n\r",pBinPath[i]); return; } } if( FS_FClose(pFileObj) == -1 ) Debug("Close file %s error\n",pBinPath[i]); } } Erase: //擦除扇区 if(EarseSecFlag||ForceDownload) { for(i=SecStart; i<=SecEnd; i++) { Debug("Erase sector %d(page %d to %d)\n\r",i,i<<8,(i<<8)+256); Q_SpiFlashSync(FlashSectorEarse,i<<16,0,NULL); } //烧录文件 for(i=0; i<CurDownItemNum; i++) { Debug("#Download %s ",pBinPath[i]); if ((pFileObj=FS_FOpen((void *)pBinPath[i], FA_OPEN_EXISTING | FA_READ)) == 0 ) { Debug("Cannot open file %s\n\r",pBinPath[i]); return; } for(ReadByte=0,j=StrToUint((void *)pAddr[i]);; j++) { if((ReadByte=FS_FRead((void *)PageBuf, SPI_FLASH_PAGE_SIZE, 1,pFileObj)) != 0) { //读到非0个数据 Q_SpiFlashSync(FlashWrite,j*SPI_FLASH_PAGE_SIZE,ReadByte,PageBuf); Debug("."); //显示进度条 } else //读到0个数据,说明读到文件末了 { break; } } Debug("\n\rHave Download \"%s\" to spi flash,from page %d to page %d\n\r",pBinPath[i],StrToUint((void *)pAddr[i]),j-1); if( FS_FClose(pFileObj) == -1 ) Debug("Close file %s error\n",pBinPath[i]); } } if(++CurSecItem==MaxSecItem) return;//下一个扇区项 } }
FS_i32 FS_FileCpy(const TCHAR*path1, const TCHAR*path2) //path1: souce file path2: destination file { FS_FILE *src; FS_FILE * dst; FS_i32 read_size,write_size; FS_i32 src_size, dst_size; struct stat buf; _DISK_INFO info; FS_i8 *buffer; if( !strcmp((const char *)path1, (const char *)path2) ) { FS_Debug("FSW_ERROR:can not copy a file to itself\r\n"); return 0; } if( -1 == FS_Stat( path1, &buf ) ) return 0; src_size = buf.st_size; if(GetDiskInfo(path2,&info)==-1) { FS_Debug("FSW_ERROR:getdiskinfo err\r\n"); return 0; } if(src_size > info.free_size) { FS_Debug("there is no enough space on the flash!\n\r"); return 0; } src = FS_FOpen(path1, FA_READ|FA_OPEN_EXISTING); if(0 == src) { FS_Debug("FSW_ERROR:cannot open the source file\r\n"); return 0; } dst = FS_FOpen(path2, FA_CREATE_ALWAYS|FA_WRITE); if(0 == dst) { FS_Debug("FSW_ERROR:cannot create the distance file\r\n"); FS_FClose(src); return 0; } buffer=Q_Mallco(COPY_FILE_BUFFER); do{ read_size = FS_FRead(buffer, COPY_FILE_BUFFER,1,src); write_size = FS_FWrite(buffer, read_size,1,dst); if(write_size < read_size) { FS_Debug("FSW_ERROR:file write error\r\n"); Q_Free(buffer); goto CP_FILE_ERROR; } }while(read_size == COPY_FILE_BUFFER); Q_Free(buffer); FS_FClose(src); FS_FClose(dst); if( -1 == FS_Stat( path2, &buf ) ) return 0; dst_size = buf.st_size; if(dst_size < src_size) { FS_Debug("there is an unkown flash operation during the copyfile!\n\r"); FS_Unlink(path2); return 0; } return 1; CP_FILE_ERROR: FS_FClose(src); FS_FClose(dst); return 0; }
int CyBtldr_SD_Bootload(char * file){ char cyacd_header[10]; char cyacd_line[589]; unsigned char cyacd_arrayId; uint16 cyacd_rowAddress; char cyacd_rowData[288]; uint16 cyacd_rowSize; unsigned char cyacd_checksum; unsigned long siliconId; unsigned char siliconRev; int err=CYRET_SUCCESS; int Flash_err=CYRET_SUCCESS; /*Initialize Flash Write Mechanism*/ if(!INIT_FLASH_WRITE){ /*If the Flash Write wasnt initialized successfully, fire a software reset and hope things will work out.*/ CYBTLDR_SW_RESET; } /*Initialize the emFile FS*/ FS_Init(); /*Open the File for reading */ dataFile = FS_FOpen(file, "r"); /*File Opened*/ if (NULL != dataFile && FS_FEof(dataFile)!=1){ err=FS_Read(dataFile,cyacd_header,10); /* Read the Header line from the CYACD file.*/ if (err!=0){ /* Send the file pointer ahead by 4,setting it to the start of the first row */ err=FS_FSeek( dataFile,4, FS_SEEK_CUR); /*Parse the header for SiliconID and SiliconRev*/ err=CyBtldr_ParseHeader(10,cyacd_header,&siliconId,&siliconRev); /*Heres where you should check the SiliconID and Rev.*/ /* if(CYSWAP_ENDIAN32(CYDEV_CHIP_JTAG_ID)==siliconID && CYDEV_CHIP_REV_EXPECT==siliconRev){ }else{ }*/ }else{ /*We have EOF or a NULL dataFile FS structure.*/ err = CYRET_ERR_EOF; return err; } /*Lets get to the real stuff.*/ while(1){ /*Read the First Line after the header.*/ err=CyBtldr_ReadLine(cyacd_line); /*Check if the line was read successfully.*/ if(err!=CYRET_SUCCESS){ break; } /*Parse the line to get Row Address,Row Data,Row Size and the Checksum Byte*/ err=CyBtldr_ParseRowData(589,cyacd_line,&cyacd_arrayId,&cyacd_rowAddress,&cyacd_rowData,&cyacd_rowSize,&cyacd_checksum); /*Check if the data was parsed successfully.*/ if(err!=CYRET_SUCCESS){ break; } /*Write the Row Data to flash*/ CyWriteRowFull(cyacd_arrayId,cyacd_rowAddress,cyacd_rowData,cyacd_rowSize); } /*Close the File*/ err=FS_FClose(dataFile); /*Fire a software reset.*/ CYBTLDR_SW_RESET; return err; } return err; }