⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flashdsk-080.cpp

📁 一个29f800的flash驱动代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    return pdir;
}
//根据起始FAT表项找到相应偏移量所对应的FAT
DWORD SearchFat(DWORD startFat,DWORD offset)
{
    DWORD prev = startFat;
    DWORD next = startFat;

    for(int i=0;i<offset/LOGIC_SECTOR_SIZE;i++)
    {
        next = pMapFat[prev];
        if((next == FAT_SYSTEM)||(next==FAT_RESERVED)||(next==FAT_REMOVE))
        {
            next=0xFFFFFFFF;
            break;
        }
        else if(next == FAT_FILEEND)
        {
            next = AllocFreeBlock(prev);
            break;
        }
        else
        {
            prev = next;
        }
    }
    
    return next;
}

void LoadFatInfo(TOpenFile *pFile)
{
    DWORD fat=SearchFat(pFile->dwFileFat,pFile->dwReadOffset);

    for(int i=0;i<8;i++)
    {
        if(fat != 0xFFFFFFFF)
            pFile->aAddrIndex[i] = (BYTE*)(fat*LOGIC_SECTOR_SIZE+(BYTE*)FLASH_DISK_BASE);
        else
        {
            pFile->aAddrIndex[i] = NULL;
            break;
        }
        fat = pMapFat[fat];
        if(fat >0xFFF0)
        {
            fat = 0xFFFFFFFF;
//          pFile->aAddrIndex[i] = NULL;
            break;
        }
    }
}

DWORD AllocFreeBlock(DWORD prevFat)
{
    DWORD fat=0xFFFFFFFF;
    DWORD i;
     
    // Find free logic sector in current disk
    for( i=0; i<FAT_ENTRY_NUM; i++ )
    {
        if(pMapFat[i] == FAT_FREE)
        {
            fat = i;
            pMapFat[i] = FAT_FILEEND;
            SetMapChangeFlag(&pMapFat[i]);
            
            if( prevFat<FAT_ENTRY_NUM )
            {
                pMapFat[prevFat] = i;
                SetMapChangeFlag(&pMapFat[prevFat]);
            }
            break;
        }
    }
                                             
    /*
    // If the currect disk is full, clear up disk and find free logic sector 
    // in new disk.
    if( fat==0xffffffff )
    {                                 
        ClearUpDisk();

        for( i=0; i<FAT_ENTRY_NUM; i++ )
        {
            if(pMapFat[i] == FAT_FREE)
            {
                fat = i;
                pMapFat[i] = FAT_FILEEND;
                SetMapChangeFlag(&pMapFat[i]);
                
                if( prevFat<FAT_ENTRY_NUM )
                {
                    pMapFat[prevFat] = i;
                    SetMapChangeFlag(&pMapFat[prevFat]);
                }
                break;
            }
        }
    }
    */

    if( fat==0xffffffff )
    {                                 
        for(int i=0;i<FAT_ENTRY_NUM;i++)
        {
            if(pMapFat[i] == FAT_REMOVE)
            {
                fat = i;
                pMapFat[i] = FAT_FILEEND;
                SetMapChangeFlag(&pMapFat[i]);

                if(prevFat < FAT_ENTRY_NUM)
                {
                    pMapFat[prevFat] = i;
                    SetMapChangeFlag(&pMapFat[prevFat]);
                }
                break;
            }
        }
    }

    return fat;
}

void SetMapChangeFlag(void *buf)
{
    BYTE *pBuf = (BYTE*)buf;
    for(int i=0;i<dwSysPhSecNum;i++)
    {
        if((pBuf > pMapSysSec[i].pOffset)&&(pBuf < pMapSysSec[i].pOffset+pMapSysSec[i].dwSize)) 
        {   
            pMapSysSec[i].wStatus = MS_CHANGE; 
            break;  
        }   
    }
}

BOOL BlankCheck(DWORD sector)
{
    BYTE *pBuf = (BYTE*)((BYTE*)pDiskDesp+sector*LOGIC_SECTOR_SIZE);
    for(int i=0;i<LOGIC_SECTOR_SIZE;i++)
    {
        if(pBuf[i] != 0xFF)
            return FALSE;
    }
    return TRUE;
} 

//磁盘镜像到磁盘系统区
DWORD Map2Disk(DWORD flag)
{
#if (__RAM_FILE == NO)

    BYTE *pDest;
    BYTE *pSrc;
    DWORD i,temp; 

    for(i=0;i<dwSysPhSecNum;i++)
    {         
        if( pMapSysSec[i].wStatus == MS_CHANGE )	//deleted by zqz 2002/12/12
        {
            // Clear change flag.
            pMapSysSec[i].wStatus = 0;

            // Erase the system sector.
            Sector_Erase(pMapSysSec[i].nSector);

            // Update system sector.
            pSrc  = (BYTE*)pMapSysSec[i].pOffset;
            temp  = pMapSysSec[i].nSector;
            pDest = (BYTE*)pMapDesp->phSector[temp].dwOffset;
            WriteBlock2Disk( pDest,pSrc,pMapSysSec[i].dwSize);
        }
    }                
#endif
    return 0;
}

DWORD Write2Cache(TOpenFile *pFile,BYTE *buf,DWORD count)
{
    DWORD num = count;
    TWriteCache *pCache = (TWriteCache *)pFile->WriteCache.GetTail();
    DWORD offset = pFile->dwWriteOffset % LOGIC_SECTOR_SIZE;

    pCache->dwOffset = offset;
    /*计算可以写的字节数*/
    if(count > (LOGIC_SECTOR_SIZE-pCache->dwLength))
        count = LOGIC_SECTOR_SIZE-pCache->dwLength;
    memcpy(&pCache->aData[pCache->dwLength],buf,count);
    pCache->dwLength = count;   
    pFile->dwWriteOffset += count;
    //ydd
    if( FD_OPEN_MODIFY != pFile->dwMode )
        pFile->dwFileLength += count;
    pFile->pEntry->dwLength = pFile->dwFileLength;
    return count;
}

//文件系统和磁盘接口
//写一块缓冲区到磁盘
void WriteBlock2Disk(void *pFlash,void *pbuf,DWORD num)
{
#if (__RAM_FILE == YES)
    memcpy((DWORD)pFlash+pDiskBase,pbuf,num);
#else
    DWORD rc,backup,offset;
    DWORD ph=0;
    int i;
    DWORD fatStart=0;
    TPhySector *pSector;
    void *pSrc, *pDest;
    
    rc = Data_Program(pFlash,pbuf,num);
    if( rc )	
    {
        //得到该地址对应的物理扇区号和备分扇区号
        ph = GetPhysicalSector(pFlash); 
        backup = pMapDesp->dwBackupSector;

        //擦除用于备份的物理扇区
        //EraseSector(backup);	
        //把该物理扇区中的数据备份到备份扇区
        pSector = &pMapDesp->phSector[ph];
        //计算该物理扇区在文件分配表中的位置
        fatStart = pSector->dwOffset/LOGIC_SECTOR_SIZE;
        
        memset(WriteFileBuf, 0, 0x10000);
        for(i=0;i<pSector->dwSize/LOGIC_SECTOR_SIZE;i++)
        {
            if((pMapFat[fatStart+i]<FAT_ENTRY_NUM)||(pMapFat[fatStart+i]==FAT_FILEEND))
            {
                pSrc = (void *)(pMapDesp->phSector[ph].dwOffset+i*LOGIC_SECTOR_SIZE+FLASH_DISK_BASE);
                pDest= (void *)(pMapDesp->phSector[backup].dwOffset+i*LOGIC_SECTOR_SIZE);
                //Data_Program(pDest,pSrc,LOGIC_SECTOR_SIZE);	
                memcpy(WriteFileBuf+i*LOGIC_SECTOR_SIZE, pSrc, LOGIC_SECTOR_SIZE);
            }
            if(pMapFat[fatStart+i]==FAT_REMOVE)
                pMapFat[fatStart+i] = FAT_FREE;  //modify by wcq in 2001.10.6 ,form == to =	
        }

        //删除该物理扇区
        EraseSector(ph);

        DWORD temp;
        temp = (DWORD)pFlash;
        memcpy((void*)(WriteFileBuf+temp%0x10000), (void*)pbuf, num);

        for(i=0;i<pSector->dwSize/LOGIC_SECTOR_SIZE;i++)
        {
            if((pMapFat[fatStart+i]<FAT_ENTRY_NUM)||(pMapFat[fatStart+i]==FAT_FILEEND))
            {
                pDest= (void *)(pMapDesp->phSector[ph].dwOffset+i*LOGIC_SECTOR_SIZE);
                pSrc = (void *)(pMapDesp->phSector[backup].dwOffset+i*LOGIC_SECTOR_SIZE+FLASH_DISK_BASE);
                //Data_Program(pDest,pSrc,LOGIC_SECTOR_SIZE);	
                Data_Program(pDest, (void*)(WriteFileBuf+i*LOGIC_SECTOR_SIZE), LOGIC_SECTOR_SIZE);
            }
        }
    }

#endif
}

// 整理磁盘,清除磁盘中被标记为删除的逻辑扇区
DWORD ClearUpDisk()
{
    void  *pSrc,*pDest;                                        
    DWORD i,j,backup;
    DWORD fatstart,fatnum;
    
    // backup sector                  
    backup = pMapDesp->dwBackupSector;
    
    // Clear the data sector
    for( i=0; i<pMapDesp->nPhSector; i++ )
    {
        // If the physical sector is not file data sector, overleap it.
        if( pFlashSec[i].dwMode == PSM_FILE )
        {
            // Erase backup sector
            Sector_Erase(backup);

            // Copy data from current data sector to backup sector
            fatstart = pMapDesp->phSector[i].dwOffset / LOGIC_SECTOR_SIZE;
            fatnum   = pMapDesp->phSector[i].dwSize / LOGIC_SECTOR_SIZE;

            for( j=0; j<fatnum; j++ )
            {
                if((pMapFat[fatstart+j]<FAT_ENTRY_NUM)||(pMapFat[fatstart+j]==FAT_FILEEND))
                {   
                    pSrc = (void *)(pMapDesp->phSector[i].dwOffset+i*LOGIC_SECTOR_SIZE+FLASH_DISK_BASE);
                    pDest= (void *)(pMapDesp->phSector[backup].dwOffset+i*LOGIC_SECTOR_SIZE);
                    Data_Program(pDest,pSrc,LOGIC_SECTOR_SIZE);
                }
                else if(pMapFat[fatstart+j]==FAT_REMOVE)
                {
                    //modified by zqz 2002/12/11	
                    pMapFat[fatstart+j] = FAT_FREE;
                }           
            }  

            // Erase data sector
            Sector_Erase(i);
            
            // Copy data from backup sector to data sector
            for( j=0; j<fatnum; j++)
            {
                if((pMapFat[fatstart+j]<FAT_ENTRY_NUM)||(pMapFat[fatstart+j]==FAT_FILEEND))
                {
                    pDest= (void *)(pMapDesp->phSector[i].dwOffset+i*LOGIC_SECTOR_SIZE);
                    pSrc = (void *)(pMapDesp->phSector[backup].dwOffset+i*LOGIC_SECTOR_SIZE+FLASH_DISK_BASE);
                    Data_Program(pDest,pSrc,LOGIC_SECTOR_SIZE);
                }
            }        
        }
    }                       

    // Set System sector change flag
    SetMapChangeFlag(pMapFat);      

    return 0;
}

DWORD WriteBack(DWORD hFile)
{
    TOpenFile *pFile = (TOpenFile*)hFile;
                
    // Check parameter
    if(pFile->dwMagic != OPEN_FILE)
    {
        DebugInfo('W','B','1');
        return 1;
    }   
    
    // Write file data to flash.
    Cache2Disk(pFile);         
    
    // Reset file length.
    pFile->pEntry->dwLength = pFile->dwFileLength;

    // Release opened file descriptor
    FreeFilePool.AddTail(&pFile->Node);

    // Write system area to flash.
    Map2Disk(); 

    DebugInfo('W','B','K');
    return 0;
}

DWORD ChangeDir(char *name)
{
    TDirectory *pdir;
    DWORD fat;
    
    //{{
    ToLower(name);
    //}}

    pdir = GetDirEntry(name);
    //提供的路径不正确
    if(pdir == NULL)
        return 2;
    //不是文件目录
    if(pdir->wType != FT_SUBDIR)
        return 3;
    fat = pdir->dwOffset;
    fat = (DWORD)pMapDir+LOGIC_SECTOR_SIZE*fat;
    pCurrentDir = (TDirectory*)fat;
    return 0;
}

DWORD Cache2Disk(TOpenFile *pFile)
{
    TWriteCache *pWrite=(TWriteCache*)pFile->WriteCache.RemoveHead();
    BYTE *pBuf;
    while(pWrite!= NULL)
    {
        pBuf = (BYTE*)(pWrite->dwSector*LOGIC_SECTOR_SIZE+pWrite->dwOffset);
        WriteBlock2Disk(pBuf,pWrite->aData,pWrite->dwLength);
        WriteCachePool.AddTail(&pWrite->Node);
        pWrite=(TWriteCache*)pFile->WriteCache.RemoveHead();
    }
}           

DWORD DebugInfo(BYTE ch1,BYTE ch2,BYTE ch3)
{
    return 0;
#if 0
    static num;
    TTest[num++]=ch1;
    TTest[num++]=ch2;
    TTest[num++]=ch3;
    TTest[num++]=*((BYTE *)CLOCK_PORT_MSECONDL);
    TTest[num++]=*((BYTE *)CLOCK_PORT_MSECONDH);
    if(num>4000)num=0;
#endif
}
ULONG change_dir(char *name)
{
    return 1;
}
ULONG stat_vfs(char *name, struct statvfs *buf)
{
    return 1;
}

#endif //(INSTALL_FLASHDISK == YES)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -