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

📄 landzo

📁 【开源】线性CCD自适应性算法攻略
💻
📖 第 1 页 / 共 5 页
字号:
    {
        for (i = 0; i < _FS_SHARE && Files[i].fs; i++) ;
        if (i == _FS_SHARE) return 0;	/* No space to register (int err) */
        Files[i].fs = dj->fs;
        Files[i].clu = dj->sclust;
        Files[i].idx = dj->index;
        Files[i].ctr = 0;
    }

    if (acc && Files[i].ctr) return 0;	/* Access violation (int err) */

    Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1;	/* Set semaphore value */

    return i + 1;
}


static
FRESULT dec_lock (	/* Decrement file open counter */
    UINT i			/* Semaphore index */
)
{
    WORD n;
    FRESULT res;


    if (--i < _FS_SHARE)
    {
        n = Files[i].ctr;
        if (n == 0x100) n = 0;
        if (n) n--;
        Files[i].ctr = n;
        if (!n) Files[i].fs = 0;
        res = FR_OK;
    }
    else
    {
        res = FR_INT_ERR;
    }
    return res;
}


static
void clear_lock (	/* Clear lock entries of the volume */
    FATFS *fs
)
{
    UINT i;

    for (i = 0; i < _FS_SHARE; i++)
    {
        if (Files[i].fs == fs) Files[i].fs = 0;
    }
}
#endif



/*-----------------------------------------------------------------------*/
/* Change window offset                                                  */
/*-----------------------------------------------------------------------*/

static
FRESULT move_window (
    FATFS *fs,		/* File system object */
    DWORD sector	/* Sector number to make appearance in the fs->win[] */
)					/* Move to zero only writes back dirty window */
{
    DWORD wsect;


    wsect = fs->winsect;
    if (wsect != sector)  	/* Changed current window */
    {
#if !_FS_READONLY
        if (fs->wflag)  	/* Write back dirty window if needed */
        {
            if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK)
                return FR_DISK_ERR;
            fs->wflag = 0;
            if (wsect < (fs->fatbase + fs->fsize))  	/* In FAT area */
            {
                BYTE nf;
                for (nf = fs->n_fats; nf > 1; nf--)  	/* Reflect the change to all FAT copies */
                {
                    wsect += fs->fsize;
                    disk_write(fs->drv, fs->win, wsect, 1);
                }
            }
        }
#endif
        if (sector)
        {
            if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK)
                return FR_DISK_ERR;
            fs->winsect = sector;
        }
    }

    return FR_OK;
}




/*-----------------------------------------------------------------------*/
/* Clean-up cached data                                                  */
/*-----------------------------------------------------------------------*/
#if !_FS_READONLY
static
FRESULT sync (	/* FR_OK: successful, FR_DISK_ERR: failed */
    FATFS *fs	/* File system object */
)
{
    FRESULT res;


    res = move_window(fs, 0);
    if (res == FR_OK)
    {
        /* Update FSInfo sector if needed */
        if (fs->fs_type == FS_FAT32 && fs->fsi_flag)
        {
            fs->winsect = 0;
            /* Create FSInfo structure */
            mem_set(fs->win, 0, 512);
            ST_WORD(fs->win + BS_55AA, 0xAA55);
            ST_DWORD(fs->win + FSI_LeadSig, 0x41615252);
            ST_DWORD(fs->win + FSI_StrucSig, 0x61417272);
            ST_DWORD(fs->win + FSI_Free_Count, fs->free_clust);
            ST_DWORD(fs->win + FSI_Nxt_Free, fs->last_clust);
            /* Write it into the FSInfo sector */
            disk_write(fs->drv, fs->win, fs->fsi_sector, 1);
            fs->fsi_flag = 0;
        }
        /* Make sure that no pending write process in the physical drive */
        if (disk_ioctl(fs->drv, CTRL_SYNC, 0) != RES_OK)
            res = FR_DISK_ERR;
    }

    return res;
}
#endif




/*-----------------------------------------------------------------------*/
/* Get sector# from cluster#                                             */
/*-----------------------------------------------------------------------*/


DWORD clust2sect (	/* !=0: Sector number, 0: Failed - invalid cluster# */
    FATFS *fs,		/* File system object */
    DWORD clst		/* Cluster# to be converted */
)
{
    clst -= 2;
    if (clst >= (fs->n_fatent - 2)) return 0;		/* Invalid cluster# */
    return clst * fs->csize + fs->database;
}




/*-----------------------------------------------------------------------*/
/* FAT access - Read value of a FAT entry                                */
/*-----------------------------------------------------------------------*/


DWORD get_fat (	/* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */
    FATFS *fs,	/* File system object */
    DWORD clst	/* Cluster# to get the link information */
)
{
    UINT wc, bc;
    BYTE *p;


    if (clst < 2 || clst >= fs->n_fatent)	/* Chack range */
        return 1;

    switch (fs->fs_type)
    {
    case FS_FAT12 :
        bc = (UINT)clst;
        bc += bc / 2;
        if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
        wc = fs->win[bc % SS(fs)];
        bc++;
        if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
        wc |= fs->win[bc % SS(fs)] << 8;
        return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);

    case FS_FAT16 :
        if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break;
        p = &fs->win[clst * 2 % SS(fs)];
        return LD_WORD(p);

    case FS_FAT32 :
        if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break;
        p = &fs->win[clst * 4 % SS(fs)];
        return LD_DWORD(p) & 0x0FFFFFFF;
    }

    return 0xFFFFFFFF;	/* An error occurred at the disk I/O layer */
}




/*-----------------------------------------------------------------------*/
/* FAT access - Change value of a FAT entry                              */
/*-----------------------------------------------------------------------*/
#if !_FS_READONLY

FRESULT put_fat (
    FATFS *fs,	/* File system object */
    DWORD clst,	/* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */
    DWORD val	/* New value to mark the cluster */
)
{
    UINT bc;
    BYTE *p;
    FRESULT res;


    if (clst < 2 || clst >= fs->n_fatent)  	/* Check range */
    {
        res = FR_INT_ERR;

    }
    else
    {
        switch (fs->fs_type)
        {
        case FS_FAT12 :
            bc = clst;
            bc += bc / 2;
            res = move_window(fs, fs->fatbase + (bc / SS(fs)));
            if (res != FR_OK) break;
            p = &fs->win[bc % SS(fs)];
            *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
            bc++;
            fs->wflag = 1;
            res = move_window(fs, fs->fatbase + (bc / SS(fs)));
            if (res != FR_OK) break;
            p = &fs->win[bc % SS(fs)];
            *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
            break;

        case FS_FAT16 :
            res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));
            if (res != FR_OK) break;
            p = &fs->win[clst * 2 % SS(fs)];
            ST_WORD(p, (WORD)val);
            break;

        case FS_FAT32 :
            res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));
            if (res != FR_OK) break;
            p = &fs->win[clst * 4 % SS(fs)];
            val |= LD_DWORD(p) & 0xF0000000;
            ST_DWORD(p, val);
            break;

        default :
            res = FR_INT_ERR;
        }
        fs->wflag = 1;
    }

    return res;
}
#endif /* !_FS_READONLY */




/*-----------------------------------------------------------------------*/
/* FAT handling - Remove a cluster chain                                 */
/*-----------------------------------------------------------------------*/
#if !_FS_READONLY
static
FRESULT remove_chain (
    FATFS *fs,			/* File system object */
    DWORD clst			/* Cluster# to remove a chain from */
)
{
    FRESULT res;
    DWORD nxt;
#if _USE_ERASE
    DWORD scl = clst, ecl = clst, resion[2];
#endif

    if (clst < 2 || clst >= fs->n_fatent)  	/* Check range */
    {
        res = FR_INT_ERR;

    }
    else
    {
        res = FR_OK;
        while (clst < fs->n_fatent)  			/* Not a last link? */
        {
            nxt = get_fat(fs, clst);			/* Get cluster status */
            if (nxt == 0) break;				/* Empty cluster? */
            if (nxt == 1)
            {
                res = FR_INT_ERR;    /* Internal error? */
                break;
            }
            if (nxt == 0xFFFFFFFF)
            {
                res = FR_DISK_ERR;    /* Disk error? */
                break;
            }
            res = put_fat(fs, clst, 0);			/* Mark the cluster "empty" */
            if (res != FR_OK) break;
            if (fs->free_clust != 0xFFFFFFFF)  	/* Update FSInfo */
            {
                fs->free_clust++;
                fs->fsi_flag = 1;
            }
#if _USE_ERASE
            if (ecl + 1 == nxt)  	/* Next cluster is contiguous */
            {
                ecl = nxt;
            }
            else  				/* End of contiguous clusters */
            {
                resion[0] = clust2sect(fs, scl);					/* Start sector */
                resion[1] = clust2sect(fs, ecl) + fs->csize - 1;	/* End sector */
                disk_ioctl(fs->drv, CTRL_ERASE_SECTOR, resion);		/* Erase the block */
                scl = ecl = nxt;

⌨️ 快捷键说明

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