修复事件等待指定时间BUG;添加小文件完整性读写类
This commit is contained in:
parent
ac089c602e
commit
2a64a5073e
|
@ -379,6 +379,8 @@ void scanner_hw::thread_image_capture(bool paper_ready)
|
|||
int attempt = 0;
|
||||
while(paper_ready && scanning_ && attempt++ < 5)
|
||||
{
|
||||
mbev.first = -1;
|
||||
mbev.second = 0;
|
||||
if(mb_events_.take(mbev, true, to_lifter_)
|
||||
&& mbev.first == MOTOR_BORD_EVENT_LIFTER_READY)
|
||||
{
|
||||
|
@ -386,7 +388,7 @@ void scanner_hw::thread_image_capture(bool paper_ready)
|
|||
break;
|
||||
}
|
||||
else
|
||||
utils::to_log(LOG_LEVEL_FATAL, "Wait Lifter event(%d - 0x%08x) before scanning failed.\n", mbev.first, mbev.second);
|
||||
utils::to_log(LOG_LEVEL_FATAL, "Wait Lifter event before scanning failed, get event(%d - 0x%08x).\n", mbev.first, mbev.second);
|
||||
motor_->start();
|
||||
}
|
||||
if(mbev.first == MOTOR_BORD_EVENT_LIFTER_READY)
|
||||
|
@ -477,19 +479,19 @@ void scanner_hw::thread_image_capture(bool paper_ready)
|
|||
// wait paper ...
|
||||
while(auto_scan_)
|
||||
{
|
||||
mbev.first = -1;
|
||||
mbev.second = 0;
|
||||
if(mb_events_.take(mbev, true))
|
||||
{
|
||||
if(mbev.first == MOTOR_BORD_EVENT_PAPER_READY)
|
||||
{
|
||||
motor_->start();
|
||||
printf("paper ready: %d-%x\n", mbev.first, mbev.second);
|
||||
mb_events_.take(mbev, true, to_lifter_);
|
||||
motor_->start();
|
||||
break;
|
||||
}
|
||||
printf("motor-board event is %d\n", mbev.first);
|
||||
printf("\tmotor-board event is %d\n", mbev.first);
|
||||
}
|
||||
}
|
||||
printf("motor-board event is %d\n", mbev.first);
|
||||
}
|
||||
|
||||
if(scanning_ && mbev.first != MOTOR_BORD_EVENT_LIFTER_READY && times == 0)
|
||||
|
|
|
@ -12,9 +12,12 @@
|
|||
#define SIZE_MB(n) SIZE_KB((n) * 1024)
|
||||
#define SIZE_GB(n) SIZE_MB((n) * 1024)
|
||||
|
||||
#define SEC_2_MS(s) ((s) * 1000)
|
||||
#define MSEC_2_US(ms) ((ms) * 1000)
|
||||
#define USEC_2_NS(us) ((long)(us) * 1000)
|
||||
#define MSEC_2_US(ms) ((long)(ms) * 1000)
|
||||
#define SEC_2_MS(s) ((long)(s) * 1000)
|
||||
#define MSEC_2_NS(ms) USEC_2_NS(MSEC_2_US(ms))
|
||||
#define SEC_2_US(s) MSEC_2_US(SEC_2_MS(s))
|
||||
#define SEC_2_NS(s) USEC_2_NS(SEC_2_US(s))
|
||||
|
||||
#define MM_PER_INCH 25.4f
|
||||
#define IS_DOUBLE_EQUAL(a, b) fabs((a) - (b)) < .000001
|
||||
|
|
|
@ -1990,9 +1990,20 @@ bool platform_event::wait(unsigned timeout)
|
|||
utils::to_log(LOG_LEVEL_DEBUG, "clock_gettime failed: %d - %s\n", errno, strerror(errno));
|
||||
to.tv_sec = time(nullptr);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
//*/
|
||||
to.tv_nsec += MSEC_2_NS(timeout);
|
||||
to.tv_sec += to.tv_nsec / SEC_2_NS(1);
|
||||
to.tv_nsec %= SEC_2_NS(1);
|
||||
/*/
|
||||
to.tv_sec += timeout / 1000;
|
||||
to.tv_nsec += (long)((timeout % 1000) * 1000 * 1000);
|
||||
to.tv_nsec += MSEC_2_NS(timeout % 1000);
|
||||
if(to.tv_nsec >= SEC_2_NS(1))
|
||||
{
|
||||
to.tv_sec++;
|
||||
to.tv_nsec -= SEC_2_NS(1);
|
||||
}
|
||||
////////*//////////////////
|
||||
waited = sem_timedwait(&sem_, &to) == 0;
|
||||
}
|
||||
if (log_)
|
||||
|
@ -2350,4 +2361,126 @@ int safe_thread::stop(const char* thread_name)
|
|||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// safe_file
|
||||
safe_file::safe_file(const char* path)
|
||||
{
|
||||
set_file_path(path);
|
||||
}
|
||||
safe_file::~safe_file()
|
||||
{}
|
||||
|
||||
uint32_t safe_file::checksum(const void* data, size_t bytes, uint32_t prev)
|
||||
{
|
||||
uint32_t chk = prev, mask[] = {0, 0x0ff, 0x0ffff, 0x0ffffff};
|
||||
const uint32_t *d = (const uint32_t*)data;
|
||||
|
||||
for(int i = 0; i < bytes / 4; ++i)
|
||||
chk ^= *d++;
|
||||
chk ^= *d & mask[bytes % 4];
|
||||
|
||||
return chk;
|
||||
}
|
||||
std::string safe_file::load_with_check(const char* file, bool ignore_lost)
|
||||
{
|
||||
FILE* src = fopen(file, "rb");
|
||||
std::string cont("");
|
||||
|
||||
if(src)
|
||||
{
|
||||
long l = 0;
|
||||
|
||||
fseek(src, 0, SEEK_END);
|
||||
l = ftell(src);
|
||||
fseek(src, 0, SEEK_SET);
|
||||
if(l > sizeof(SFHEAD))
|
||||
{
|
||||
SFHEAD head;
|
||||
fread(&head, 1, sizeof(head), src);
|
||||
if(head.len == l - sizeof(head))
|
||||
{
|
||||
char buf[256] = {0};
|
||||
int r = fread(buf, 1, sizeof(buf), src);
|
||||
while(r > 0)
|
||||
{
|
||||
cont += std::string(buf, r);
|
||||
r = fread(buf, 1, sizeof(buf), src);
|
||||
}
|
||||
|
||||
uint32_t chk = checksum(&head, sizeof(head));
|
||||
|
||||
chk = checksum(cont.c_str(), cont.length(), chk);
|
||||
if(chk)
|
||||
{
|
||||
utils::to_log(LOG_LEVEL_FATAL, "Checksum(%08x) of safe_file(%s) failed!\n", chk, file);
|
||||
cont = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
iotimes_ = head.iotimes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
utils::to_log(LOG_LEVEL_FATAL, "safe_file(%s) length(%d) is mismatched(%d)!\n", file, (int)l, head.len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
utils::to_log(LOG_LEVEL_FATAL, "safe_file(%s) length(%d) is too small!\n", file, (int)l);
|
||||
}
|
||||
fclose(src);
|
||||
}
|
||||
else if(!ignore_lost)
|
||||
{
|
||||
utils::to_log(LOG_LEVEL_FATAL, "open safe_file(%s) failed: %d(%s).\n", file, errno, strerror(errno));
|
||||
}
|
||||
|
||||
return std::move(cont);
|
||||
}
|
||||
|
||||
void safe_file::set_file_path(const char* path)
|
||||
{
|
||||
path_ = path ? path : "";
|
||||
iotimes_ = 0;
|
||||
}
|
||||
std::string safe_file::load(void)
|
||||
{
|
||||
std::string cont(load_with_check((path_ + tmp_appendix_).c_str(), true));
|
||||
|
||||
if(cont.empty())
|
||||
cont = load_with_check(path_.c_str(), false);
|
||||
|
||||
return std::move(cont);
|
||||
}
|
||||
int safe_file::save(const void* data, uint16_t bytes)
|
||||
{
|
||||
// io time ...
|
||||
if(iotimes_ == 0)
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
SFHEAD head;
|
||||
FILE *dst = nullptr;
|
||||
|
||||
head.chksum = 0;
|
||||
head.iotimes = ++iotimes_;
|
||||
head.len = bytes;
|
||||
head.time = time(nullptr);
|
||||
head.chksum = checksum(&head, sizeof(head));
|
||||
head.chksum = checksum(data, bytes, head.chksum);
|
||||
|
||||
dst = fopen((path_ + tmp_appendix_).c_str(), "wb");
|
||||
if(!dst)
|
||||
return errno;
|
||||
|
||||
fwrite(&head, 1, sizeof(head), dst);
|
||||
fwrite(data, 1, bytes, dst);
|
||||
fclose(dst);
|
||||
|
||||
return rename((path_ + tmp_appendix_).c_str(), path_.c_str());
|
||||
}
|
||||
|
|
|
@ -482,3 +482,36 @@ public:
|
|||
int start(std::function<void(void)> f, const char* thread_name, void* addr = nullptr);
|
||||
int stop(const char* thread_name);
|
||||
};
|
||||
|
||||
// Purpose: safe file ensure the integrity of small data files
|
||||
//
|
||||
// Format: (uint16_t)raw data len + (uint32_t)checksum + raw data
|
||||
//
|
||||
// Flow: when save, write into file 'name.new' first, and rename to 'name' at last
|
||||
// when read, check 'name.new' first, and open name if '.new' not exists
|
||||
class safe_file
|
||||
{
|
||||
typedef struct _sf_head // ensure this struct size be multiple of size uint32_t
|
||||
{
|
||||
uint32_t chksum;
|
||||
uint32_t time;
|
||||
uint64_t len : 16;
|
||||
uint64_t iotimes : 48;
|
||||
}SFHEAD, *LPSFHEAD;
|
||||
|
||||
const std::string tmp_appendix_ = ".new";
|
||||
std::string path_;
|
||||
uint64_t iotimes_ = 0;
|
||||
|
||||
uint32_t checksum(const void* data, size_t bytes, uint32_t prev = 0);
|
||||
std::string load_with_check(const char* file, bool ignore_lost);
|
||||
|
||||
public:
|
||||
safe_file(const char* path);
|
||||
~safe_file();
|
||||
|
||||
public:
|
||||
void set_file_path(const char* path);
|
||||
std::string load(void);
|
||||
int save(const void* data, uint16_t bytes);
|
||||
};
|
||||
|
|
|
@ -403,6 +403,10 @@ static uint8_t qiaoting[] = {128, 32
|
|||
}
|
||||
};
|
||||
|
||||
#define TEST_PLATFORM_EVENT
|
||||
#ifdef TEST_PLATFORM_EVENT
|
||||
platform_event to__("to");
|
||||
#endif
|
||||
ui_mgr::ui_mgr() : disp_data_("lcd-msg")
|
||||
{
|
||||
utils::init_log(LOG_TYPE_FILE);
|
||||
|
@ -428,10 +432,40 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
|
|||
|
||||
auto display = [this](void) -> void
|
||||
{
|
||||
#ifdef TEST_PLATFORM_EVENT
|
||||
printf("\tdisplay thread starting, sleep 3000ms ...\n");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
|
||||
printf("\tdisplay thread trigger event ...\n");
|
||||
to__.trigger();
|
||||
#endif
|
||||
thread_display();
|
||||
};
|
||||
#ifdef TEST_PLATFORM_EVENT
|
||||
to__.enable_log(false);
|
||||
#endif
|
||||
disp_thrd_.start(display, "thread_display");
|
||||
|
||||
#ifdef TEST_PLATFORM_EVENT
|
||||
// display thread starting, sleep 3000ms ...
|
||||
// [2024-02-18 08:01:54.349173] try wait 001: Failure
|
||||
// [2024-02-18 08:01:54.849311] try wait 002: Failure
|
||||
// [2024-02-18 08:01:55.349411] try wait 003: Failure
|
||||
// [2024-02-18 08:01:55.849550] try wait 004: Failure
|
||||
// [2024-02-18 08:01:56.349645] try wait 005: Failure
|
||||
// display thread trigger event ...
|
||||
// [2024-02-18 08:01:56.849441] try wait 006: OK
|
||||
// [2024-02-18 08:01:57.349550] try wait 007: Failure
|
||||
// [2024-02-18 08:01:57.849659] try wait 008: Failure
|
||||
int up = 10000;
|
||||
for(int i = 0; i < up; ++i)
|
||||
{
|
||||
bool wait = to__.wait(500);
|
||||
printf("[%s] try wait %03d: %s\n", utils::format_current_time().c_str(), i + 1, wait ? "OK" : "Failure");
|
||||
if(wait)
|
||||
up = i + 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto statu = [this](devui::LPMSGSTREAM pack) -> void
|
||||
{
|
||||
if(pack->msg == devui::UI_STATUS_SCANNING)
|
||||
|
@ -462,6 +496,10 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
|
|||
disp_data_.save(dd, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
perm_data_->save();
|
||||
}
|
||||
}
|
||||
else if(pack->msg == devui::UI_STATUS_PAPER_CNT)
|
||||
{
|
||||
|
|
|
@ -136,40 +136,42 @@ class ui_mgr : public refer
|
|||
utils::create_folder(root_.c_str());
|
||||
root_ += PATH_SEPARATOR;
|
||||
|
||||
char buf[1024] = {0}, *ptr = buf;
|
||||
FILE *src = fopen((root_ + his_name_).c_str(), "rb");
|
||||
int len = 0;
|
||||
safe_file file((root_ + his_name_).c_str());
|
||||
std::string cont(file.load());
|
||||
char *ptr = &cont[0];
|
||||
LPSPEEDTM pspt = nullptr;
|
||||
|
||||
if(src)
|
||||
if(!cont.empty())
|
||||
{
|
||||
len = fread(buf, 1, sizeof(buf), src);
|
||||
fclose(src);
|
||||
history_cnt_ = *(uint64_t*)buf;
|
||||
|
||||
len -= sizeof(history_cnt_);
|
||||
ptr = buf + sizeof(history_cnt_);
|
||||
history_cnt_ = *(uint64_t*)ptr;
|
||||
ptr += sizeof(history_cnt_);
|
||||
pspt = (LPSPEEDTM)ptr;
|
||||
for(int i = 0; i < len / sizeof(*pspt); ++i)
|
||||
for(int i = 0; i < (cont.length() - sizeof(history_cnt_)) / sizeof(*pspt); ++i)
|
||||
{
|
||||
TIMES t = {0};
|
||||
t.history = pspt[i].ms;
|
||||
speed_times_[pspt[i].speed] = t;
|
||||
}
|
||||
}
|
||||
|
||||
src = fopen((root_ + rol_name_).c_str(), "rb");
|
||||
if(src)
|
||||
else
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
len = fread(buf, 1, sizeof(buf), src);
|
||||
fclose(src);
|
||||
roller_cnt_ = *(uint32_t*)buf;
|
||||
// test data:
|
||||
TIMES t = {0};
|
||||
|
||||
len -= sizeof(roller_cnt_);
|
||||
ptr = buf + sizeof(roller_cnt_);
|
||||
history_cnt_ = 711;
|
||||
t.history = 0x65642;
|
||||
speed_times_[816] = t;
|
||||
}
|
||||
|
||||
file.set_file_path((root_ + rol_name_).c_str());
|
||||
cont = file.load();
|
||||
if(!cont.empty())
|
||||
{
|
||||
ptr = &cont[0];
|
||||
roller_cnt_ = *(uint32_t*)ptr;
|
||||
ptr += sizeof(roller_cnt_);
|
||||
pspt = (LPSPEEDTM)ptr;
|
||||
for(int i = 0; i < len / sizeof(*pspt); ++i)
|
||||
for(int i = 0; i < (cont.length() - sizeof(roller_cnt_)) / sizeof(*pspt); ++i)
|
||||
{
|
||||
if(speed_times_.count(pspt[i].speed))
|
||||
{
|
||||
|
@ -178,11 +180,17 @@ class ui_mgr : public refer
|
|||
else
|
||||
{
|
||||
TIMES t = {0};
|
||||
t.roller = pspt[i].ms;
|
||||
t.history = t.roller = pspt[i].ms;
|
||||
speed_times_[pspt[i].speed] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// test data:
|
||||
roller_cnt_ = 257;
|
||||
speed_times_[816].roller = 0x2e54b;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -209,6 +217,11 @@ class ui_mgr : public refer
|
|||
speed_times_[speed_].roller += run_ms;
|
||||
if(hiscnt)
|
||||
*hiscnt = history_cnt_;
|
||||
if(adden_ > 10)
|
||||
{
|
||||
save();
|
||||
adden_ = 0;
|
||||
}
|
||||
|
||||
return roller_cnt_;
|
||||
}
|
||||
|
@ -217,6 +230,8 @@ class ui_mgr : public refer
|
|||
roller_cnt_ = 0;
|
||||
for(auto& v: speed_times_)
|
||||
v.second.roller = 0;
|
||||
|
||||
save();
|
||||
|
||||
return roller_cnt_;
|
||||
}
|
||||
|
@ -231,33 +246,31 @@ class ui_mgr : public refer
|
|||
}
|
||||
void save(void)
|
||||
{
|
||||
FILE *dst = fopen((root_ + his_name_).c_str(), "wb");
|
||||
if(dst)
|
||||
{
|
||||
fwrite(&history_cnt_, 1, sizeof(history_cnt_), dst);
|
||||
for(auto& v: speed_times_)
|
||||
{
|
||||
SPEEDTM stm = {0};
|
||||
stm.speed = v.first;
|
||||
stm.ms = v.second.history;
|
||||
fwrite(&stm, 1, sizeof(stm), dst);
|
||||
}
|
||||
fclose(dst);
|
||||
}
|
||||
safe_file file((root_ + his_name_).c_str());
|
||||
std::string cont((char*)&history_cnt_, sizeof(history_cnt_));
|
||||
|
||||
dst = fopen((root_ + rol_name_).c_str(), "wb");
|
||||
if(dst)
|
||||
for(auto& v: speed_times_)
|
||||
{
|
||||
fwrite(&roller_cnt_, 1, sizeof(roller_cnt_), dst);
|
||||
for(auto& v: speed_times_)
|
||||
SPEEDTM stm = {0};
|
||||
stm.speed = v.first;
|
||||
stm.ms = v.second.history;
|
||||
cont += std::string((char*)&stm, sizeof(stm));
|
||||
}
|
||||
file.save(cont.c_str(), cont.length());
|
||||
|
||||
cont = std::string((char*)&roller_cnt_, sizeof(roller_cnt_));
|
||||
for(auto& v: speed_times_)
|
||||
{
|
||||
if(v.second.roller)
|
||||
{
|
||||
SPEEDTM stm = {0};
|
||||
stm.speed = v.first;
|
||||
stm.ms = v.second.roller;
|
||||
fwrite(&stm, 1, sizeof(stm), dst);
|
||||
cont += std::string((char*)&stm, sizeof(stm));
|
||||
}
|
||||
fclose(dst);
|
||||
}
|
||||
file.set_file_path((root_ + rol_name_).c_str());
|
||||
file.save(cont.c_str(), cont.length());
|
||||
}
|
||||
};
|
||||
refer_guard<permanent_data> perm_data_;
|
||||
|
|
|
@ -60,8 +60,8 @@ add_packagedirs("sdk")
|
|||
add_defines("BUILD_AS_DEVICE")
|
||||
add_defines("VER_MAIN=2")
|
||||
add_defines("VER_FAMILY=200")
|
||||
add_defines("VER_DATE=20240208")
|
||||
add_defines("VER_BUILD=2")
|
||||
add_defines("VER_DATE=20240218")
|
||||
add_defines("VER_BUILD=20")
|
||||
|
||||
target("conf")
|
||||
set_kind("phony")
|
||||
|
|
Loading…
Reference in New Issue