binファイルのアップグレードとデータの位置決め--ファイル操作関数クラスタ!

11850 ワード

前に書く
以前はチップ上のアプリケーションのアップグレード機能、いわゆるBootloaderプログラムを自分でやっていましたが、もちろん、Secondery Bootloaderプログラムです.
チップアップグレードのBootLoaderプログラムをする時、私のやり方は簡単です:普通は上位機の下で送ったデータを受信して、データプロトコルが正しいかどうかを判断して、正しいと判断した後にデータをflashに書きます.しかし、上位機はどのようにデータをパッケージ化して送ってきたのか、どのようにプロトコルグループのデータフレームに従って、どのようにbinファイルの中でデータを正確に位置決めして、自分は一致して接触する機会がありません.
たまたま携帯でチップをアップグレードする機能を開発する必要があり、下位機コードは自分が書いたBootLoaderプログラムなので、プロトコルなどはまだ熟知しているので、この機会にファイル操作関数に触れました.
この文書は次のとおりです.
  • ファイルポインタおよびファイル情報構造
  • ファイル
  • を開く
  • ファイルを閉じる
  • ファイル内のデータ配置
  • ファイル削除
  • ファイルリストメニュー表示
  • ファイルポインタおよび構造体定義
    c言語ライブラリには、ファイル操作の関数ライブラリが多数含まれており、ファイルポインタの定義は
    _FILE *FilePointer

    _FILEはc言語ライブラリで定義されており、操作が必要なファイル情報を保存するためにファイルポインタを直接定義することができます.
    ファイルポインタは何ですか.一般的には、ファイルを開くときには、ポインタがファイルを指す必要がありますが、ポインタのタイプはFILE型であり、ファイル名を指すのは適切ではありません.もちろん、実際にはポインタ情報にはファイル名だけが含まれています.
    もう1つ定義する必要があるのは、検索したファイル情報を保存する構造体です.次のようにします.
    typedef __packed struct FINDBLK{
        U16 num;     //         
        U8 Cur_S; 
        U8 Index;    
        S8 name[8];  //    ,  8    ,   
        S8 ext[3];
        S8 dir[65];  //   
        U8 ff_ftime[16];   /* file  date_time*/
        U32 ff_fsize;       /* file size */
        S8 ff_name[13];     /* found file name */
        U8 ff_attrib;       /* attribute found */
    }FindBlk;

    上記の構造体では、ファイル操作を行うために検索されたファイル情報の変数を定義できます.
    ファイル検索
    完結構造体を定義した後、findfirstとfindnext関数を使用するファイルを検索して開く必要があります.この2つの関数の機能は名前の通りです.
    注意:ファイルを開く前にファイルを閉じる必要があります.ファイルポインタとファイルの関係を切断した後、連絡を再確立します.
    次に、ファイル情報を定義し、開いているファイルを検索します.
        FindBlk fileinfo;
        U8 ret;
    
        LCDcls();     //  
        _fcloseall();//              
        _setcurdir("D:\\"); //         
        ret = _findfirst("*.bin",&fileinfo);
        //   bin  ,    *     
        line = 3;
        num = 0;
        while(ret==0)
        {
            strncpy(&name[num][0],&fileinfo.ff_name,sizeof(fileinfo.ff_name));
            ret = _findnext(&fileinfo);
            num++;//      
        }
    
        if (num == 0)
        {
            while (1)
            {
                myPutString(4,1,"   ",1);
                myPutString(4,2,"     ",1);
                if (_bioskey(0) == ENTER)
                {
                    LCDcls();
                    return;
                }
            }
        }   
    ... ...

    上のコードは主にbin形式のファイルを検索し、定義したname配列にファイル名を保存し、カウンタnumで検索したファイルの数を記録します.
    ファイルのオープンとデータの配置
    ファイルを見つけたら、ファイルを開く必要があります.つまり、ファイルポインタとファイルの関係を再確立します.開く必要があるファイルのファイル名をインデックスし、fopen、fseek、filelength、fread関数を使用してデータを配置します.
    LCDcls();
        _fclose(FilePointer);
        FilePointer = _fopen(&name[cn-1][0],"r"); //     ,      。
    
        if (FilePointer != 0)
        //     ,    != NULL ((void *) 0)
        {
            filesize = _filelength(FilePointer); 
            //       ,          ,   。
            filesize_ori = filesize;
            _fseek(FilePointer,0,0);
            //                   ,  0  0
            memset(data_buffer,0,sizeof(data_buffer));
            //       
            _fread(data_buffer,filesize,FilePointer);
            //                 
            // filesize--        FilePointer--    
        //  :      ,                 ,   1024   (0-1023),           1025   ,    1024   。
            memset(&data_buffer[filesize],0x1A,(1024*(filesize/1024+1) - filesize));
    
            if (filesize % 1024 != 0)
            {
                filesize = 1024*(filesize/1024+1);
            }
            ChooseFile_flag = 1;
    
            while (1) 
            {   
                myPutString(4,1,"    ",1);
                myPutString(4,2,"     ",1);
                if (_bioskey(0) == ENTER)
                {
                    LCDcls();
                    break;
                }
            }
        }   
        else
        {
            ChooseFile_flag = 0;
            while (1)
            {
                myPutString(4,1,"    ",1);
                myPutString(4,2,"     ",1);
                if (_bioskey(0) == ENTER)
                {
                    LCDcls();
                    break;
                }
            }
        }
    

    以上の操作により、ファイルのオープンおよびデータの位置決め読み取りが完了します.
    ファイル削除
    ファイルの削除は簡単です.filedeleteでいいです.
        do
        {
            ret = _filedelete(&name[cn-1][0]);
        }while(ret != 0);
    
        LCDcls();
    
        num--;

    _filedeleteは削除するファイル名を入力し、結果0または1に戻ります.もちろん、削除する前にファイルを閉じてパスを設定する必要があります.
        _fcloseall();   /*           */
        _setcurdir("D:\\");

    マルチファイルを表示するウィジェット
    LOOP9:while(1)
        {   
            myPutString(4,1,"--    --",1);
            _setdispcolor(1);
    
    
            if((k!=0)||(fist==0))/*              */
            {
                for(i = 0;i < num;i++)
                { 
                    if(i == (cn-head))
                    {
                        myPutString(4,3+i,&name[cn-1][0],0);
                    }
                    else
                    {
                        myPutString(4,3+i,&name[i+head-1][0],1);
                    }
                    if ((i>=7)||(i>=num))
                    {
                        break;
                    }
                }
                fist = 1;
                k = 0;
            }
    
            k = _key_time(100);
    
            if(k==DOWN)
            {
                cn++;
                if (cn > tail) 
                {
                    head++;
                    tail++;
                }
                Oper_flag = 1;
            }           
            if(k==UP)
            {
                cn--;
                if (cn < head)
                {
                    head--;
                    tail--;
                }
                Oper_flag = 1;
            }       
            if(k==ENTER)
            {
                res = DeleteInfirm();
    
                if (res == 0)
                {
                    break;
                }
                else
                {
                    LCDcls();
                    goto LOOP9;
                }   
            }
            if(k==ESC)
            {
                LCDcls();
                return;
            }
            if(cn <= 0)
            {
                cn = num;
                if (num>7)
                {
                    head = num-6;
                    tail = num;
                }
                else
                {
                    head = 1;
                    tail = 7;
                }
            }               
            if(cn > num)
            {
                cn = 1;
                head = 1;
                tail = 7;
            }
        }

    このプログラムは,検索したファイル名をハンドヘルドに表示し,リスト形式で表示することを実現する.画面サイズの制限により、同じ画面に最大7つのファイルが表示されます.ファイルが7つ余っている場合は、上下キーを押してファイル名のリフレッシュ上下移動を実現する必要があります.この小さなプログラムはこの機能を実現しています.