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

📄 landzo

📁 【开源】线性CCD自适应性算法攻略
💻
📖 第 1 页 / 共 5 页
字号:
            }
#endif
            clst = nxt;	/* Next cluster */
        }
    }

    return res;
}
#endif




/*-----------------------------------------------------------------------*/
/* FAT handling - Stretch or Create a cluster chain                      */
/*-----------------------------------------------------------------------*/
#if !_FS_READONLY
static
DWORD create_chain (	/* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */
    FATFS *fs,			/* File system object */
    DWORD clst			/* Cluster# to stretch. 0 means create a new chain. */
)
{
    DWORD cs, ncl, scl;
    FRESULT res;


    if (clst == 0)  		/* Create a new chain */
    {
        scl = fs->last_clust;			/* Get suggested start point */
        if (!scl || scl >= fs->n_fatent) scl = 1;
    }
    else  					/* Stretch the current chain */
    {
        cs = get_fat(fs, clst);			/* Check the cluster status */
        if (cs < 2) return 1;			/* It is an invalid cluster */
        if (cs < fs->n_fatent) return cs;	/* It is already followed by next cluster */
        scl = clst;
    }

    ncl = scl;				/* Start cluster */
    for (;;)
    {
        ncl++;							/* Next cluster */
        if (ncl >= fs->n_fatent)  		/* Wrap around */
        {
            ncl = 2;
            if (ncl > scl) return 0;	/* No free cluster */
        }
        cs = get_fat(fs, ncl);			/* Get the cluster status */
        if (cs == 0) break;				/* Found a free cluster */
        if (cs == 0xFFFFFFFF || cs == 1)/* An error occurred */
            return cs;
        if (ncl == scl) return 0;		/* No free cluster */
    }

    res = put_fat(fs, ncl, 0x0FFFFFFF);	/* Mark the new cluster "last link" */
    if (res == FR_OK && clst != 0)
    {
        res = put_fat(fs, clst, ncl);	/* Link it to the previous one if needed */
    }
    if (res == FR_OK)
    {
        fs->last_clust = ncl;			/* Update FSINFO */
        if (fs->free_clust != 0xFFFFFFFF)
        {
            fs->free_clust--;
            fs->fsi_flag = 1;
        }
    }
    else
    {
        ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1;
    }

    return ncl;		/* Return new cluster number or error code */
}
#endif /* !_FS_READONLY */



/*-----------------------------------------------------------------------*/
/* FAT handling - Convert offset into cluster with link map table        */
/*-----------------------------------------------------------------------*/

#if _USE_FASTSEEK
static
DWORD clmt_clust (	/* <2:Error, >=2:Cluster number */
    FIL *fp,		/* Pointer to the file object */
    DWORD ofs		/* File offset to be converted to cluster# */
)
{
    DWORD cl, ncl, *tbl;


    tbl = fp->cltbl + 1;	/* Top of CLMT */
    cl = ofs / SS(fp->fs) / fp->fs->csize;	/* Cluster order from top of the file */
    for (;;)
    {
        ncl = *tbl++;			/* Number of cluters in the fragment */
        if (!ncl) return 0;		/* End of table? (error) */
        if (cl < ncl) break;	/* In this fragment? */
        cl -= ncl;
        tbl++;		/* Next fragment */
    }
    return cl + *tbl;	/* Return the cluster number */
}
#endif	/* _USE_FASTSEEK */



/*-----------------------------------------------------------------------*/
/* Directory handling - Set directory index                              */
/*-----------------------------------------------------------------------*/

static
FRESULT dir_sdi (
    DIR *dj,		/* Pointer to directory object */
    WORD idx		/* Directory index number */
)
{
    DWORD clst;
    WORD ic;


    dj->index = idx;
    clst = dj->sclust;
    if (clst == 1 || clst >= dj->fs->n_fatent)	/* Check start cluster range */
        return FR_INT_ERR;
    if (!clst && dj->fs->fs_type == FS_FAT32)	/* Replace cluster# 0 with root cluster# if in FAT32 */
        clst = dj->fs->dirbase;

    if (clst == 0)  	/* Static table (root-dir in FAT12/16) */
    {
        dj->clust = clst;
        if (idx >= dj->fs->n_rootdir)		/* Index is out of range */
            return FR_INT_ERR;
        dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / SZ_DIR);	/* Sector# */
    }
    else  				/* Dynamic table (sub-dirs or root-dir in FAT32) */
    {
        ic = SS(dj->fs) / SZ_DIR * dj->fs->csize;	/* Entries per cluster */
        while (idx >= ic)  	/* Follow cluster chain */
        {
            clst = get_fat(dj->fs, clst);				/* Get next cluster */
            if (clst == 0xFFFFFFFF) return FR_DISK_ERR;	/* Disk error */
            if (clst < 2 || clst >= dj->fs->n_fatent)	/* Reached to end of table or int error */
                return FR_INT_ERR;
            idx -= ic;
        }
        dj->clust = clst;
        dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / SZ_DIR);	/* Sector# */
    }

    dj->dir = dj->fs->win + (idx % (SS(dj->fs) / SZ_DIR)) * SZ_DIR;	/* Ptr to the entry in the sector */

    return FR_OK;	/* Seek succeeded */
}




/*-----------------------------------------------------------------------*/
/* Directory handling - Move directory index next                        */
/*-----------------------------------------------------------------------*/

static
FRESULT dir_next (	/* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not stretch */
    DIR *dj,		/* Pointer to directory object */
    int stretch		/* 0: Do not stretch table, 1: Stretch table if needed */
)
{
    DWORD clst;
    WORD i;


    stretch = stretch;		/* To suppress warning on read-only cfg. */
    i = dj->index + 1;
    if (!i || !dj->sect)	/* Report EOT when index has reached 65535 */
        return FR_NO_FILE;

    if (!(i % (SS(dj->fs) / SZ_DIR)))  	/* Sector changed? */
    {
        dj->sect++;					/* Next sector */

        if (dj->clust == 0)  	/* Static table */
        {
            if (i >= dj->fs->n_rootdir)	/* Report EOT when end of table */
                return FR_NO_FILE;
        }
        else  					/* Dynamic table */
        {
            if (((i / (SS(dj->fs) / SZ_DIR)) & (dj->fs->csize - 1)) == 0)  	/* Cluster changed? */
            {
                clst = get_fat(dj->fs, dj->clust);				/* Get next cluster */
                if (clst <= 1) return FR_INT_ERR;
                if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
                if (clst >= dj->fs->n_fatent)  					/* When it reached end of dynamic table */
                {
#if !_FS_READONLY
                    BYTE c;
                    if (!stretch) return FR_NO_FILE;			/* When do not stretch, report EOT */
                    clst = create_chain(dj->fs, dj->clust);		/* Stretch cluster chain */
                    if (clst == 0) return FR_DENIED;			/* No free cluster */
                    if (clst == 1) return FR_INT_ERR;
                    if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
                    /* Clean-up stretched table */
                    if (move_window(dj->fs, 0)) return FR_DISK_ERR;	/* Flush active window */
                    mem_set(dj->fs->win, 0, SS(dj->fs));			/* Clear window buffer */
                    dj->fs->winsect = clust2sect(dj->fs, clst);	/* Cluster start sector */
                    for (c = 0; c < dj->fs->csize; c++)  		/* Fill the new cluster with 0 */
                    {
                        dj->fs->wflag = 1;
                        if (move_window(dj->fs, 0)) return FR_DISK_ERR;
                        dj->fs->winsect++;
                    }
                    dj->fs->winsect -= c;						/* Rewind window address */
#else
                    return FR_NO_FILE;			/* Report EOT */
#endif
                }
                dj->clust = clst;				/* Initialize data for new cluster */
                dj->sect = clust2sect(dj->fs, clst);
            }
        }
    }

    dj->index = i;
    dj->dir = dj->fs->win + (i % (SS(dj->fs) / SZ_DIR)) * SZ_DIR;

    return FR_OK;
}




/*-----------------------------------------------------------------------*/
/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry   */
/*-----------------------------------------------------------------------*/
#if _USE_LFN
static
const BYTE LfnOfs[] = {1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30};	/* Offset of LFN chars in the directory entry */


static
int cmp_lfn (			/* 1:Matched, 0:Not matched */
    WCHAR *lfnbuf,		/* Pointer to the LFN to be compared */
    BYTE *dir			/* Pointer to the directory entry containing a part of LFN */
)
{
    UINT i, s;
    WCHAR wc, uc;


    i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13;	/* Get offset in the LFN buffer */
    s = 0;
    wc = 1;
    do
    {
        uc = LD_WORD(dir + LfnOfs[s]);	/* Pick an LFN character from the entry */
        if (wc)  	/* Last char has not been processed */
        {
            wc = ff_wtoupper(uc);		/* Convert it to upper case */
            if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++]))	/* Compare it */
                return 0;				/* Not matched */
        }
        else
        {
            if (uc != 0xFFFF) return 0;	/* Check filler */
        }
    }
    while (++s < 13);				/* Repeat until all chars in the entry are checked */

    if ((dir[LDIR_Ord] & LLE) && wc && lfnbuf[i])	/* Last segment matched but different length */
        return 0;

    return 1;						/* The part of LFN matched */
}



static
int pick_lfn (			/* 1:Succeeded, 0:Buffer overflow */
    WCHAR *lfnbuf,		/* Pointer to the Unicode-LFN buffer */
    BYTE *dir			/* Pointer to the directory entry */
)
{
    UINT i, s;
    WCHAR wc, uc;


    i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13;	/* Offset in the LFN buffer */

    s = 0;
    wc = 1;
    do
    {
        uc = LD_WORD(dir + LfnOfs[s]);		/* Pick an LFN character from the entry */
        if (wc)  	/* Last char has not been processed */
        {
            if (i >= _MAX_LFN) return 0;	/* Buffer overflow? */
            lfnbuf[i++] = wc = uc;			/* Store it */
        }
        else
        {
            if (uc != 0xFFFF) return 0;		/* Check filler */
        }
    }
    while (++s < 13);						/* Read all character in the entry */

    if (dir[LDIR_Ord] & LLE)  				/* Put terminator if it is the last LFN part */
    {
        if (i >= _MAX_LFN) return 0;		/* Buffer overflow? */
        lfnbuf[i] = 0;
    }

    return 1;
}


#if !_FS_READONLY
static
void fit_lfn (
    const WCHAR *lfnbuf,	/* Pointer to the LFN buffer */
    BYTE *dir,				/* Pointer to the directory entry */
    BYTE ord,				/* LFN order (1-20) */
    BYTE sum				/* SFN sum */
)
{
    UINT i, s;
    WCHAR wc;


    dir[LDIR_Chksum] = sum;			/* Set check sum */
    dir[LDIR_Attr] = AM_LFN;		/* Set attribute. LFN entry */
    dir[LDIR_Type] = 0;

⌨️ 快捷键说明

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