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

📄 file.c

📁 arm7 zlg lpc2219 bootloader
💻 C
📖 第 1 页 / 共 3 页
字号:
    uint8 Rt;
    uint8 *Buf;

    Rt = PARAMETER_ERR;
    fp = FileInfo + Handle;
    if (Handle < MAX_OPEN_FILES)      /* Handle是否有效 */
    if (((fp->Flags) & FILE_FLAGS_WRITE) != 0)       /* 文件是否可写 */
    {
        Rt = FILE_EOF;
        if (fp->Offset <= fp->FileSize)
        {
            Rt = NOT_FIND_DISK;
                /* 获取文件所在逻辑盘信息 */
            DiskInfo = GetDiskInfo(fp->Drive);
            if (DiskInfo != NULL)
            {
                j = (fp->Offset) % (DiskInfo->SecPerClus * DiskInfo->BytsPerSec);
                
                if (j == 0)
                if (fp->Offset == fp->FileSize)
                {
                    i = FATAddClus(fp->Drive, fp->Clus);
                    if (i >= BAD_CLUS)
                    {
                        return DISK_FULL;
                    }
                    fp->Clus = i;
                    if (fp->FstClus == EMPTY_CLUS)
                    {
                        fp->FstClus = i;
                    }
                }
                /* 计算数据所在扇区 */
                i = j / DiskInfo->BytsPerSec;
                j = j % DiskInfo->BytsPerSec;
                SecIndex = (fp->Clus - 2) * DiskInfo->SecPerClus + DiskInfo->DataStartSec + i;
                Rt = SECTOR_READ_ERR;
                
                /* 打开扇区 */
                Buf = OpenSec(fp->Drive, SecIndex);
                if (Buf != NULL)
                {
                    /* 写扇区数据 */
                    if (ReadSec(fp->Drive, SecIndex) == RETURN_OK)
                    {
                        /* 存储数据 */
                        Buf[j] = Ch;
                        WriteSec(fp->Drive, SecIndex);
                        Rt = RETURN_OK;
                    }
                    CloseSec(fp->Drive, SecIndex);
                }

                /* 调整打开文件信息表 */
                fp->Offset++;
                if (fp->Offset > fp->FileSize)
                {
                    fp->FileSize = fp->Offset;
                }

                if ((j + 1) >= DiskInfo->BytsPerSec)
                {
                    if ((i + 1) >= DiskInfo->SecPerClus)
                    if (fp->Offset < fp->FileSize)
                    {
                        fp->Clus = FATGetNextClus(fp->Drive, fp->Clus);
                    }
                }            
            }
        }
    }
    return Rt;
}

/*********************************************************************************************************
** 函数名称: FileWrite
** 功能描述: 写文件
**
** 输 入: Buf:要写的数据
**        Size:要写的字节数
**        Handle:文件句柄
** 输 出: 实际写的字节数
**         
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2003年6月5日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        uint32 FileWrite(void *Buf, uint32 Size, HANDLE Handle)
{
    uint32 i, j, k, SecIndex;
    MY_FILE *fp;
    Disk_Info * DiskInfo;
    uint32 Rt;
    uint8 *Buf1, *Buf2;

    if (Size == 0)
    {
        return 0;
    }
    
    Rt = 0;
    fp = FileInfo + Handle;             // 获得登记项句柄
    Buf2 = (uint8 *)Buf;                // 数据源
    if (Handle < MAX_OPEN_FILES)        /* Handle是否有效 */
    if (((fp->Flags) & FILE_FLAGS_WRITE) != 0)       /* 文件是否可写 */
    {
        if (fp->Offset > fp->FileSize)  // 偏移超出文件范围,返回
        {
            return 0;
        }
        
        while (Size != 0)
        {
            /* 获取文件所在逻辑盘信息 */
            DiskInfo = GetDiskInfo(fp->Drive);
            if (DiskInfo == NULL)
            {
                break;
            }
            /* 计算数据所在扇区 */
            j = fp->Offset % (DiskInfo->SecPerClus * DiskInfo->BytsPerSec);   // 字节偏移量(簇内)
            
            if (j == 0) 
            if (fp->Offset == fp->FileSize)  
            {           // 如果指向簇的最后一字节,并且偏移量等于文件大小,即指向文件最后一个字节
                i = FATAddClus(fp->Drive, fp->Clus);  // 则需要增加新簇
                if (i >= BAD_CLUS)
                {
                    return DISK_FULL;
                }
                fp->Clus = i;
                if (fp->FstClus == EMPTY_CLUS)
                {
                    fp->FstClus = i;
                }
            }

            i = j / DiskInfo->BytsPerSec;   // 扇区偏移(簇内)
            j = j % DiskInfo->BytsPerSec;   // 字节偏移(扇区内)
            SecIndex = (fp->Clus - 2) * DiskInfo->SecPerClus + 
                       DiskInfo->DataStartSec + i;

            k = DiskInfo->BytsPerSec - j;   // 扇区剩余字节
            if (Size < k)                   // 如果该扇区的空闲字节大于要保存的文件大小
            {
                k = Size;
            }

            /* 打开扇区 */
            Buf1 = OpenSec(fp->Drive, SecIndex);
            if (Buf1 == NULL)
            {
                break;
            }
            /* 读取扇区数据 */
            if (ReadSec(fp->Drive, SecIndex) != RETURN_OK)
            {
                break;
            }

            memcpy(Buf1 + j, Buf2, k);      // 数据复制,从数据源Buf2复制K字节数据到Buf1+j
            Buf2 += k;                      // 数据源指针加K

            /* 关闭扇区 */
            WriteSec(fp->Drive, SecIndex);  // 设置被修改标记
            CloseSec(fp->Drive, SecIndex);
            
            Size -= k;                      // 剩余待写入数据量减k
            Rt += k;
            /* 调整文件指针 */
            fp->Offset += k;                // 写入点指针偏移位置+k
            if (fp->Offset > fp->FileSize)  // 如果文件增大,更新文件大小值
            {
                fp->FileSize = fp->Offset;
            }

            if ((j + k) >= DiskInfo->BytsPerSec)
            {
                if ((i + 1) >= DiskInfo->SecPerClus)
                if (fp->Offset < fp->FileSize)
                {
                    fp->Clus = FATGetNextClus(fp->Drive, fp->Clus);
                }
            }
        }
    }
    return Rt;
}

/*********************************************************************************************************
** 函数名称: FileCloseAll
** 功能描述: 关闭所有打开的文件
**
** 输 入: 无
**
** 输 出: 无
**         
** 全局变量: FileInfo
** 调用模块: AllCacheWriteBack
**
** 作 者: 陈明计
** 日 期: 2003年6月5日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        void FileCloseAll(void)
{
    uint32 i;

    for (i = 0; i < MAX_OPEN_FILES; i++)
    {
        FileClose(i);
    }
    AllCacheWriteBack();
}

/*********************************************************************************************************
** 函数名称: FileEof
** 功能描述: 判断文件是否到读\写到文件尾
**
** 输 入: Handle:文件句柄
**
** 输 出: 0:否
**        1:是 
** 全局变量: FileInfo
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2003年6月5日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        uint8 FileEof(HANDLE Handle)
{
    if (Handle < MAX_OPEN_FILES)
    if (FileInfo[Handle].Offset < FileInfo[Handle].FileSize)
    {
        return 0;
    }
    return 1;
}

/*********************************************************************************************************
** 函数名称: FileSeek
** 功能描述: 移动文件读\写位置
**
** 输 入: Handle:文件句柄
**        offset:移动偏移量
**        Whence:移动模式SEEK_SET:从文件头计算SEEK_CUR:从当前位置计算SEEK_END:从文件尾计算
** 输 出: 无
**         
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2003年6月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2004年4月10日
**------------------------------------------------------------------------------------------------------
** 修改人: 陈明计
** 日 期: 2004年7月12日
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        uint8 FileSeek(HANDLE Handle, int32 offset, uint8 Whence)
{
    uint8 Rt;
    uint32 i, Clus;
    MY_FILE *fp;
    Disk_Info * DiskInfo;
    
    Rt = PARAMETER_ERR;
    fp = FileInfo + Handle;
    if (Handle < MAX_OPEN_FILES)                    /* Handle是否有效 */
    if (fp->Flags  != 0)                            /* 对应的打开文件信息表是否已使用 */
    {
        Rt = RETURN_OK;
        switch (Whence)
        {
            case SEEK_END:             /* 从文件尾计算 */
                fp->Offset = fp->FileSize - offset;
                offset = -offset;
                break;
            case SEEK_SET:
                fp->Offset = offset;
                break;
            case SEEK_CUR:             /* 从当前位置计算 这里不用break是正确的*/
                i = fp->Offset + offset;
                break;
            default:
                Rt = PARAMETER_ERR;
                break;
        }
        /* 改变当前簇号 */
        if (Rt == RETURN_OK)
        {
            if (fp->Offset > fp->FileSize)
            {
                if (offset > 0)
                {
                    fp->Offset = fp->FileSize;
                }
                else
                {
                    fp->Offset = 0;
                }
            }
            Rt = NOT_FIND_DISK;
            DiskInfo = GetDiskInfo(fp->Drive);
            if (DiskInfo != NULL)
            {
                Rt = RETURN_OK;
                i = fp->Offset / (DiskInfo->BytsPerSec * DiskInfo->SecPerClus);
                Clus = fp->FstClus;
                for (; i != 0; i--)
                {
                    Clus = FATGetNextClus(fp->Drive, Clus);
                    if (Clus >= BAD_CLUS)
                    {
                        Rt = FAT_ERR;
                        break;
                    }
                }
                fp->Clus = Clus;
            }
        }
    }
    return Rt;
}

/*********************************************************************************************************
** 函数名称: FS_GetDateTime
** 功能描述: 时间格式转换函数,将DATE_TIME格式的数据转换为SYS_TIME格式的时间数据
**
** 输 入: CurTime  指向保存结果
**
** 输 出: 错误代码,RETURN_OK为正确
**         
** 全局变量: 无
** 调用模块: GetDataTime
**
** 作 者: 严寒亮
** 日 期: 2004年11月3日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
   uint8   FS_GetDateTime(SYS_TIME *CurTime)
{
   uint8       temp8;
   uint16      temp16 = 0;
   DATE_TIME   Time;
   
   temp8 = GetDataTime(&Time);            // 获取当前时间
   if(temp8 != RETURN_OK)
   {
      return temp8;                       // 如果获取失败,就返回错误代码
   }
   
   /* 时间格式转换 */
   if(Time.da_year > 1980)
   {
      temp16  = Time.da_year - 1980;      // 年,如果当前年小于1980年,设为0
   }
   temp16  = (temp16 & 0x7F) << 9;        // 年:9~15位
   temp16 |= (Time.da_mon & 0x0F) << 5;   // 月:5~8位
   temp16 |= Time.da_day & 0x1F ;         // 日:0~4位
   CurTime->date = temp16;
	
   temp16  = (Time.ti_hour & 0x1F) << 11; // 时:11~15位
   temp16 |= (Time.ti_min  & 0x3F) << 5;  // 分:5~10位
   temp16 |= (Time.ti_sec  & 0x3F) >> 1;  // 秒,变为2秒的倍数:0~4位
   CurTime->time = temp16; 
   
   if((Time.ti_sec & 0x01) == 0x01)
   {
      temp8   = 100;                   // 如果当前秒为奇数,毫秒戳加上100
   } 
   temp8   += Time.ti_hund;            // 加上百分之一秒数
   CurTime->msec = temp8;
   
   return RETURN_OK;
}

/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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