找回密码
 立即注册
查看: 23|回复: 0

写了一个flash模拟EEPROM 的程序,大家看看有没有漏洞

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2026-05-02 15:44:47

24

主题

106

回帖

920

积分

高级会员

积分
920
发表于 昨天 15:44 | 显示全部楼层 |阅读模式
  1. #ifndef _EEPROM_IAP_H_
  2. #define _EEPROM_IAP_H_
  3. /* ========= Flash 配置 ========= */
  4. #define FLASH_BLOCK_SIZE    512
  5. #define FLASH_START_ADDR    0x0000
  6. #define FLASH_TOTAL_BLOCKS  8
  7. /* ========= EEPROM 配置 ========= */
  8. #define EEPROM_META_SIZE    8
  9. #define EEPROM_TOTAL_SIZE   3072   // 3KB 一页只用 504字节,要小于分配的Flash
  10. #define EEPROM_PAGE_SIZE    (FLASH_BLOCK_SIZE - EEPROM_META_SIZE) //6字节页元数据,2个预留
  11. #define EEPROM_PAGE_NUM     (EEPROM_TOTAL_SIZE / EEPROM_PAGE_SIZE)
  12. /* ========= API ========= */
  13. bit  EEPROM_Init(void);
  14. bit  EEPROM_ReadByte(uint16_t addr, uint8_t *dat);
  15. bit  EEPROM_WriteByte(uint16_t addr, uint8_t dat);
  16. bit  EEPROM_Read(uint16_t addr, uint8_t *buf, uint16_t len);
  17. bit  EEPROM_Write(uint16_t addr, uint8_t *buf, uint16_t len);
  18. bit  EEPROM_Save(void);
  19. #endif
复制代码
  1. #include "Config.h"
  2. #include "eeprom_iap.h"
  3. /* ========= 页缓存 ========= */
  4. static uint8_t xdata page_buf[EEPROM_PAGE_SIZE];
  5. static uint16_t cached_page = 0;
  6. static bit page_dirty = 0;
  7. /* ========= 页元数据 ========= */
  8. typedef struct {
  9.     uint16_t magic;
  10.     uint16_t seq;
  11.     uint16_t crc;
  12. } FlashPageMeta;
  13. /* ========= IAP 基础 ========= */
  14. #define IAP_ENABLE()    IAP_CONTR = 0x80
  15. #define IAP_DISABLE()   IAP_CONTR = 0x00
  16. #define IAP_WAIT()      while (IAP_CONTR & 0x01)
  17. static void Flash_EraseSector(uint16_t addr)
  18. {
  19.   //  EA = 0;
  20.     IAP_TPS = 22;
  21.     IAP_ENABLE();
  22.     IAP_CMD = 0x03;
  23.     IAP_ADDRH = addr >> 8;
  24.     IAP_ADDRL = addr & 0xFF;
  25.     IAP_TRIG = 0x5A;
  26.     IAP_TRIG = 0xA5;
  27.     IAP_WAIT();
  28.     IAP_DISABLE();
  29.   //  EA = 1;
  30. }
  31. static void Flash_WriteByte(uint16_t addr, uint8_t dat)
  32. {
  33.    // EA = 0;
  34.     IAP_TPS = 22;
  35.     IAP_ENABLE();
  36.     IAP_CMD = 0x02;
  37.     IAP_ADDRH = addr >> 8;
  38.     IAP_ADDRL = addr & 0xFF;
  39.     IAP_DATA = dat;
  40.     IAP_TRIG = 0x5A;
  41.     IAP_TRIG = 0xA5;
  42.     IAP_WAIT();
  43.     IAP_DISABLE();
  44.   //  EA = 1;
  45. }
  46. static uint8_t Flash_ReadByte(uint16_t addr)
  47. {
  48.     uint8_t dat;
  49.   //  EA = 0;
  50.     IAP_TPS = 22;
  51.     IAP_ENABLE();
  52.     IAP_CMD = 0x01;
  53.     IAP_ADDRH = addr >> 8;
  54.     IAP_ADDRL = addr & 0xFF;
  55.     IAP_TRIG = 0x5A;
  56.     IAP_TRIG = 0xA5;
  57.     IAP_WAIT();
  58.     dat = IAP_DATA;
  59.     IAP_DISABLE();
  60.   //  EA = 1;
  61.     return dat;
  62. }
  63. /* ========= CRC16 ========= */
  64. static uint16_t CRC16(uint8_t *p, uint16_t len)
  65. {
  66.     uint16_t crc = 0xFFFF;
  67.     uint16_t i, j;
  68.     for (i = 0; i < len; i++) {
  69.         crc ^= p[i];
  70.         for (j = 0; j < 8; j++) {
  71.             if (crc & 1)
  72.                 crc = (crc >> 1) ^ 0x8408;
  73.             else
  74.                 crc >>= 1;
  75.         }
  76.     }
  77.     return crc ^ 0xFFFF;
  78. }
  79. /* ========= 地址映射 ========= */
  80. static uint16_t addr_to_page(uint16_t addr)
  81. {
  82.     return addr / EEPROM_PAGE_SIZE;
  83. }
  84. static uint16_t addr_to_offset(uint16_t addr)
  85. {
  86.     return addr % EEPROM_PAGE_SIZE;
  87. }
  88. static uint16_t page_to_flash(uint16_t page)
  89. {
  90.     return FLASH_START_ADDR + page * FLASH_BLOCK_SIZE;
  91. }
  92. /* ========= 页加载 ========= */
  93. static bit load_page(uint16_t page)
  94. {
  95.     uint16_t i;
  96.     uint16_t flash_addr = page_to_flash(page);
  97.     FlashPageMeta meta;
  98.     meta.magic = Flash_ReadByte(flash_addr + 0) << 8 | Flash_ReadByte(flash_addr + 1);
  99.     meta.seq   = Flash_ReadByte(flash_addr + 2) << 8 | Flash_ReadByte(flash_addr + 3);
  100.     meta.crc   = Flash_ReadByte(flash_addr + 4) << 8 | Flash_ReadByte(flash_addr + 5);
  101.     if (meta.magic != 0x55AA) return 0;
  102.     for (i = 0; i < EEPROM_PAGE_SIZE; i++)
  103.         page_buf[i] = Flash_ReadByte(flash_addr + EEPROM_META_SIZE + i);
  104.     if (CRC16(page_buf, EEPROM_PAGE_SIZE) != meta.crc) return 0;
  105.     cached_page = page;
  106.     page_dirty = 0;
  107.     return 1;
  108. }
  109. /* ========= 页保存 ========= */
  110. static bit save_current_page(void)
  111. {
  112.     uint16_t i;
  113.     uint16_t flash_addr;
  114.     FlashPageMeta meta;
  115.     if (page_dirty==1)  //有修改
  116.      {
  117.        flash_addr = page_to_flash(cached_page);
  118.        Flash_EraseSector(flash_addr);
  119.        meta.magic = 0x55AA;
  120.        meta.seq   = Flash_ReadByte(flash_addr + 2) << 8 | Flash_ReadByte(flash_addr + 3) + 1;
  121.        meta.crc   = CRC16(page_buf, EEPROM_PAGE_SIZE);
  122.        Flash_WriteByte(flash_addr + 0, meta.magic >> 8);
  123.        Flash_WriteByte(flash_addr + 1, meta.magic & 0xFF);
  124.        Flash_WriteByte(flash_addr + 2, meta.seq >> 8);
  125.        Flash_WriteByte(flash_addr + 3, meta.seq & 0xFF);
  126.        Flash_WriteByte(flash_addr + 4, meta.crc >> 8);
  127.        Flash_WriteByte(flash_addr + 5, meta.crc & 0xFF);
  128.        for (i = 0; i < EEPROM_PAGE_SIZE; i++)
  129.           Flash_WriteByte(flash_addr + EEPROM_META_SIZE + i, page_buf[i]);
  130.        page_dirty=0;
  131.        printf(" SAVE........\r\n");
  132.      }
  133.     return 1;
  134. }
  135. /* ========= 页切换保护 ========= */
  136. static bit ensure_page(uint16_t page)
  137. {
  138.     if (cached_page == page) return 1;
  139.     if (!save_current_page()) return 0;
  140.     return load_page(page);
  141. }
  142. static bit is_empty_flash(void)
  143. {
  144.     uint16_t i;
  145.     uint16_t addr;
  146.     for (i = 0; i < EEPROM_PAGE_NUM; i++)
  147.       {
  148.         addr = page_to_flash(i);
  149.         if (Flash_ReadByte(addr) != 0xFF || Flash_ReadByte(addr + 1) != 0xFF) return 0;
  150.     }
  151.     return 1;
  152. }
  153. static bit init_empty_eeprom(void)
  154. {
  155.     uint16_t i;
  156.     uint16_t flash_addr = page_to_flash(0);
  157.     FlashPageMeta meta;
  158.     Flash_EraseSector(flash_addr);
  159.     meta.magic = 0x55AA;
  160.     meta.seq   = 1;
  161.     meta.crc   = CRC16(page_buf, EEPROM_PAGE_SIZE);
  162.     Flash_WriteByte(flash_addr + 0, meta.magic >> 8);
  163.     Flash_WriteByte(flash_addr + 1, meta.magic & 0xFF);
  164.     Flash_WriteByte(flash_addr + 2, meta.seq >> 8);
  165.     Flash_WriteByte(flash_addr + 3, meta.seq & 0xFF);
  166.     Flash_WriteByte(flash_addr + 4, meta.crc >> 8);
  167.     Flash_WriteByte(flash_addr + 5, meta.crc & 0xFF);
  168.     for (i = 0; i < EEPROM_PAGE_SIZE; i++)
  169.       {
  170.         Flash_WriteByte(flash_addr + EEPROM_META_SIZE + i, page_buf[i]);
  171.       }
  172.     cached_page = 0;
  173.     return 1;
  174. }
  175. /* ========= EEPROM API ========= */
  176. bit EEPROM_Init(void)
  177. {
  178.     if (is_empty_flash())         // 首次使用
  179.       {if(!init_empty_eeprom()) return 0;}
  180.     // 正常加载
  181.     if (!load_page(0)) return 0;
  182.     return 1;
  183. }
  184. bit EEPROM_ReadByte(uint16_t addr, uint8_t *dat)
  185. {
  186.     if (addr >= EEPROM_TOTAL_SIZE) return 0;
  187.     if (!ensure_page(addr_to_page(addr))) return 0;
  188.     *dat = page_buf[addr_to_offset(addr)];
  189.     return 1;
  190. }
  191. bit EEPROM_WriteByte(uint16_t addr, uint8_t dat)
  192. {
  193.    uint16_t page, offset;
  194.     if (addr >= EEPROM_TOTAL_SIZE) return 0;
  195.     page   = addr_to_page(addr);
  196.     offset = addr_to_offset(addr);
  197.     if (!ensure_page(page)) return 0;
  198.     if (page_buf[offset] != dat)
  199.       {
  200.         page_buf[offset] = dat;
  201.         page_dirty = 1;
  202.         printf(">");  
  203.       }
  204.     else
  205.         printf(" ");  
  206.     printf("[%04X]:%02bX\r\n",addr,dat);
  207.     return 1;
  208. }
  209. bit EEPROM_Read(uint16_t addr, uint8_t *buf, uint16_t len)
  210. {
  211.     uint16_t i;
  212.     if (addr + len > EEPROM_TOTAL_SIZE) return 0;
  213.     for (i = 0; i < len; i++)
  214.         if (!EEPROM_ReadByte(addr + i, &buf[i])) return 0;
  215.     return 1;
  216. }
  217. bit EEPROM_Write(uint16_t addr, uint8_t *buf, uint16_t len)
  218. {
  219.     uint16_t i;
  220.     if (addr + len > EEPROM_TOTAL_SIZE) return 0;
  221.     for (i = 0; i < len; i++)
  222.         if (!EEPROM_WriteByte(addr + i, buf[i])) return 0;
  223.     return 1;
  224. }
  225. bit EEPROM_Save(void)
  226. {
  227.    return save_current_page();
  228. }
复制代码
  1. #ifndef __CONFIG_H__
  2. #define __CONFIG_H__
  3. #include <AI8H.h>
  4. #include <def.h>
  5. #include <stdio.h>
  6. #include <intrins.h>
  7. #include <string.h>
  8. #include <stdarg.h>
  9. #include <math.h>
  10. #include <stdlib.h>
  11. #endif
复制代码
大家看看有没有漏洞
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-5-3 16:41 , Processed in 0.107920 second(s), 46 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表