写了一个flash模拟EEPROM 的程序,大家看看有没有漏洞
#ifndef _EEPROM_IAP_H_#define _EEPROM_IAP_H_
/* ========= Flash 配置 ========= */
#define FLASH_BLOCK_SIZE 512
#define FLASH_START_ADDR 0x0000
#define FLASH_TOTAL_BLOCKS8
/* ========= EEPROM 配置 ========= */
#define EEPROM_META_SIZE 8
#define EEPROM_TOTAL_SIZE 3072 // 3KB 一页只用 504字节,要小于分配的Flash
#define EEPROM_PAGE_SIZE (FLASH_BLOCK_SIZE - EEPROM_META_SIZE) //6字节页元数据,2个预留
#define EEPROM_PAGE_NUM (EEPROM_TOTAL_SIZE / EEPROM_PAGE_SIZE)
/* ========= API ========= */
bitEEPROM_Init(void);
bitEEPROM_ReadByte(uint16_t addr, uint8_t *dat);
bitEEPROM_WriteByte(uint16_t addr, uint8_t dat);
bitEEPROM_Read(uint16_t addr, uint8_t *buf, uint16_t len);
bitEEPROM_Write(uint16_t addr, uint8_t *buf, uint16_t len);
bitEEPROM_Save(void);
#endif
#include "Config.h"
#include "eeprom_iap.h"
/* ========= 页缓存 ========= */
static uint8_t xdata page_buf;
static uint16_t cached_page = 0;
static bit page_dirty = 0;
/* ========= 页元数据 ========= */
typedef struct {
uint16_t magic;
uint16_t seq;
uint16_t crc;
} FlashPageMeta;
/* ========= IAP 基础 ========= */
#define IAP_ENABLE() IAP_CONTR = 0x80
#define IAP_DISABLE() IAP_CONTR = 0x00
#define IAP_WAIT() while (IAP_CONTR & 0x01)
static void Flash_EraseSector(uint16_t addr)
{
//EA = 0;
IAP_TPS = 22;
IAP_ENABLE();
IAP_CMD = 0x03;
IAP_ADDRH = addr >> 8;
IAP_ADDRL = addr & 0xFF;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
IAP_WAIT();
IAP_DISABLE();
//EA = 1;
}
static void Flash_WriteByte(uint16_t addr, uint8_t dat)
{
// EA = 0;
IAP_TPS = 22;
IAP_ENABLE();
IAP_CMD = 0x02;
IAP_ADDRH = addr >> 8;
IAP_ADDRL = addr & 0xFF;
IAP_DATA = dat;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
IAP_WAIT();
IAP_DISABLE();
//EA = 1;
}
static uint8_t Flash_ReadByte(uint16_t addr)
{
uint8_t dat;
//EA = 0;
IAP_TPS = 22;
IAP_ENABLE();
IAP_CMD = 0x01;
IAP_ADDRH = addr >> 8;
IAP_ADDRL = addr & 0xFF;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
IAP_WAIT();
dat = IAP_DATA;
IAP_DISABLE();
//EA = 1;
return dat;
}
/* ========= CRC16 ========= */
static uint16_t CRC16(uint8_t *p, uint16_t len)
{
uint16_t crc = 0xFFFF;
uint16_t i, j;
for (i = 0; i < len; i++) {
crc ^= p;
for (j = 0; j < 8; j++) {
if (crc & 1)
crc = (crc >> 1) ^ 0x8408;
else
crc >>= 1;
}
}
return crc ^ 0xFFFF;
}
/* ========= 地址映射 ========= */
static uint16_t addr_to_page(uint16_t addr)
{
return addr / EEPROM_PAGE_SIZE;
}
static uint16_t addr_to_offset(uint16_t addr)
{
return addr % EEPROM_PAGE_SIZE;
}
static uint16_t page_to_flash(uint16_t page)
{
return FLASH_START_ADDR + page * FLASH_BLOCK_SIZE;
}
/* ========= 页加载 ========= */
static bit load_page(uint16_t page)
{
uint16_t i;
uint16_t flash_addr = page_to_flash(page);
FlashPageMeta meta;
meta.magic = Flash_ReadByte(flash_addr + 0) << 8 | Flash_ReadByte(flash_addr + 1);
meta.seq = Flash_ReadByte(flash_addr + 2) << 8 | Flash_ReadByte(flash_addr + 3);
meta.crc = Flash_ReadByte(flash_addr + 4) << 8 | Flash_ReadByte(flash_addr + 5);
if (meta.magic != 0x55AA) return 0;
for (i = 0; i < EEPROM_PAGE_SIZE; i++)
page_buf = Flash_ReadByte(flash_addr + EEPROM_META_SIZE + i);
if (CRC16(page_buf, EEPROM_PAGE_SIZE) != meta.crc) return 0;
cached_page = page;
page_dirty = 0;
return 1;
}
/* ========= 页保存 ========= */
static bit save_current_page(void)
{
uint16_t i;
uint16_t flash_addr;
FlashPageMeta meta;
if (page_dirty==1)//有修改
{
flash_addr = page_to_flash(cached_page);
Flash_EraseSector(flash_addr);
meta.magic = 0x55AA;
meta.seq = Flash_ReadByte(flash_addr + 2) << 8 | Flash_ReadByte(flash_addr + 3) + 1;
meta.crc = CRC16(page_buf, EEPROM_PAGE_SIZE);
Flash_WriteByte(flash_addr + 0, meta.magic >> 8);
Flash_WriteByte(flash_addr + 1, meta.magic & 0xFF);
Flash_WriteByte(flash_addr + 2, meta.seq >> 8);
Flash_WriteByte(flash_addr + 3, meta.seq & 0xFF);
Flash_WriteByte(flash_addr + 4, meta.crc >> 8);
Flash_WriteByte(flash_addr + 5, meta.crc & 0xFF);
for (i = 0; i < EEPROM_PAGE_SIZE; i++)
Flash_WriteByte(flash_addr + EEPROM_META_SIZE + i, page_buf);
page_dirty=0;
printf(" SAVE........\r\n");
}
return 1;
}
/* ========= 页切换保护 ========= */
static bit ensure_page(uint16_t page)
{
if (cached_page == page) return 1;
if (!save_current_page()) return 0;
return load_page(page);
}
static bit is_empty_flash(void)
{
uint16_t i;
uint16_t addr;
for (i = 0; i < EEPROM_PAGE_NUM; i++)
{
addr = page_to_flash(i);
if (Flash_ReadByte(addr) != 0xFF || Flash_ReadByte(addr + 1) != 0xFF) return 0;
}
return 1;
}
static bit init_empty_eeprom(void)
{
uint16_t i;
uint16_t flash_addr = page_to_flash(0);
FlashPageMeta meta;
Flash_EraseSector(flash_addr);
meta.magic = 0x55AA;
meta.seq = 1;
meta.crc = CRC16(page_buf, EEPROM_PAGE_SIZE);
Flash_WriteByte(flash_addr + 0, meta.magic >> 8);
Flash_WriteByte(flash_addr + 1, meta.magic & 0xFF);
Flash_WriteByte(flash_addr + 2, meta.seq >> 8);
Flash_WriteByte(flash_addr + 3, meta.seq & 0xFF);
Flash_WriteByte(flash_addr + 4, meta.crc >> 8);
Flash_WriteByte(flash_addr + 5, meta.crc & 0xFF);
for (i = 0; i < EEPROM_PAGE_SIZE; i++)
{
Flash_WriteByte(flash_addr + EEPROM_META_SIZE + i, page_buf);
}
cached_page = 0;
return 1;
}
/* ========= EEPROM API ========= */
bit EEPROM_Init(void)
{
if (is_empty_flash()) // 首次使用
{if(!init_empty_eeprom()) return 0;}
// 正常加载
if (!load_page(0)) return 0;
return 1;
}
bit EEPROM_ReadByte(uint16_t addr, uint8_t *dat)
{
if (addr >= EEPROM_TOTAL_SIZE) return 0;
if (!ensure_page(addr_to_page(addr))) return 0;
*dat = page_buf;
return 1;
}
bit EEPROM_WriteByte(uint16_t addr, uint8_t dat)
{
uint16_t page, offset;
if (addr >= EEPROM_TOTAL_SIZE) return 0;
page = addr_to_page(addr);
offset = addr_to_offset(addr);
if (!ensure_page(page)) return 0;
if (page_buf != dat)
{
page_buf = dat;
page_dirty = 1;
printf(">");
}
else
printf(" ");
printf("[%04X]:%02bX\r\n",addr,dat);
return 1;
}
bit EEPROM_Read(uint16_t addr, uint8_t *buf, uint16_t len)
{
uint16_t i;
if (addr + len > EEPROM_TOTAL_SIZE) return 0;
for (i = 0; i < len; i++)
if (!EEPROM_ReadByte(addr + i, &buf)) return 0;
return 1;
}
bit EEPROM_Write(uint16_t addr, uint8_t *buf, uint16_t len)
{
uint16_t i;
if (addr + len > EEPROM_TOTAL_SIZE) return 0;
for (i = 0; i < len; i++)
if (!EEPROM_WriteByte(addr + i, buf)) return 0;
return 1;
}
bit EEPROM_Save(void)
{
return save_current_page();
}
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include <AI8H.h>
#include <def.h>
#include <stdio.h>
#include <intrins.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#include <stdlib.h>
#endif大家看看有没有漏洞
页:
[1]