色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

寫flash意外斷電的處理方法

冬至子 ? 來源:小陳學不停 ? 作者:小陳學不停 ? 2023-07-21 16:33 ? 次閱讀

1 寫flash意外斷電
在寫flash時突然斷電可能會造成數據丟失,為了避免這種情況發生,我們可以加一層數據保護,在上電時檢查數據是否正確,如果不正確則使用備份的數據

2 內部flash還是以STM32F103ZET6為例可在ST官網下載文檔:PM0075
(STM32F10xxx Flash memory microcontrollers)

圖片

FLASH的最小擦除單位是扇區,扇區大小為2K

3 實現數據恢復
3.1 實現原理
-在保存數據時,對當前數據進行CRC校驗,把校驗結果一起寫入FLASH,同時再拷貝一份作為備份數據
-在上電加載參數時,對當前數據進行CRC校驗,對比校驗結果是否正確,如果不正確則使用備份數據,正確則不處理
3.1.1 測試數據
假設需要存儲的數據是這樣的:

typedef struct
{
  uint32_t times_clean;
  uint32_t times_error;
  uint8_t name[8];
  uint32_t crc32;
}test_data_t;

利用影子變量,每隔一定時間來檢查參數是否發生變化,如果變化了就把最新的數據寫入FLASH

if  (0  !=  rt_memcmp(&test_data,&test_data_shadow,sizeof(test_data_t)))
{
    uint32_t get_crc = crc32_customized(&test_data_shadow,sizeof(test_data_t)-4);
    test_data_shadow.crc32 = get_crc;         
    stm32_flash_erase(CONFIG_ADDRESS_TEST_DATA,sizeof(test_data_t)*2);
    stm32_flash_write(CONFIG_ADDRESS_TEST_DATA,&test_data_shadow,sizeof(test_data_t));         
    stm32_flash_write(CONFIG_ADDRESS_TEST_DATA+sizeof(test_data_t),&test_data_shadow,sizeof(test_data_t));   
    rt_memcpy(&test_data,&test_data_shadow,sizeof(test_data_t));
}

此時FLASH中的數據應該是這個樣子的:

圖片

3.2 實現代碼
3.2.1 需要被存儲的數據相關定義

#define CONFIG_ADDRESS_TEST_DATA        0x0807F800


#define CONFIG_HEAT_PARAMETER_DEFAULT   
{                                       
    .times_clean = 0,                   
    .times_error = 0,                   
    .name = "test",                     
};
test_data_t test_data =  CONFIG_HEAT_PARAMETER_DEFAULT;
test_data_t test_data_shadow = CONFIG_HEAT_PARAMETER_DEFAULT;
test_data_t test_data_bak = CONFIG_HEAT_PARAMETER_DEFAULT;

3.2.2 CRC32校驗API,與STM32的硬件CRC結果相同

#define CONFIG_CRC32_POLY              0x04C11DB7
#define CONFIG_CRC32_INIT_VALUE        0xFFFFFFFF
#define CONFIG_CRC32_OUT_XOR          0x00000000 


uint32_t crc32_stm32_hardware(uint8_t *source,uint32_t length)
{
    uint32_t crc_value = CONFIG_CRC32_INIT_VALUE;


    for  (int i =0; i < length; i++)
    {
        for  (int j = 0; j < 8; j++)
        {
            uint8_t get_bit_value = ((source[i] > > (7 - j) & 1) == 1);
            uint8_t get_value = ((crc_value > > 31 & 1) == 1);
            crc_value < <= 1;
            if  (get_value ^ get_bit_value)
            {
                crc_value ^= CONFIG_CRC32_POLY;
            }
        }
    }


    crc_value &= 0xFFFFFFFF;


    return (crc_value ^= CONFIG_CRC32_OUT_XOR);
}

3.2.3 上電加載參數,檢查數據是否出錯,出錯則使用備份數據

void g_check_data(void)
{
    stm32_flash_read(CONFIG_ADDRESS_TEST_DATA,&test_data_shadow,sizeof(test_data_t));
    stm32_flash_read(CONFIG_ADDRESS_TEST_DATA+sizeof(test_data_t),&test_data_bak,sizeof(test_data_t));
    uint32_t crc_value_cal = crc32_stm32_hardware(&test_data_shadow,sizeof(test_data_t)-4);


    rt_kprintf("crc_value_cal[%x], crc_old[%x]rn",crc_value_cal,test_data_shadow.crc32);

    if  (crc_value_cal != test_data_shadow.crc32)
    {
        rt_kprintf("test data is invalidrn");

        rt_memcpy(&test_data_shadow,&test_data_bak,sizeof(test_data_t)-4);

        uint32_t crc_value_bak = crc32_stm32_hardware(&test_data_bak,sizeof(test_data_t)-4);

        test_data_shadow.crc32 = crc_value_bak;

        rt_memcpy(&test_data_shadow,&test_data_bak,sizeof(test_data_t)-4);
    }

    rt_memcpy(&test_data,&test_data_shadow,sizeof(test_data_t)); 
}

3.2.4 完整的測試代碼

int main(void)
{
    uint32_t get_crc_first = crc32_stm32_hardware(&test_data_shadow,sizeof(test_data_t)-4);

    test_data_shadow.crc32 = get_crc_first;
    test_data.crc32 = get_crc_first;

    g_check_data();

    while (1)
    {
         if (0 != rt_memcmp(&test_data,&test_data_shadow,sizeof(test_data_t)))
         {
             uint32_t get_crc = crc32_stm32_hardware(&test_data_shadow,sizeof(test_data_t)-4);

             test_data_shadow.crc32 = get_crc;

             rt_base_t level;

             level = rt_hw_interrupt_disable();

             stm32_flash_erase(CONFIG_ADDRESS_TEST_DATA,sizeof(test_data_t)*2);

             stm32_flash_write(CONFIG_ADDRESS_TEST_DATA,&test_data_shadow,sizeof(test_data_t));

             stm32_flash_write(CONFIG_ADDRESS_TEST_DATA+sizeof(test_data_t),&test_data_shadow,sizeof(test_data_t));

             rt_hw_interrupt_enable(level);

             rt_memcpy(&test_data,&test_data_shadow,sizeof(test_data_t));
         }
         
         rt_thread_mdelay(1000);
    }
}


int cmd_flash_protect_test(int argc, char **argv)
{
    if (2 == argc)
    {
        uint32_t get_type = atoi(argv[1]);


        if (0 == get_type)
        {
            g_check_data();
        }
        else if (1 == get_type)
        {
            test_data_shadow.times_clean++;
        }
    }

    return 0;
}
MSH_CMD_EXPORT_ALIAS(cmd_flash_protect_test,flash_protect,flash_protect [val]);

4 測試效果

| /
RT -     Thread Operating System
 / |      4.1.1 build Jul  1 2023 21:37:26
 2006 - 2022 Copyright by RT-Thread team
crc_value_cal[95663ff9], crc_old[95663ff9]
msh / >flash_protect 1
msh / >need write flash crc[ba0600aa]
old_data: times_clean:[6] times_error:[0] name[test] crc:[95663ff9] old_data end
new_data: times_clean:[7] times_error:[0] name[test] crc:[ba0600aa] new_data end
msh / >flash_protect 0
crc_value_cal[ba0600aa], crc_old[ba0600aa]

5 總結
這個方法不適合存儲的數據超過一個扇區大小,還需要根據實際情況來調整寫入和加載參數的方式
我們雖不能保證自己的軟件完全沒有BUG,但可以先寫一份軟件測試用例,將需要測試的每一個功能列成TODOLIST,再按照這個清單去自測,這樣就能在自測試發現并及時修正錯誤,反復測試多次后,我們再把軟件提交給測試可能會更好一些,工作中遇到困難是讓我們進步的,是提醒我們該優化自己的工作方法了。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 存儲器
    +關注

    關注

    38

    文章

    7637

    瀏覽量

    166531
  • CRC校驗
    +關注

    關注

    0

    文章

    84

    瀏覽量

    15526
  • RT-Thread
    +關注

    關注

    32

    文章

    1372

    瀏覽量

    41556
  • Flash單片機
    +關注

    關注

    0

    文章

    111

    瀏覽量

    9685
  • STM32F103ZET6
    +關注

    關注

    9

    文章

    67

    瀏覽量

    21627
收藏 0人收藏

    評論

    相關推薦
    熱點推薦

    STM32燒失敗錯誤的處理方法

    STM32燒失敗錯誤:Contents mismatch at: 08000000H (Flash=FFH Required=00H)
    的頭像 發表于 06-21 08:55 ?1.5w次閱讀
    STM32燒<b class='flag-5'>寫</b>失敗錯誤的<b class='flag-5'>處理</b><b class='flag-5'>方法</b>

    flash,要不要加個判斷?

    flash,要不要加個判斷?”這是我一個朋友的提問。
    的頭像 發表于 11-21 10:07 ?891次閱讀
    <b class='flag-5'>寫</b><b class='flag-5'>flash</b>,要不要加個判斷?

    *** Flash 成功燒 斷電不運行

    dsp *** 編寫的串口程序,用ccs4.1.2 成功調通,燒寫過程沒有問題,但是斷電后程序沒有正常運行。燒后進行了復位,也沒有反應
    發表于 03-01 16:02

    28035燒FLash出現錯誤

    之前燒寫過很多次,也沒事,今天燒FLash的時候突然出現這個問題:Flash API Error #24:The Erase operation failed the pre-compaction step
    發表于 11-09 14:21

    基于CCS的DSP片外Flash直接燒設計

    基于CCS的DSP片外Flash直接燒設計 自加載后DSP能夠正常運行,關鍵是Flash中原程序代碼的正確燒。CCS編譯生成的.out格式文件不能直接用于
    發表于 10-04 09:41 ?3732次閱讀
    基于CCS的DSP片外<b class='flag-5'>Flash</b>直接燒<b class='flag-5'>寫</b>設計

    JTAG接口在線燒Flash的實現

    本文闡述了一種針對TMS320VC5509A DSP 簡單有效的Flash方法, 并提出了程序自舉引導的實現方法。可以有效地解決程序代碼存儲問題和DSP 脫機自舉問題.
    發表于 09-16 14:43 ?1.6w次閱讀
    JTAG接口在線燒<b class='flag-5'>寫</b><b class='flag-5'>Flash</b>的實現

    FPGA配置– 使用JTAG是如何燒SPI/BPI Flash的?

    Xilinx的JTAG電纜可以通過FPGA“直接”燒SPI/BPI。很多對xilinx開發環境不熟悉的用戶,如果第一次接觸這種燒模式可能會有疑惑,FPGA是如何做到JTAG和Flash之間的橋接
    發表于 02-08 02:40 ?9644次閱讀
    FPGA配置– 使用JTAG是如何燒<b class='flag-5'>寫</b>SPI/BPI <b class='flag-5'>Flash</b>的?

    使用JTAG燒Nand Flash實驗解析

    4.4 實驗內容使用JTAG燒Nand Flash 1.實驗目的 通過使用JTAG燒Flash的實驗,了解嵌入式硬件環境,熟悉JTAG的使用,為今后的進一步學習打下良好的基礎。本書
    發表于 10-18 17:03 ?6次下載
    使用JTAG燒<b class='flag-5'>寫</b>Nand <b class='flag-5'>Flash</b>實驗解析

    基于DSP虹膜識別系統中Flash方法的研究

    基于DSP虹膜識別系統中Flash方法的研究
    發表于 10-19 14:41 ?2次下載
    基于DSP虹膜識別系統中<b class='flag-5'>Flash</b>燒<b class='flag-5'>寫</b><b class='flag-5'>方法</b>的研究

    CCS的DSP片外Flash直接燒設計

    CCS的DSP片外Flash直接燒設計
    發表于 10-20 08:29 ?3次下載
    CCS的DSP片外<b class='flag-5'>Flash</b>直接燒<b class='flag-5'>寫</b>設計

    如何采用DATA進行Flash的在線燒

    自加載后DSP能夠正常運行,關鍵是Flash中原程序代碼的正確燒。CCS編譯生成的.out格式文件不能直接用于Flash,在TI公司給出的技術文檔閉中,首先將.out文件利用其H
    的頭像 發表于 02-06 08:51 ?3929次閱讀
    如何采用DATA進行<b class='flag-5'>Flash</b>的在線燒<b class='flag-5'>寫</b>

    NOR Flash,Flash鎖死怎么辦 詳解NOR Flash方法

    上面的代碼中第4個操縱周期中的ADDR是從ARM處理器的角度來看的BYTE地址, 由于在執行操縱的時候,用戶希看指定的是從 ARM 的角度看到的地址,這樣會更方便和更直觀。
    的頭像 發表于 09-19 09:21 ?1.4w次閱讀

    HCC推出故障安全 防止意外復位或斷電的exFAT解決方案

    HCC推出故障安全,防止意外復位或斷電的exFAT解決方案
    的頭像 發表于 02-25 16:11 ?2457次閱讀

    可供用戶修改的FLASH驅動介紹

    為方便客戶針對 S698 芯片外接不同種類的 FLASH 進行在線編程。V8mon 的 FLASH 燒提供源碼可以進行用戶自行修改。FLASH
    發表于 06-08 14:39 ?0次下載
    可供用戶修改的<b class='flag-5'>FLASH</b>燒<b class='flag-5'>寫</b>驅動介紹

    stm32 flash數據怎么存儲的

    stm32 flash數據怎么存儲的? STM32是一款廣泛應用于嵌入式系統開發的微控制器,它的Flash存儲器是其中一個重要的組成部分。在本文中,我將詳細介紹STM32 Flash
    的頭像 發表于 01-31 15:46 ?3032次閱讀
    主站蜘蛛池模板: 含羞草影院免费区 | 99久视频只有精品2019 | 欧美最猛性xxxxx亚洲精品 | 一色狗影院| 狠狠操天天操夜夜操 | TUBE8最新日本护士 | 色综合99久久久国产AV | 久久久久久极精品久久久 | 无码日韩人妻精品久久蜜桃入口 | 日韩人妻少妇一区二区三区 | 一个人免费观看完整视频日本 | 亚洲 欧美 制服 校园 动漫 | 精品久久久噜噜噜久久7 | 好大太快了快插穿子宫了 | 99久久热视频只有精品 | 沟沟人体一区二区 | 天天影视色欲 影视 | 贵妇局长的蕾丝乳罩 | 亚洲 欧洲 国产 日产 综合 | 渔夫床满艳史bd高清在线直播 | 久久成人免费观看草草影院 | 麻豆免费观看高清完整视频在线 | 国产一卡2卡3卡4卡孕妇网站 | 一本道色播| 精品国产影院 | 无码不卡中文字幕在线观看 | 亚洲日本天堂在线 | 成人欧美尽粗二区三区AV | 亚洲伊人精品综合在合线 | 色男人的天堂久久综合 | 俄罗斯人与动ZOOZ | 亚洲精品在线观看视频 | 亚洲国产综合久久久无码色伦 | 国产色精品久久人妻无码 | 日本人的xxxxxxxxx69 | 成人在免费观看视频国产 | 亚洲VA欧美VA天堂V国产综合 | 老师的丝袜脚 | 亚洲综合久久一本伊伊区 | 边摸边吃奶边做下面视频 | 国产精品久久久久久熟妇吹潮软件 |

    電子發燒友

    中國電子工程師最喜歡的網站

    • 2931785位工程師會員交流學習
    • 獲取您個性化的科技前沿技術信息
    • 參加活動獲取豐厚的禮品