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

📄 flashfs.c

📁 flash驱动程序,Nor flash类型
💻 C
📖 第 1 页 / 共 5 页
字号:
**  slot        Details of file to be removed.**** Returns:**  ESUCCESS    File removed**  <>ESUCCESS  Error code.****----------------------------------------------------------------------*/static int flashfs_RemoveFile (OPENFILE *slot){    int     rc;    BOOL    isDynamic;    U32     prev;    /*    ** Look for the file, noting in which section it was found.    */    if (flashfs_Find (slot, &prev, &isDynamic))    {        /*        ** Check that this filing system isn't actively in use (otherwise the        ** writes will wreck any open reads).        */        if (flashfs_HasFilesOpen (slot->partition))        {            rc = EBUSY;            TRACE3 ("File system in use\n");        }        else        {            /*            ** Action taken depends upon where the file to be removed is located.            ** (Don't need to touch the other area).            */            BYTE    *copyBuffer;            copyBuffer = (BYTE *) malloc (SCRATCH_BUFFER_SIZE);            if (NULL != copyBuffer)            {                FLASHFS_DIRENT  entry;                U32             shift = 0;                U32             link;                rc = ESUCCESS;                slot->datptr = slot->datptr - sizeof (entry) + sizeof (entry.data);                flash_read_fs_data (slot->datptr, (BYTE *)&entry, sizeof entry);                TRACE3 ("Remove file '%s' %x %d\n", slot->name, slot->datptr, slot->fmax);                if (isDynamic)                {                    if (prev != 0)                    {                        shift = prev - slot->datptr;                    }                    else                    {                        /*                        ** This is the first file in the list being removed. The distance shifted is simply the                         ** amount of space occupied by the file, ignoring the granularity. The code cannot assume                        ** that the current granularity is the same as that stored, and calculating the stored                        ** granularity is difficult in all circumstances.                        */                        shift = flashfsSize - GRANULARITY - slot->datptr;                        /*REVIEW*/                    }                    /*                    ** Reset previous link                    */                    if (0 == prev)                    {                        /*                        ** The file being removed is the first file in the list so simply                        ** copy all other files "up", overwriting the previous file.                        */                        if (entry.next != 0)                        {                            flashfsRoot.first.dynamic = entry.next + shift;                        }                        else                        {                            /*                            ** Special case: no more files                            */                            flashfsRoot.first.dynamic = 0;                        }                        rc = flash_write_fs_data((BYTE *)&flashfsRoot, 0, sizeof flashfsRoot);                    }                    else                    {                        FLASHFS_DIRENT  preventry;                        /*                        ** The file being removed is some way down the list; so rewrite the previous entry.                        */                        flash_read_fs_data (prev, (BYTE *)&preventry, sizeof preventry);                        if (entry.next == 0)                        {                            preventry.next = 0;                        }                        else                        {                            preventry.next = entry.next + shift;                        }                        rc = flash_write_fs_data ((BYTE *)&preventry, prev, sizeof preventry);                    }                    /*                    ** Move any other files                    */                    while ((ESUCCESS == rc) && (entry.next != 0))                    {                        U32     addr = entry.next;                        flash_read_fs_data (addr, (BYTE *)&entry, sizeof (entry));                        if (entry.next != 0)                        {                            link = entry.next + shift;                        }                        else                        {                            link = 0;                        }                        rc = move_flash_file (addr + shift, addr, entry.len + sizeof (entry), link, copyBuffer);                    }                }                else                {                    /*                    ** Last entry: zap previous link                    */                    if (entry.next == 0)                    {                        if (prev == 0)                        {                            /*                            ** First, and only, file being removed.                            */                            flashfsRoot.first.fixed = 0;                            rc = flash_write_fs_data((BYTE *)&flashfsRoot, 0, sizeof flashfsRoot);                        }                        else                        {                            /*                            ** Last file in the chain...                            */                            flash_read_fs_data (prev, (BYTE *)&entry, sizeof entry);                            entry.next = 0;                            rc = flash_write_fs_data ((BYTE *)&entry, prev, sizeof entry);                        }                    }                    else                    {                        prev = slot->datptr;                        shift = entry.next - prev;                        while ((ESUCCESS == rc) && (entry.next != 0))                        {                            U32     addr = entry.next;                            flash_read_fs_data (addr, (BYTE *)&entry, sizeof entry);                                                        /*                            ** Adjust link provided that it is not the last one.                            */                            if (entry.next != 0)                            {                                link = entry.next - shift;                            }                            else                            {                                link = 0;                            }                            rc = move_flash_file (prev, addr, entry.len + sizeof (entry), link, copyBuffer);                            prev = link;                        }                    }                }                /*                ** Rewrite flash header if all was well (this will flush any trailing data).                */                if (ESUCCESS == rc)                {                    rc = flashfs_program_header ();                }                free (copyBuffer);            }            else            {                TRACE3 ("Can't allocate copy buffer\n");                rc = ENOMEM;            }        }    }    else    {        rc = ENOENT;    }    return  rc;}/***----------------------------------------------------------------------**** flashfs_CreateFile:**** Create a file in flashfs.**** If the file already exists it will be removed. No other files can be** open (in the specified partition) as removal may move the files around** in flash memory.**** Arguments:**  slot        Details of file to be created**** Returns:**  ESUCCESS    File created**  <>ESUCCESS  Error code.****----------------------------------------------------------------------*/static int flashfs_CreateFile (OPENFILE *slot){    int     rc;    /*    ** No other files open    */    if (flashfs_HasFilesOpen (slot->partition))    {        rc = EBUSY;    }    else    {        BOOL    dummy;        /*        ** Delete any previous instance of the file.        */        if (flashfs_Find (slot, NULL, &dummy))        {            rc = flashfs_RemoveFile (slot);        }        else        {            rc = ESUCCESS;        }            /*        ** If everything is still correct then set up the entry        */        if (ESUCCESS == rc)        {            struct fsinfo   fsinfobuf;            /*            ** Determine free space on device for use when writing.            */            rc = flashfs_SysInfo (slot->partition, &fsinfobuf);            if (ESUCCESS == rc)            {                FLASHFS_DIRENT  entry;                /*                ** Calculate free space available for writing                */                slot->limit = (fsinfobuf.blocks - fsinfobuf.used) * fsinfobuf.blocksize;                if (slot->limit < ALIGN_UP (sizeof (FLASHFS_DIRENT)))                {                    TRACE3 ("Create file '%s' failed - no more space\n", slot->name);                    rc = ENOSPC;                }                /*                ** Now create flashfs entry, always create in 'fixed' area as it allows the                ** the file to grow upwards.                */                else if (flashfsRoot.first.fixed == 0)                {                    slot->datptr = flashfsRoot.first.fixed = ALIGN_UP (sizeof (FLASHFS_ROOT));                    rc = flash_write_fs_data((BYTE *)&flashfsRoot, 0, sizeof (FLASHFS_ROOT));                }                else                {                    U32     last;                    /*                    ** Chain down list of files, finding the last entry.                    */                    entry.next = flashfsRoot.first.fixed;                            while (entry.next != 0)                    {                        last = entry.next;                        flash_read_fs_data (last, (BYTE *) &entry, sizeof (FLASHFS_DIRENT));                    }                    assert (0 != CHECK_ADDR (last));                    entry.next = slot->datptr = last + ALIGN_UP (sizeof (FLASHFS_DIRENT) + entry.len);                    rc = flash_write_fs_data ((BYTE *) &entry, last, sizeof (FLASHFS_DIRENT));                }                if (ESUCCESS == rc)                {                    /*                    ** Adjust available space by size of control block.                    */                    slot->limit -= sizeof (FLASHFS_DIRENT);                    entry.next = 0;                    entry.len = 0;                    strncpy (entry.name, slot->name, FLASHFS_NAME_LENGTH);                    slot->fpos = 0;                    slot->fmax = 0;                    rc = flash_write_fs_data ((BYTE *) &entry, slot->datptr, sizeof (FLASHFS_DIRENT));                    if (ESUCCESS == rc)                    {                        /*                        ** At this point the FLASHFS is, technically, corrupt and will only be valid again                        ** after the file has been closed.                        */                        TRACE3 ("Create file '%s' @%x (limit %d)\n", slot->name, slot->datptr, slot->limit);                                                /*                        ** Point to real data area.                        */                        slot->datptr += sizeof (FLASHFS_DIRENT);                                                /*                        ** Ensure header details are written out (maintains the file structure                        ** consistancy but not the checksum). This has to be done as the underlying                        ** flash drivers do a buffered write but the read routines don't go through                        ** the sector buffer.                        */                        rc = program_sector ();                    }                }            }        }    }    return  rc;}/***----------------------------------------------------------------------**** flashfs_CloseFile:**** Close a file which was open for writing.**** Arguments:**  slot        Details of file to be closed**** Returns:**  ESUCCESS    File created**  <>ESUCCESS  Error code.****----------------------------------------------------------------------*/static int  flashfs_CloseFile (OPENFILE *slot){    int             rc;    FLASHFS_DIRENT  entry;    assert (NULL != slot);    assert (slot->inuse);    TRACE3 ("Close file '%s' @%x\n", slot->name, slot->datptr - sizeof (FLASHFS_DIRENT));    /*    ** Store file's correct length then update the checksum.    */    flash_read_fs_data (slot->datptr - sizeof (FLASHFS_DIRENT), (BYTE *) &entry, sizeof (FLASHFS_DIRENT));    entry.len = slot->fmax;    rc = flash_write_fs_data ((BYTE *) &entry, slot->datptr - sizeof (FLASHFS_DIRENT), sizeof (FLASHFS_DIRENT));    if (ESUCCESS == rc)    {        rc = flashfs_program_header ();    }    return  rc;}static void flashfs_msgOpen(ATMOS_MESSAGE *m){    OPENFILE *slot;    MSG_D_OPEN(o, m);    assert (NULL != m);    assert (m->code == MSG_N_OPEN);    /*    ** First see if there is a spare file slot.    */    slot = flashfs_OpenslotFind ();    if (NULL == slot)    {        TRACE1("%C: fopen failed, too many files open (%d)\n", FLASHFS_OPENS);        m->errno = EMFILE;    }    else    {        char    residue [256];        PTR		values [MAX_FLASHFS_ATTRIBUTES];        FILE *  fp = o->fp;                /*        ** Allow partition to be set by attribute selection (effective a write-once attribute).        */        slot->partition = NO_PARTITION;        flashfs_InitialiseAttributes (slot, &values [0]);        /* Read and interpret open mode */        m->errno = open_decoder (fp, o->fname, o->mode, residue, MODE_WRITE | MODE_READ | _IOB_DIRECTORY, flashfsKeys, values, NULL);                if (m->errno == ESUCCESS)        {            if (slot->partition == NO_PARTITION)            {                slot->partition = currentDefaultPartition;            }            if (flashfs_PartitionCheck (slot->partition, TRUE))            {                /*                ** Switch to new partition.                */                flashfs_PartitionChange (slot->partition);                if (fp->flags & _IOB_DIRECTORY)                {                    /*                    ** Directory entry? Ignore filename since we only have a 'flat' FS to date.                    */                    slot->inuse  = 1;                    slot->datptr = flashfsRoot.first.dynamic;                    slot->fpos   = DYNAMIC;  /* dynamic files to start*/                    slot->fmax   = 0;        /* set for completeness. */                    slot->fp     = fp;                    strcpy (slot->name, ".");                    fp->flags     |= _IOB_OPEN;                    fp->devuse    = (PTR) slot;                    TRACE3("%C: fopen for \"d\" OK\n");                }                else                {                    /*                    ** 'normal' file open ... so copy name into slot and search for that name                    ** but ensure that the name isn't overlong.                    */                    strncpy (slot->name, residue, FLASHFS_NAME_LENGTH);                    slot->name [FLASHFS_NAME_LENGTH - 1] = '\0';                    if ('\0' != slot->name [0])                    {                        BOOL    isDynamic;                        /*                        ** If opening for write then must create the file.                        */                        if (fp->flags & _IOB_WRITE)                        {                            m->errno = flashfs_CreateFile (slot);                        }

⌨️ 快捷键说明

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