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

📄 landzo

📁 【开源】线性CCD自适应性算法攻略
💻
📖 第 1 页 / 共 5 页
字号:
    ST_WORD(dir + LDIR_FstClusLO, 0);

    i = (ord - 1) * 13;				/* Get offset in the LFN buffer */
    s = wc = 0;
    do
    {
        if (wc != 0xFFFF) wc = lfnbuf[i++];	/* Get an effective char */
        ST_WORD(dir + LfnOfs[s], wc);	/* Put it */
        if (!wc) wc = 0xFFFF;		/* Padding chars following last char */
    }
    while (++s < 13);
    if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLE;	/* Bottom LFN part is the start of LFN sequence */
    dir[LDIR_Ord] = ord;			/* Set the LFN order */
}

#endif
#endif



/*-----------------------------------------------------------------------*/
/* Create numbered name                                                  */
/*-----------------------------------------------------------------------*/
#if _USE_LFN
void gen_numname (
    BYTE *dst,			/* Pointer to generated SFN */
    const BYTE *src,	/* Pointer to source SFN to be modified */
    const WCHAR *lfn,	/* Pointer to LFN */
    WORD seq			/* Sequence number */
)
{
    BYTE ns[8], c;
    UINT i, j;


    mem_cpy(dst, src, 11);

    if (seq > 5)  	/* On many collisions, generate a hash number instead of sequential number */
    {
        do seq = (seq >> 1) + (seq << 15) + (WORD) * lfn++;
        while (*lfn);
    }

    /* itoa (hexdecimal) */
    i = 7;
    do
    {
        c = (seq % 16) + '0';
        if (c > '9') c += 7;
        ns[i--] = c;
        seq /= 16;
    }
    while (seq);
    ns[i] = '~';

    /* Append the number */
    for (j = 0; j < i && dst[j] != ' '; j++)
    {
        if (IsDBCS1(dst[j]))
        {
            if (j == i - 1) break;
            j++;
        }
    }
    do
    {
        dst[j++] = (i < 8) ? ns[i++] : ' ';
    }
    while (j < 8);
}
#endif




/*-----------------------------------------------------------------------*/
/* Calculate sum of an SFN                                               */
/*-----------------------------------------------------------------------*/
#if _USE_LFN
static
BYTE sum_sfn (
    const BYTE *dir		/* Ptr to directory entry */
)
{
    BYTE sum = 0;
    UINT n = 11;

    do sum = (sum >> 1) + (sum << 7) + *dir++;
    while (--n);
    return sum;
}
#endif




/*-----------------------------------------------------------------------*/
/* Directory handling - Find an object in the directory                  */
/*-----------------------------------------------------------------------*/

static
FRESULT dir_find (
    DIR *dj			/* Pointer to the directory object linked to the file name */
)
{
    FRESULT res;
    BYTE c, *dir;
#if _USE_LFN
    BYTE a, ord, sum;
#endif

    res = dir_sdi(dj, 0);			/* Rewind directory object */
    if (res != FR_OK) return res;

#if _USE_LFN
    ord = sum = 0xFF;
#endif
    do
    {
        res = move_window(dj->fs, dj->sect);
        if (res != FR_OK) break;
        dir = dj->dir;					/* Ptr to the directory entry of current index */
        c = dir[DIR_Name];
        if (c == 0)
        {
            res = FR_NO_FILE;    /* Reached to end of table */
            break;
        }
#if _USE_LFN	/* LFN configuration */
        a = dir[DIR_Attr] & AM_MASK;
        if (c == DDE || ((a & AM_VOL) && a != AM_LFN))  	/* An entry without valid data */
        {
            ord = 0xFF;
        }
        else
        {
            if (a == AM_LFN)  			/* An LFN entry is found */
            {
                if (dj->lfn)
                {
                    if (c & LLE)  		/* Is it start of LFN sequence? */
                    {
                        sum = dir[LDIR_Chksum];
                        c &= ~LLE;
                        ord = c;	/* LFN start order */
                        dj->lfn_idx = dj->index;
                    }
                    /* Check validity of the LFN entry and compare it with given name */
                    ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
                }
            }
            else  					/* An SFN entry is found */
            {
                if (!ord && sum == sum_sfn(dir)) break;	/* LFN matched? */
                ord = 0xFF;
                dj->lfn_idx = 0xFFFF;	/* Reset LFN sequence */
                if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break;	/* SFN matched? */
            }
        }
#else		/* Non LFN configuration */
        if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
            break;
#endif
        res = dir_next(dj, 0);		/* Next entry */
    }
    while (res == FR_OK);

    return res;
}




/*-----------------------------------------------------------------------*/
/* Read an object from the directory                                     */
/*-----------------------------------------------------------------------*/
#if _FS_MINIMIZE <= 1
static
FRESULT dir_read (
    DIR *dj			/* Pointer to the directory object that pointing the entry to be read */
)
{
    FRESULT res;
    BYTE c, *dir;
#if _USE_LFN
    BYTE a, ord = 0xFF, sum = 0xFF;
#endif

    res = FR_NO_FILE;
    while (dj->sect)
    {
        res = move_window(dj->fs, dj->sect);
        if (res != FR_OK) break;
        dir = dj->dir;					/* Ptr to the directory entry of current index */
        c = dir[DIR_Name];
        if (c == 0)
        {
            res = FR_NO_FILE;    /* Reached to end of table */
            break;
        }
#if _USE_LFN	/* LFN configuration */
        a = dir[DIR_Attr] & AM_MASK;
        if (c == DDE || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN))  	/* An entry without valid data */
        {
            ord = 0xFF;
        }
        else
        {
            if (a == AM_LFN)  			/* An LFN entry is found */
            {
                if (c & LLE)  			/* Is it start of LFN sequence? */
                {
                    sum = dir[LDIR_Chksum];
                    c &= ~LLE;
                    ord = c;
                    dj->lfn_idx = dj->index;
                }
                /* Check LFN validity and capture it */
                ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
            }
            else  					/* An SFN entry is found */
            {
                if (ord || sum != sum_sfn(dir))	/* Is there a valid LFN? */
                    dj->lfn_idx = 0xFFFF;		/* It has no LFN. */
                break;
            }
        }
#else		/* Non LFN configuration */
        if (c != DDE && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL))	/* Is it a valid entry? */
            break;
#endif
        res = dir_next(dj, 0);				/* Next entry */
        if (res != FR_OK) break;
    }

    if (res != FR_OK) dj->sect = 0;

    return res;
}
#endif



/*-----------------------------------------------------------------------*/
/* Register an object to the directory                                   */
/*-----------------------------------------------------------------------*/
#if !_FS_READONLY
static
FRESULT dir_register (	/* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */
    DIR *dj				/* Target directory with object name to be created */
)
{
    FRESULT res;
    BYTE c, *dir;
#if _USE_LFN	/* LFN configuration */
    WORD n, ne, is;
    BYTE sn[12], *fn, sum;
    WCHAR *lfn;


    fn = dj->fn;
    lfn = dj->lfn;
    mem_cpy(sn, fn, 12);

    if (_FS_RPATH && (sn[NS] & NS_DOT))		/* Cannot create dot entry */
        return FR_INVALID_NAME;

    if (sn[NS] & NS_LOSS)  			/* When LFN is out of 8.3 format, generate a numbered name */
    {
        fn[NS] = 0;
        dj->lfn = 0;			/* Find only SFN */
        for (n = 1; n < 100; n++)
        {
            gen_numname(fn, sn, lfn, n);	/* Generate a numbered name */
            res = dir_find(dj);				/* Check if the name collides with existing SFN */
            if (res != FR_OK) break;
        }
        if (n == 100) return FR_DENIED;		/* Abort if too many collisions */
        if (res != FR_NO_FILE) return res;	/* Abort if the result is other than 'not collided' */
        fn[NS] = sn[NS];
        dj->lfn = lfn;
    }

    if (sn[NS] & NS_LFN)  			/* When LFN is to be created, reserve an SFN + LFN entries. */
    {
        for (ne = 0; lfn[ne]; ne++) ;
        ne = (ne + 25) / 13;
    }
    else  						/* Otherwise reserve only an SFN entry. */
    {
        ne = 1;
    }

    /* Reserve contiguous entries */
    res = dir_sdi(dj, 0);
    if (res != FR_OK) return res;
    n = is = 0;
    do
    {
        res = move_window(dj->fs, dj->sect);
        if (res != FR_OK) break;
        c = *dj->dir;				/* Check the entry status */
        if (c == DDE || c == 0)  	/* Is it a blank entry? */
        {
            if (n == 0) is = dj->index;	/* First index of the contiguous entry */
            if (++n == ne) break;	/* A contiguous entry that required count is found */
        }
        else
        {
            n = 0;					/* Not a blank entry. Restart to search */
        }
        res = dir_next(dj, 1);		/* Next entry with table stretch */
    }
    while (res == FR_OK);

    if (res == FR_OK && ne > 1)  	/* Initialize LFN entry if needed */
    {
        res = dir_sdi(dj, is);
        if (res == FR_OK)
        {
            sum = sum_sfn(dj->fn);	/* Sum of the SFN tied to the LFN */
            ne--;
            do  					/* Store LFN entries in bottom first */
            {
                res = move_window(dj->fs, dj->sect);
                if (res != FR_OK) break;
                fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum);
                dj->fs->wflag = 1;
                res = dir_next(dj, 0);	/* Next entry */
            }
            while (res == FR_OK && --ne);
        }
    }

#else	/* Non LFN configuration */

⌨️ 快捷键说明

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