parent
040ada6f6c
commit
bc088cf2b8
84
Config.cpp
84
Config.cpp
|
@ -2,8 +2,8 @@
|
|||
#include "Flash.h"
|
||||
#include "Security\Crc.h"
|
||||
|
||||
//#define CFG_DEBUG DEBUG
|
||||
#define CFG_DEBUG 0
|
||||
#define CFG_DEBUG DEBUG
|
||||
//#define CFG_DEBUG 0
|
||||
#if CFG_DEBUG
|
||||
//#define CTS TS
|
||||
#else
|
||||
|
@ -11,7 +11,7 @@
|
|||
#define TS(name)
|
||||
#endif
|
||||
|
||||
Config* Config::Current = NULL;
|
||||
const Config* Config::Current = NULL;
|
||||
|
||||
/*================================ 配置块 ================================*/
|
||||
|
||||
|
@ -29,7 +29,7 @@ struct ConfigBlock
|
|||
const void* Data() const;
|
||||
|
||||
bool Init(const char* name, const Array& bs);
|
||||
bool Write(Storage* storage, uint addr, const Array& bs);
|
||||
bool Write(const Storage& storage, uint addr, const Array& bs);
|
||||
};
|
||||
|
||||
ushort ConfigBlock::GetHash() const
|
||||
|
@ -43,6 +43,7 @@ bool ConfigBlock::Valid() const
|
|||
return GetHash() == Hash;
|
||||
}
|
||||
|
||||
// 获取下一块。当前块必须有效,否则返回空,下一块不在乎有效无效
|
||||
const ConfigBlock* ConfigBlock::Next() const
|
||||
{
|
||||
if(!Valid()) return NULL;
|
||||
|
@ -71,6 +72,7 @@ bool ConfigBlock::Init(const char* name, const Array& bs)
|
|||
if(slen > sizeof(Name)) return false;
|
||||
|
||||
if(slen > ArrayLength(Name)) slen = ArrayLength(Name);
|
||||
// 无论如何,把整个名称区域清空
|
||||
memset(Name, 0, ArrayLength(Name));
|
||||
|
||||
// 配置块的大小,只有第一次能够修改,以后即使废弃也不能修改,仅仅清空名称
|
||||
|
@ -86,16 +88,14 @@ bool ConfigBlock::Init(const char* name, const Array& bs)
|
|||
}
|
||||
|
||||
// 更新块
|
||||
bool ConfigBlock::Write(Storage* storage, uint addr, const Array& bs)
|
||||
bool ConfigBlock::Write(const Storage& storage, uint addr, const Array& bs)
|
||||
{
|
||||
assert_ptr(storage);
|
||||
|
||||
TS("ConfigBlock::Write");
|
||||
|
||||
// 如果大小超标,并且下一块有效,那么这是非法操作
|
||||
if(bs.Length() > Size && Next()->Valid())
|
||||
{
|
||||
debug_printf("ConfigBlock::Write 配置块 %s 大小 %d 小于要写入的数据库大小 %d,并且下一块是有效配置块,不能覆盖! \r\n", Name, Size, bs.Length());
|
||||
debug_printf("ConfigBlock::Write 配置块 %s 大小 %d 小于要写入的数据大小 %d,并且下一块是有效配置块,不能覆盖! \r\n", Name, Size, bs.Length());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -103,12 +103,12 @@ bool ConfigBlock::Write(Storage* storage, uint addr, const Array& bs)
|
|||
|
||||
// 先写入头部,然后写入数据
|
||||
uint len = sizeof(ConfigBlock) - offsetof(ConfigBlock, Hash);
|
||||
if(!storage->Write(addr, Array(&Hash, len))) return false;
|
||||
if(!storage.Write(addr, Array(&Hash, len))) return false;
|
||||
if(bs.Length() > 0)
|
||||
{
|
||||
uint len2 = bs.Length();
|
||||
if(len2 > Size) len2 = Size;
|
||||
if(!storage->Write(addr + len, Array(bs.GetBuffer(), len2))) return false;
|
||||
if(!storage.Write(addr + len, Array(bs.GetBuffer(), len2))) return false;
|
||||
}
|
||||
|
||||
return rs;
|
||||
|
@ -116,14 +116,15 @@ bool ConfigBlock::Write(Storage* storage, uint addr, const Array& bs)
|
|||
|
||||
/*================================ 配置 ================================*/
|
||||
|
||||
Config::Config(Storage* st, uint addr)
|
||||
Config::Config(const Storage& st, uint addr, uint size)
|
||||
: Device(st)
|
||||
{
|
||||
Device = st;
|
||||
Address = addr;
|
||||
Size = size;
|
||||
}
|
||||
|
||||
// 循环查找配置块
|
||||
const void* Config::Find(const char* name, int size)
|
||||
// 循环查找配置块。如果找不到而又指明了大小,则找一个满足该大小的空闲数据块,或者在最后划分一个
|
||||
const void* Config::Find(const char* name, int size) const
|
||||
{
|
||||
TS("Config::Find");
|
||||
|
||||
|
@ -138,11 +139,12 @@ const void* Config::Find(const char* name, int size)
|
|||
{
|
||||
if(!size) return NULL;
|
||||
|
||||
Device->Write(addr, Array(&c_Version, sizeof(c_Version)));
|
||||
Device.Write(addr, Array(&c_Version, sizeof(c_Version)));
|
||||
}
|
||||
|
||||
addr += sizeof(c_Version);
|
||||
auto cfg = (const ConfigBlock*)addr;
|
||||
|
||||
uint slen = strlen(name);
|
||||
if(slen > sizeof(cfg->Name)) return NULL;
|
||||
//assert_param2(slen <= sizeof(cfg->Name), "配置段名称最大4个字符");
|
||||
|
@ -155,30 +157,34 @@ const void* Config::Find(const char* name, int size)
|
|||
cfg = cfg->Next();
|
||||
}
|
||||
|
||||
// 如果需要添加,返回最后一个非法块的地址
|
||||
//return fAppend ? cfg : NULL;
|
||||
|
||||
if(!size) return NULL;
|
||||
|
||||
// 找一块合适的区域
|
||||
// 找一块合适大小的空闲区域
|
||||
cfg = (const ConfigBlock*)addr;
|
||||
while(cfg->Valid())
|
||||
{
|
||||
if(cfg->Name[0] && cfg->Size == size) return cfg;
|
||||
if(cfg->Name[0] == 0 && cfg->Size == size) return cfg;
|
||||
|
||||
cfg = cfg->Next();
|
||||
}
|
||||
|
||||
// 实在没办法,最后划分一个新的区块。这里判断一下空间是否足够
|
||||
if(Size && (uint)(byte*)cfg + sizeof(ConfigBlock) + size <= Address + Size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
// 废弃
|
||||
bool Config::Invalid(const char* name)
|
||||
bool Config::Invalid(const char* name) const
|
||||
{
|
||||
return Set(name, ByteArray(0));
|
||||
}
|
||||
|
||||
// 根据名称更新块
|
||||
const void* Config::Set(const char* name, const Array& bs)
|
||||
const void* Config::Set(const char* name, const Array& bs) const
|
||||
{
|
||||
TS("Config::Set");
|
||||
|
||||
|
@ -201,7 +207,7 @@ const void* Config::Set(const char* name, const Array& bs)
|
|||
}
|
||||
|
||||
// 获取配置数据
|
||||
bool Config::Get(const char* name, Array& bs)
|
||||
bool Config::Get(const char* name, Array& bs) const
|
||||
{
|
||||
TS("Config::Get");
|
||||
|
||||
|
@ -220,7 +226,7 @@ bool Config::Get(const char* name, Array& bs)
|
|||
return false;
|
||||
}
|
||||
|
||||
const void* Config::Get(const char* name)
|
||||
const void* Config::Get(const char* name) const
|
||||
{
|
||||
TS("Config::GetByName");
|
||||
|
||||
|
@ -234,7 +240,7 @@ const void* Config::Get(const char* name)
|
|||
}
|
||||
|
||||
// 获取配置数据,如果不存在则覆盖
|
||||
bool Config::GetOrSet(const char* name, Array& bs)
|
||||
bool Config::GetOrSet(const char* name, Array& bs) const
|
||||
{
|
||||
TS("Config::GetOrSet");
|
||||
|
||||
|
@ -251,21 +257,21 @@ bool Config::GetOrSet(const char* name, Array& bs)
|
|||
}
|
||||
|
||||
// Flash最后一块作为配置区
|
||||
Config& Config::CreateFlash()
|
||||
const Config& Config::CreateFlash()
|
||||
{
|
||||
// 最后一块作为配置区
|
||||
static Flash flash;
|
||||
static Config cfg(&flash, flash.Start + flash.Size - flash.Block);
|
||||
static Config cfg(flash, flash.Start + flash.Size - flash.Block, flash.Block);
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
// RAM最后一小段作为热启动配置区
|
||||
Config& Config::CreateRAM()
|
||||
const Config& Config::CreateRAM()
|
||||
{
|
||||
// 最后一块作为配置区
|
||||
static CharStorage cs;
|
||||
static Config cfg(&cs, Sys.StackTop());
|
||||
static Config cfg(cs, Sys.StackTop(), 64);
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
@ -273,12 +279,10 @@ Config& Config::CreateRAM()
|
|||
/******************************** ConfigBase ********************************/
|
||||
|
||||
ConfigBase::ConfigBase()
|
||||
: Cfg(*Config::Current)
|
||||
{
|
||||
// Flash最后一块作为配置区
|
||||
if(!Config::Current) Config::Current = &Config::CreateFlash();
|
||||
assert_ptr(&Cfg);
|
||||
|
||||
Cfg = Config::Current;
|
||||
|
||||
New = true;
|
||||
|
||||
_Name = NULL;
|
||||
|
@ -308,11 +312,9 @@ void ConfigBase::Init()
|
|||
|
||||
void ConfigBase::Load()
|
||||
{
|
||||
if(!Cfg) return;
|
||||
|
||||
// 尝试加载配置区设置
|
||||
auto bs = ToArray();
|
||||
New = !Cfg->GetOrSet(_Name, bs);
|
||||
New = !Cfg.GetOrSet(_Name, bs);
|
||||
if(New)
|
||||
debug_printf("%s::Load 首次运行,创建配置区!\r\n", _Name);
|
||||
else
|
||||
|
@ -321,22 +323,18 @@ void ConfigBase::Load()
|
|||
|
||||
void ConfigBase::Save() const
|
||||
{
|
||||
if(!Cfg) return;
|
||||
|
||||
debug_printf("%s::Save \r\n", _Name);
|
||||
|
||||
Cfg->Set(_Name, ToArray());
|
||||
Cfg.Set(_Name, ToArray());
|
||||
}
|
||||
|
||||
void ConfigBase::Clear()
|
||||
{
|
||||
if(!Cfg) return;
|
||||
|
||||
Init();
|
||||
|
||||
debug_printf("%s::Clear \r\n", _Name);
|
||||
|
||||
Cfg->Set(_Name, ToArray());
|
||||
Cfg.Set(_Name, ToArray());
|
||||
}
|
||||
|
||||
void ConfigBase::Show() const
|
||||
|
@ -363,7 +361,7 @@ void* HotConfig::Next() const
|
|||
|
||||
HotConfig& HotConfig::Current()
|
||||
{
|
||||
static Config& cfg = Config::CreateRAM();
|
||||
static const Config& cfg = Config::CreateRAM();
|
||||
|
||||
// 查找配置数据,如果不存在,则清空
|
||||
auto dat = cfg.Get("Hot");
|
||||
|
|
27
Config.h
27
Config.h
|
@ -12,30 +12,31 @@ class Config
|
|||
private:
|
||||
|
||||
public:
|
||||
Storage* Device;
|
||||
uint Address;
|
||||
const Storage& Device; // 配置存储的设备
|
||||
uint Address; // 在存储区中的起始地址
|
||||
uint Size; // 在存储区中的可用空间大小
|
||||
|
||||
Config(Storage* st, uint addr);
|
||||
Config(const Storage& st, uint addr, uint size);
|
||||
|
||||
// 查找。size不为0时表示要查找该大小的合适配置块
|
||||
const void* Find(const char* name, int size = 0);
|
||||
const void* Find(const char* name, int size = 0) const;
|
||||
// 废弃。仅清空名称,并不删除数据区
|
||||
bool Invalid(const char* name);
|
||||
bool Invalid(const char* name) const;
|
||||
// 设置配置数据
|
||||
const void* Set(const char* name, const Array& bs);
|
||||
const void* Set(const char* name, const Array& bs) const;
|
||||
// 获取配置数据
|
||||
bool Get(const char* name, Array& bs);
|
||||
bool Get(const char* name, Array& bs) const;
|
||||
// 获取配置数据,如果不存在则覆盖
|
||||
bool GetOrSet(const char* name, Array& bs);
|
||||
bool GetOrSet(const char* name, Array& bs) const;
|
||||
// 获取配置数据
|
||||
const void* Get(const char* name);
|
||||
const void* Get(const char* name) const;
|
||||
|
||||
// 当前
|
||||
static Config* Current;
|
||||
static const Config* Current;
|
||||
// Flash最后一块作为配置区
|
||||
static Config& CreateFlash();
|
||||
static const Config& CreateFlash();
|
||||
// RAM最后一小段作为热启动配置区
|
||||
static Config& CreateRAM();
|
||||
static const Config& CreateRAM();
|
||||
};
|
||||
|
||||
/******************************** ConfigBase ********************************/
|
||||
|
@ -59,7 +60,7 @@ public:
|
|||
void Read(Stream& ms);
|
||||
|
||||
protected:
|
||||
Config* Cfg;
|
||||
const Config& Cfg;
|
||||
const char* _Name;
|
||||
|
||||
void* _Start;
|
||||
|
|
|
@ -44,13 +44,6 @@ TinyServer::TinyServer(TinyController* control)
|
|||
|
||||
bool TinyServer::Send(Message& msg) const
|
||||
{
|
||||
auto mg = (TinyMessage&) msg;
|
||||
|
||||
//如果目标地址为往关地址
|
||||
if(mg.Dest == Cfg->Address)
|
||||
{
|
||||
WriteCfg(mg);
|
||||
}
|
||||
// 附加目标物理地址
|
||||
//if(!msg.State)
|
||||
{
|
||||
|
@ -557,7 +550,7 @@ bool TinyServer::OnWriteReply(const Message& msg, Device& dv)
|
|||
return true;
|
||||
}
|
||||
|
||||
//设置zigbee的通道,2401无效
|
||||
// 设置zigbee的通道,2401无效
|
||||
void TinyServer::SetChannel(byte channel)
|
||||
{
|
||||
if(!Control) return;
|
||||
|
@ -573,33 +566,6 @@ void TinyServer::SetChannel(byte channel)
|
|||
}
|
||||
}
|
||||
|
||||
void TinyServer::WriteCfg(TinyMessage& msg)const
|
||||
{
|
||||
if(msg.Code != 0x16||msg.Reply||msg.Length < 2) return;
|
||||
|
||||
// 起始地址为7位压缩编码整数
|
||||
auto ms = msg.ToStream();
|
||||
uint offset = ms.ReadEncodeInt();
|
||||
if(offset < 64) return;
|
||||
offset -= 64;
|
||||
|
||||
auto tc = TinyConfig::Current;
|
||||
|
||||
//uint adrr = 64;
|
||||
int len = ms.Remain();
|
||||
if(offset + len > tc->Length) len = tc->Length - offset;
|
||||
if(len <= 0) return;
|
||||
|
||||
//Array bs(ms.Current(), len);
|
||||
//bs.CopyTo(&cfg + offset - 64, len);
|
||||
ByteArray cfg((byte*)&tc + offset, tc->Length - offset);
|
||||
ms.Read(cfg);
|
||||
|
||||
tc->Save();
|
||||
|
||||
Sys.Reset();
|
||||
}
|
||||
|
||||
Device* TinyServer::FindDevice(byte id) const
|
||||
{
|
||||
if(id == 0) return NULL;
|
||||
|
@ -658,15 +624,23 @@ bool TinyServer::DeleteDevice(byte id)
|
|||
return false;
|
||||
}
|
||||
|
||||
// 获取设备列表存储对象
|
||||
const Config GetStore(Flash& flash)
|
||||
{
|
||||
// 最后4k的位置作为存储位置
|
||||
uint addr = 0x8000000 + (Sys.FlashSize << 10) - (4 << 10);
|
||||
Config cfg(flash, addr, 4 << 10);
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
int TinyServer::LoadDevices()
|
||||
{
|
||||
TS("TinyServer::LoadDevices");
|
||||
|
||||
debug_printf("TinyServer::LoadDevices 加载设备!\r\n");
|
||||
// 最后4k的位置作为存储位置
|
||||
uint addr = 0x8000000 + (Sys.FlashSize << 10) - (4 << 10);
|
||||
Flash flash;
|
||||
Config cfg(&flash, addr);
|
||||
auto cfg = GetStore(flash);
|
||||
|
||||
byte* data = (byte*)cfg.Get("Devs");
|
||||
if(!data) return -1;
|
||||
|
@ -710,7 +684,7 @@ int TinyServer::LoadDevices()
|
|||
debug_printf("\r\n");
|
||||
}
|
||||
|
||||
debug_printf("TinyServer::LoadDevices 从 0x%08X 加载 %d 个设备!\r\n", addr, i);
|
||||
debug_printf("TinyServer::LoadDevices 从 0x%08X 加载 %d 个设备!\r\n", cfg.Address, i);
|
||||
|
||||
byte len = Devices.Length();
|
||||
debug_printf("Devices内已有节点 %d 个\r\n", len);
|
||||
|
@ -722,10 +696,8 @@ void TinyServer::SaveDevices() const
|
|||
{
|
||||
TS("TinyServer::SaveDevices");
|
||||
|
||||
// 最后4k的位置作为存储位置
|
||||
uint addr = 0x8000000 + (Sys.FlashSize << 10) - (4 << 10);
|
||||
Flash flash;
|
||||
Config cfg(&flash, addr);
|
||||
auto cfg = GetStore(flash);
|
||||
|
||||
byte buf[0x800];
|
||||
|
||||
|
@ -738,7 +710,7 @@ void TinyServer::SaveDevices() const
|
|||
Device* dv = Devices[i];
|
||||
dv->Write(ms);
|
||||
}
|
||||
debug_printf("TinyServer::SaveDevices 保存 %d 个设备到 0x%08X!\r\n", count, addr);
|
||||
debug_printf("TinyServer::SaveDevices 保存 %d 个设备到 0x%08X!\r\n", count, cfg.Address);
|
||||
cfg.Set("Devs", Array(ms.GetBuffer(), ms.Position()));
|
||||
}
|
||||
|
||||
|
@ -746,12 +718,10 @@ void TinyServer::ClearDevices()
|
|||
{
|
||||
TS("TinyServer::ClearDevices");
|
||||
|
||||
// 最后4k的位置作为存储位置
|
||||
uint addr = 0x8000000 + (Sys.FlashSize << 10) - (4 << 10);
|
||||
Flash flash;
|
||||
Config cfg(&flash, addr);
|
||||
auto cfg = GetStore(flash);
|
||||
|
||||
debug_printf("TinyServer::ClearDevices 清空设备列表 0x%08X \r\n", addr);
|
||||
debug_printf("TinyServer::ClearDevices 清空设备列表 0x%08X \r\n", cfg.Address);
|
||||
|
||||
cfg.Invalid("Devs");
|
||||
|
||||
|
@ -776,70 +746,6 @@ void TinyServer::ClearDevices()
|
|||
SaveDevices();
|
||||
}
|
||||
|
||||
bool TinyServer::LoadConfig()
|
||||
{
|
||||
TS("TinyServer::LoadConfig");
|
||||
|
||||
debug_printf("TinyServer::LoadDevices 加载设备!\r\n");
|
||||
// 最后4k的位置作为存储位置
|
||||
uint addr = 0x8000000 + (Sys.FlashSize << 10) - (4 << 10);
|
||||
Flash flash;
|
||||
Config cfg(&flash, addr);
|
||||
|
||||
byte* data = (byte*)cfg.Get("TCfg");
|
||||
if(!data)
|
||||
{
|
||||
SaveConfig(); // 没有就保存默认配置
|
||||
return true;
|
||||
}
|
||||
|
||||
Stream ms(data, sizeof(TinyConfig));
|
||||
// 读取配置信息
|
||||
Cfg->Read(ms);
|
||||
|
||||
debug_printf("TinyServer::LoadConfig 从 0x%08X 加载成功 !\r\n", addr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TinyServer::SaveConfig() const
|
||||
{
|
||||
TS("TinyServer::SaveConfig");
|
||||
|
||||
// 最后4k的位置作为存储位置
|
||||
uint addr = 0x8000000 + (Sys.FlashSize << 10) - (4 << 10);
|
||||
Flash flash;
|
||||
Config cfg(&flash, addr);
|
||||
|
||||
byte buf[sizeof(TinyConfig)];
|
||||
|
||||
Stream ms(buf, ArrayLength(buf));
|
||||
Cfg->Write(ms);
|
||||
|
||||
debug_printf("TinyServer::SaveConfig 保存到 0x%08X!\r\n", addr);
|
||||
|
||||
cfg.Set("TCfg", Array(ms.GetBuffer(), ms.Position()));
|
||||
}
|
||||
|
||||
void TinyServer::ClearConfig()
|
||||
{
|
||||
TS("TinyServer::ClearConfig");
|
||||
|
||||
debug_printf("TinyServer::ClearDevices 设备区清零!\r\n");
|
||||
// 最后4k的位置作为存储位置
|
||||
uint addr = 0x8000000 + (Sys.FlashSize << 10) - (4 << 10);
|
||||
Flash flash;
|
||||
Config cfg(&flash, addr);
|
||||
|
||||
debug_printf("TinyServer::ClearConfig 重置配置信息 0x%08X \r\n", addr);
|
||||
|
||||
cfg.Invalid("TCfg");
|
||||
|
||||
for(int i=0; i<Devices.Length(); i++)
|
||||
delete Devices[i];
|
||||
Devices.SetLength(0);
|
||||
}
|
||||
|
||||
// 输出所有设备
|
||||
void DeviceShow(void* param)
|
||||
{
|
||||
|
|
|
@ -44,10 +44,6 @@ public:
|
|||
|
||||
void SetChannel(byte channel);
|
||||
|
||||
void WriteCfg(TinyMessage& msg)const;
|
||||
bool LoadConfig();
|
||||
void SaveConfig() const;
|
||||
void ClearConfig();
|
||||
// 当前设备
|
||||
Device* Current;
|
||||
bool Study; //学习模式
|
||||
|
|
Loading…
Reference in New Issue