新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > avr eeprom保護方法

        avr eeprom保護方法

        作者: 時間:2016-11-23 來源:網(wǎng)絡 收藏
        在項目中復制出來的程序,使用時可能有些地方需要修改。
        編譯環(huán)境:WinAVR-20060421+AVRStudio4.12.498ServicePack4


        基本思路:每份寫到EEPRM的數(shù)據(jù),都做三個備份,每個備份的數(shù)據(jù)都做CRC16校驗,只要系統(tǒng)運行中出錯,錯誤地修改了EEPROM數(shù)據(jù),
        那么根據(jù)校驗字節(jié)就知道哪個備份的數(shù)據(jù)被修改了,然后用正確的備份覆蓋出錯的備份,達到數(shù)據(jù)恢復的目的。


        EEPROMSave.h文件:



        #defineEepromPageSize 64 //頁容量定義

        #defineEepromPage0Addr 0x0000 //各個頁的其始地址定義
        #defineEepromPage1Addr (EepromPage0Addr+EepromPageSize)
        #defineEepromPage2Addr (EepromPage1Addr+EepromPageSize)
        #defineEepromPage3Addr (EepromPage2Addr+EepromPageSize)
        #defineEepromPage4Addr (EepromPage3Addr+EepromPageSize)
        #defineEepromPage5Addr (EepromPage4Addr+EepromPageSize)
        #defineEepromPage6Addr (EepromPage5Addr+EepromPageSize)
        #defineEepromPage7Addr (EepromPage6Addr+EepromPageSize)



        #defineVALID 0x01
        #defineINVALID 0x00



        EEPROMSave.c文件:


        unsignedcharEepromReadByte(unsignedchar*address)
        {
        unsignedchardata;

        data=0;

        eeprom_busy_wait();
        data=eeprom_read_byte(address);

        returndata;
        }


        uint16_tEepromReadWord(uint16_t*address)
        {
        uint16_tdata;

        data=0;

        eeprom_busy_wait();
        data=eeprom_read_word(address);

        returndata;
        }


        voidEepromWriteByte(unsignedchar*address,unsignedchardata)
        {
        eeprom_busy_wait();
        eeprom_write_byte(address,data);
        }


        voidEepromWriteWord(unsignedint*address,unsignedintdata)
        {
        eeprom_busy_wait();
        eeprom_write_word(address,data);
        }


        voidEepromWriteBlock(unsignedchar*buff,unsignedchar*address,unsignedcharn)
        {
        unsignedchari;

        for(i=0;i<n;i++)
        {
        EepromWriteByte((unsignedchar*)(address+i),*buff);

        buff++;
        }
        }


        unsignedcharEepromCheck(unsignedchar*pdata,unsignedcharpacksize)
        {
        unsignedchari,j;
        unsignedintcrc,ref_crc;

        crc=0;
        ref_crc=0;

        for(i=0;i<(packsize-2);i++)
        {
        crc=crc^((uint16_t)EepromReadByte(pdata)<<8);

        for(j=0;j<8;j++)
        {
        if(crc&0x8000)
        {
        crc=(crc<<1)^0x1021;
        }
        else
        {
        crc=crc<<1;
        }
        }

        pdata++;
        }

        ref_crc=(uint16_t)EepromReadByte(pdata);
        ref_crc=ref_crc<<8;
        pdata++;
        ref_crc|=(uint16_t)EepromReadByte(pdata);

        if(crc==ref_crc)
        {
        returnVALID;
        }
        else
        {
        returnINVALID;
        }
        }


        unsignedcharCheckWriteCRC(unsignedchar*pdata,unsignedcharpacksize)
        {
        unsignedchari,j;
        unsignedintcrc;

        crc=0;

        for(i=0;i<(packsize-2);i++)
        {
        crc=crc^((uint16_t)EepromReadByte(pdata)<<8);

        for(j=0;j<8;j++)
        {
        if(crc&0x8000)
        {
        crc=(crc<<1)^0x1021;
        }
        else
        {
        crc=crc<<1;
        }
        }

        pdata++;
        }

        EepromWriteByte(pdata,(uint8_t)(crc>>8));
        pdata++;
        EepromWriteByte(pdata,(uint8_t)crc);
        pdata++;

        if(EepromCheck((pdata-packsize),packsize))
        {
        returnVALID;
        }
        else
        {
        returnINVALID;
        }
        }


        uint8_tCheckAllPage(void)
        {
        if((EepromCheck((unsignedchar*)EepromPage1Add,EepromPageSize)==VALID)
        &&(EepromCheck((unsignedchar*)EepromPage2Add,EepromPageSize)==VALID)
        &&(EepromCheck((unsignedchar*)EepromPage3Add,EepromPageSize)==VALID))
        {
        returnVALID;
        }

        returnINVALID;
        }


        uint8_tDataRecover(void)
        {
        unsignedchari;
        unsignedchartemp;
        unsignedcharpage;
        unsignedintinvalidpage[3];
        unsignedintvalidpage;

        invalidpage[0]=0;
        invalidpage[1]=0;
        invalidpage[2]=0;
        validpage=0;
        temp=0;
        page=0;

        if(EepromCheck((uint8_t*)EepromPage1Add,EepromPageSize)==VALID)
        {
        validpage=EepromPage1Add;
        }
        else
        {
        invalidpage[page]=EepromPage1Add;
        page++;
        }

        if(EepromCheck((uint8_t*)EepromPage2Add,EepromPageSize)==VALID)
        {
        validpage=EepromPage2Add;
        }
        else
        {
        invalidpage[page]=EepromPage2Add;
        page++;
        }

        if(EepromCheck((uint8_t*)EepromPage3Add,EepromPageSize)==VALID)
        {
        validpage=EepromPage3Add;
        }
        else
        {
        invalidpage[page]=EepromPage3Add;
        page++;
        }

        if(page==3) //三個備份都被破壞了
        {
        returnINVALID; //數(shù)據(jù)完全無效了
        }

        while((page--)>0) //數(shù)據(jù)恢復
        {
        for(i=0;i<EepromPageSize;i++)
        {
        temp=EepromReadByte((uint8_t*)(validpage+i));
        EepromWriteByte((uint8_t*)(invalidpage[page]+i),temp);
        }
        }

        if(CheckAllPage()==VALID)
        {
        returnVALID;
        }

        returnINVALID;
        }



        使用方法(三個備份):
        1、定義一個數(shù)組:EEPROMData[EepromPageSize-2],數(shù)組定義為EepromPageSize-2是為了給每個備份留2個字節(jié)的校驗
        2、要保存數(shù)據(jù)時,先把數(shù)據(jù)放到數(shù)組中,然后調(diào)用EepromWriteBlock()函數(shù),把這個數(shù)組的數(shù)據(jù)寫進EEPROM,三個備份要寫三次。
        3、寫完了之后,調(diào)用CheckWriteCRC()函數(shù),該函數(shù)會計算出當前備份的CRC16檢驗數(shù)據(jù)并寫到EEPROM備份的尾部,有多少個備份就要調(diào)用多少次。
        4、至此,數(shù)據(jù)的備份工作已經(jīng)完成。

        5、校驗數(shù)據(jù)(一般在復位后運行),執(zhí)行CheckAllPage()函數(shù),若通過了,則EEPROM數(shù)據(jù)沒有問題,否則要運行DataRecover()函數(shù),對損壞的備份進行修復






        ------------------修改原因:修改變量的定義形式


        關鍵詞: avreeprom保護方

        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 龙陵县| 徐州市| 德清县| 内丘县| 芷江| 日照市| 洛浦县| 民权县| 徐水县| 沁阳市| 鲁甸县| 谢通门县| 阳信县| 古田县| 饶平县| 都安| 定边县| 囊谦县| 灵武市| 柞水县| 太白县| 姚安县| 芦山县| 松潘县| 巢湖市| 抚州市| 余姚市| 启东市| 工布江达县| 镇原县| 潜江市| 甘肃省| 连江县| 琼结县| 镶黄旗| 扬州市| 阳新县| 凤庆县| 青海省| 顺义区| 新巴尔虎左旗|