合并写入,减少擦除次数

This commit is contained in:
大石头X2 2017-03-01 03:52:51 +08:00
parent 1eff827d45
commit b42f7c5ab3
5 changed files with 53 additions and 22 deletions

View File

@ -109,12 +109,26 @@ bool ConfigBlock::Write(const Storage& storage, uint addr, const Buffer& bs)
// 先写入头部,然后写入数据
uint len = sizeof(ConfigBlock) - offsetof(ConfigBlock, Hash);
if(!storage.Write(addr, Buffer(&Hash, len))) return false;
if(bs.Length() > 0)
// 合并写入,减少擦除次数
if(Size <= 512 && len + bs.Length() <= 512)
{
uint len2 = bs.Length();
if(len2 > Size) len2 = Size;
if(!storage.Write(addr + len, bs.Sub(0, len2))) return false;
byte buf[512];
Buffer ds(buf, 512);
ds.Copy(0, &Hash, len);
ds.Copy(len, bs, 0, bs.Length());
ds.SetLength(len + bs.Length());
if(!storage.Write(addr, ds)) return false;
}
else
{
if(!storage.Write(addr, Buffer(&Hash, len))) return false;
if(bs.Length() > 0)
{
uint len2 = bs.Length();
if(len2 > Size) len2 = Size;
if(!storage.Write(addr + len, bs.Sub(0, len2))) return false;
}
}
return true;

View File

@ -8,6 +8,7 @@ Flash::Flash()
Block = 0x400;
Start = 0x8000000;
ReadModifyWrite = true;
XIP = true;
OnInit();
}

View File

@ -11,6 +11,8 @@ public:
virtual bool WriteBlock(uint address, const byte* buf, int len, bool inc) const;
// 擦除块 (段地址)
virtual bool EraseBlock(uint address) const;
// 指定块是否被擦除
virtual bool IsErased(uint address, int len) const;
public:
Flash();

View File

@ -8,6 +8,11 @@
#define st_printf(format, ...)
#endif
WEAK bool ReadBlock(uint address, Buffer& bs)
{
return bs.Copy(0, (byte*)address, -1);
}
bool BlockStorage::Read(uint address, Buffer& bs) const
{
int len = bs.Length();
@ -19,7 +24,10 @@ bool BlockStorage::Read(uint address, Buffer& bs) const
st_printf("BlockStorage::Read(%p, %d, %p)\r\n", address, len, bs.GetBuffer());
#endif
bs.Copy(0, (byte*)address, -1);
if(XIP)
bs.Copy(0, (byte*)address, -1);
else
ReadBlock(address, bs);
return true;
}
@ -48,25 +56,28 @@ bool BlockStorage::Write(uint address, const Buffer& bs) const
// 长度也必须2字节对齐
if(len & 0x01) len++;
// 比较跳过相同数据
while(len)
if(XIP)
{
if(*(ushort*)address != *(ushort*)buf) break;
while(len)
{
if(*(ushort*)address != *(ushort*)buf) break;
address += 2;
buf += 2;
len -= 2;
}
// 从后面比较相同数据
while(len)
{
if(*(ushort*)(address + len - 2) != *(ushort*)(buf + len - 2)) break;
address += 2;
buf += 2;
len -= 2;
}
// 从后面比较相同数据
while(len)
{
if(*(ushort*)(address + len - 2) != *(ushort*)(buf + len - 2)) break;
len -= 2;
}
if(!len)
{
st_printf("数据相同,无需写入!\r\n");
return true;
len -= 2;
}
if(!len)
{
st_printf("数据相同,无需写入!\r\n");
return true;
}
}
// 如果没有读改写,直接执行
@ -201,6 +212,8 @@ bool BlockStorage::IsErased(uint address, int len) const
//st_printf("BlockStorage::IsErased(%p, %d)\r\n", address, len);
#endif
if(!XIP) return false;
ushort* p = (ushort*)address;
ushort* e = (ushort*)(address + len);

View File

@ -21,6 +21,7 @@ public:
uint Start; // 起始地址
int Block; // 每块字节数
bool ReadModifyWrite; // 是否读改写
bool XIP; // 是否映射片上执行
// 读取
virtual bool Read(uint address, Buffer& bs) const;