调整图像包头信息;启动扫描成功返回硬件配置参数JSON

This commit is contained in:
gb 2024-01-23 15:07:17 +08:00
parent d98f5039a5
commit 4291bca09c
17 changed files with 346 additions and 147 deletions

View File

@ -355,11 +355,15 @@ void FpgaComm::setDelayTime(int value) {
WR_Reg(DelayTime);
}
bool FpgaComm::update()
bool FpgaComm::update(std::vector<int>* data)
{
bool good = true;
std::vector<int> d;
chronograph watch;
if(!data)
data = &d;
utils::to_log(LOG_LEVEL_DEBUG, "Read %u FpgaComm registers ...\n", MAX_REGS);
for(int i = 0; i < MAX_REGS; i++)
{
@ -369,6 +373,7 @@ bool FpgaComm::update()
utils::to_log(LOG_LEVEL_FATAL, " FATAL: Register %d(0x%08x) timeout.\n", i, fpgaParams.regs[i]);
break;
}
data->push_back(fpgaParams.regs[i]);
utils::to_log(LOG_LEVEL_DEBUG, " reg(%02d) = 0x%08x\n", i, fpgaParams.regs[i]);
}
utils::to_log(LOG_LEVEL_DEBUG, "Read FpgaComm registers over.\n");

View File

@ -1,6 +1,7 @@
#pragma once
#include <string>
#include <memory>
#include <vector>
#include "../uart/regsaccess.h"
#ifdef HAS_UV
@ -234,7 +235,7 @@ public:
void setDelayTime(int value);
void setTrigMode(bool isArmMode);
bool update();
bool update(std::vector<int>* data = nullptr);
void enableJamCheck(bool b);
void resetADC();
virtual bool write(unsigned int addr, unsigned int val);

View File

@ -240,7 +240,7 @@ void scanner_hw::init(void)
};
OPT_HANDLER(cntm)
{
scan_cntless_ = strcmp((char*)value, "\350\277\236\347\273\255\346\211\253\346\217\217") == 0;
};
OPT_HANDLER(cnt)
{
@ -331,7 +331,9 @@ void scanner_hw::thread_image_capture(void)
{
PACKIMAGE img(img_base_);
safe_fifo<int> avail_mem("v4l2-mem");
int used_v4l2_mem = 0, times = 0, minh = 210 * dpi_ / 25.4;
int used_v4l2_mem = 0, times = 0, minh = 210 * dpi_ / 25.4,
err = SCANNER_ERR_OK;
chronograph watch;
std::pair<int, int> mbev;
auto put_v4l2_mem = [&](BEFORE_DESTROY_PARAM) -> BEFORE_DESTROY_RET
@ -347,7 +349,7 @@ void scanner_hw::thread_image_capture(void)
motor_->start();
while(scanning_ && times++ < 5)
{
if(mb_events_.take(mbev, true, 5000))
if(mb_events_.take(mbev, true, to_lifter_))
{
utils::to_log(LOG_LEVEL_DEBUG, "take first motorboard event: %d - 0x%08x\n", mbev.first, mbev.second);
break;
@ -359,22 +361,27 @@ void scanner_hw::thread_image_capture(void)
times = 0;
while(scanning_ && mbev.first == MOTOR_BORD_EVENT_LIFTER_READY) // auto scan cycle ...
{
times++;
watch.reset();
motor_->pick_paper();
// scanning ONE turn ...
while(scanning_ && motor_->wait_paper_out(3000))
while(scanning_ && motor_->wait_paper_out(to_paper_out_))
{
img.height = get_image_real_height(minh);
size_t size = 0;
int ind = -1;
void* frame = camera_->read_frame(5 * 1000, size, ind);
void* frame = camera_->read_frame(to_stream_, size, ind);
dyn_mem_shared_ptr mem = nullptr;
if(!frame)
{
err = SCANNER_ERR_DEVICE_CIS_STREAM;
break;
}
img.prc_time = watch.elapse_ms();
printf("Fetch paper %d: %ums\n", img.pos.paper_ind + 1, img.prc_time);
mem = new dyn_mem_shared(frame, size, put_v4l2_mem, (void*)ind);
used_v4l2_mem++;
img.pos.paper_ind++;
@ -383,18 +390,20 @@ void scanner_hw::thread_image_capture(void)
img_handler_(mem, true, &img);
mem->release();
if(img.pos.paper_ind == scan_count_ || is_scan_fatal())
if((!scan_cntless_ && img.pos.paper_ind == scan_count_) || is_scan_fatal())
break;
// retrieve V4L2 memory ...
retrieve_v4l2_mem(&avail_mem, &used_v4l2_mem);
if(used_v4l2_mem >= camera_->get_mem_count())
{
err = SCANNER_ERR_DEVICE_CIS_OUT_OF_MEM;
stop_scan();
utils::to_log(LOG_LEVEL_FATAL, "Scanning stopped for that V4L2 is out of memory!\n");
break;
}
watch.reset();
motor_->pick_paper();
}
@ -412,6 +421,9 @@ void scanner_hw::thread_image_capture(void)
// wait paper ...
}
if(scanning_ && mbev.first != MOTOR_BORD_EVENT_LIFTER_READY && times == 0)
err = SCANNER_ERR_DEVICE_FEEDER_POS;
stop_scan();
while(used_v4l2_mem)
{
@ -428,7 +440,7 @@ void scanner_hw::thread_image_capture(void)
utils::to_log(LOG_LEVEL_DEBUG, "scanning thread exited.\n");
scanning_ = false;
img_handler_((dyn_mem_ptr)WORKER_STATUS_IDLE, false, 0);
img_handler_((dyn_mem_ptr)WORKER_STATUS_IDLE, false, (LPPACKIMAGE)err);
}
int scanner_hw::get_image_real_height(int minh)
{
@ -594,9 +606,10 @@ void scanner_hw::enable(const char* name, bool able)
}
// operation ...
int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler, std::string* cfgjson)
{
std::string tips("");
refer_guard<gb_json> cfg(new gb_json());
this->close();
int fh = 16380;
@ -630,6 +643,16 @@ int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
img_controller_->enableLed(cis_led_);
img_controller_->setVsp(66, 67);
utils::to_log(LOG_LEVEL_DEBUG, "FPGA Sp = %d, Sample = %d\n", sp_, sample_);
if(cfgjson)
{
cfg->set_value("color", mode_.c_str());
cfg->set_value("dpi", (std::to_string(dpi_) + " * " + std::to_string(dpi_y_)).c_str());
cfg->set_value("sample", sample_);
cfg->set_value("Sp", sp_);
cfg->set_value("Vsp-A", 66);
cfg->set_value("Vsp-B", 67);
cfg->set_value("Led-On", cis_led_);
}
void(FpgaComm::* exposure[])(int) = {&FpgaComm::setAExposureB, &FpgaComm::setAExposureG
, &FpgaComm::setAExposureR, &FpgaComm::setBExposureB, &FpgaComm::setBExposureG, &FpgaComm::setBExposureR};
@ -646,6 +669,16 @@ int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
tips += "];";
}
utils::to_log(LOG_LEVEL_DEBUG, "%s\n", tips.c_str());
if(cfgjson)
{
char val[128] = {0};
sprintf(val, "(%u, %u, %u)", exposure_[SIDE_FRONT][COLOR_IND_RED], exposure_[SIDE_FRONT][COLOR_IND_GREEN], exposure_[SIDE_FRONT][COLOR_IND_BLUE]);
cfg->set_value("exposure-A(RGB)", val);
sprintf(val, "(%u, %u, %u)", exposure_[SIDE_BACK][COLOR_IND_RED], exposure_[SIDE_BACK][COLOR_IND_GREEN], exposure_[SIDE_BACK][COLOR_IND_BLUE]);
cfg->set_value("exposure-B(RGB)", val);
}
for(int i = 0; i < CIS_SECTOR_COUNT; ++i)
{
@ -658,6 +691,19 @@ int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
img_controller_->setBOffset(i, off_[SIDE_BACK][i]);
utils::to_log(LOG_LEVEL_DEBUG, "%s\n", tips.c_str());
}
if(cfgjson)
{
for(int i = 0; i < CIS_SECTOR_COUNT; ++i)
{
char key[40] = {0}, val[128] = {0};
sprintf(key, "gain-sec-%d", i + 1);
sprintf(val, "A = %ux + %u, B = %ux + %u"
, gain_[SIDE_FRONT][i], off_[SIDE_FRONT][i]
, gain_[SIDE_BACK][i], off_[SIDE_BACK][i]);
cfg->set_value(key, val);
}
}
auto cb = [this](int ev, unsigned int data) -> void
{
@ -717,7 +763,19 @@ int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
// for(int i = 0; i < _countof(vals); ++i)
// img_controller_->write(i, vals[i]);
// }
img_controller_->update();
std::vector<int> regs;
img_controller_->update(&regs);
if(cfgjson)
{
gb_json *c = new gb_json();
c->clear(true);
for(auto& v: regs)
*c += v;
cfg->set_value("controller", c);
c->release();
*cfgjson = std::move(cfg->to_string());
}
return SCANNER_ERR_OK;
}

View File

@ -61,7 +61,8 @@ class scanner_hw : public sane_opt_provider
std::string family_ = "G200";
PACKIMAGE img_base_;
volatile bool auto_scan_ = false;
int scan_count_ = -1;
bool scan_cntless_ = true;
int scan_count_ = 1;
int cis_length_ = 3888;
bool cis_led_ = true;
int dpi_ = 300;
@ -89,6 +90,10 @@ class scanner_hw : public sane_opt_provider
std::map<std::string, std::function<void(void*)>> opt_handler_;
int to_lifter_ = 5000; // timeout in ms of lifter arrived
int to_paper_out_ = 3000; // timeout in ms of paper passed
int to_stream_ = 5000; // timeout in ms of frame data can be read
void init(void);
void init_version(std::string& text);
void thread_image_capture(void);
@ -111,7 +116,7 @@ public:
// operation ...
public:
int open(std::function<IMAGE_HANDLER_PROTO> image_handler);
int open(std::function<IMAGE_HANDLER_PROTO> image_handler, std::string* cfgjson = nullptr);
int start_scan(void);
int stop_scan(void);
int close(bool from_worker = false);

View File

@ -57,7 +57,7 @@ typedef struct SMB_CONFIG
unsigned int v_setting : 2;//10
unsigned int speed_set_enable : 1;
unsigned int double_out_en : 1;
unsigned int dpi_mode : 2;
// unsigned int sleep_parameter : 2;//6
// unsigned int dpi600:1;
@ -183,6 +183,9 @@ enum motor_board_port
MB_PORT_TIME, // ???
MB_PORT_FUNCTION,
MB_PORT_ULTROSONIC,
// I am the last
MB_PORT_COUNT
};
enum
{

View File

@ -22,68 +22,6 @@ rebuild::rebuild() : image_processor("rebuild")
rebuild::~rebuild()
{}
int rebuild::do_rebuild(PROCIMGINFO& in, std::vector<PROCIMGINFO>& out)
{
int ret = SCANNER_ERR_OK,
secl = cis::get_sector_pixels(0, in.info.resolution_x, true),
linel = cis::get_line_stream_length(in.info.resolution_x, false),
size = in.info.height * in.info.width / 2;
PROCIMGINFO o;
o.info = in.info;
if(in.info.pos.paper_side != PAPER_SIDE_BACK &&
in.info.pos.paper_side != PAPER_SIDE_FRONT)
linel *= 2;
if(in.info.width == linel) // gray
{
}
else // color
{
uint8_t *srcd = in.img.data + in.info.width * (in.info.height - 1), // line reverse
*dstf = (uint8_t*)malloc(size),
*dstb = (uint8_t*)malloc(size),
*df = dstf, *db = dstb,
soff[] = {11, 10, 9, 2, 1, 0};
o.info.channels = 3;
o.info.width /= 3 * 2;
o.info.prc_stage = get_position();
printf("rebuild (%d * %d * 8) to (%d * %d * 24), front = %p, back = %p, size = %u ...\n", in.info.width, in.info.height
, o.info.width, o.info.height, dstf, dstb, size);
for(int h = 0; h < in.info.height; ++h)
{
for(int w = 0; w < o.info.width; ++w)
{
int s = w / secl;
*df++ = srcd[(soff[s] + 0) * secl + (w % secl)];
*df++ = srcd[(soff[s] + 6) * secl + (w % secl)];
*df++ = srcd[(soff[s] + 3) * secl + (w % secl)];
*db++ = srcd[in.info.width / 2 + (soff[s] + 6) * secl + (w % secl)];
*db++ = srcd[in.info.width / 2 + (soff[s] + 0) * secl + (w % secl)];
*db++ = srcd[in.info.width / 2 + (soff[s] + 3) * secl + (w % secl)];
}
srcd -= in.info.width;
}
printf(" bits data ready, construct cv::Mat(front = %u, back = %u) ...\n", df - dstf, db - dstb);
o.info.pos.paper_side = PAPER_SIDE_FRONT;
o.img = cv::Mat(o.info.height, o.info.width, CV_8UC3, (void*)dstf, size);
out.push_back(o);
// free(dstf);
o.info.pos.paper_side = PAPER_SIDE_BACK;
o.img = (cv::Mat(o.info.height, o.info.width, CV_8UC3, (void*)dstb, size));
out.push_back(o);
// free(dstb);
}
return ret;
}
int rebuild::set_value(const char* name/*nullptr for all options*/, void* val/*nullptr for restore*/)
{
int ret = SCANNER_ERR_OK;
@ -108,7 +46,7 @@ int rebuild::process(std::vector<PROCIMGINFO>& in, std::vector<PROCIMGINFO>& out
{
for(auto& v: in)
{
ret = do_rebuild(v, out);
do_rebuild(&v.info, v.img.ptr(), out);
}
}
else
@ -121,3 +59,69 @@ int rebuild::process(std::vector<PROCIMGINFO>& in, std::vector<PROCIMGINFO>& out
return ret;
}
void rebuild::do_rebuild(LPPACKIMAGE info, uint8_t* stream, std::vector<PROCIMGINFO>& out)
{
int secl = cis::get_sector_pixels(0, info->resolution_x, true),
linel = cis::get_line_stream_length(info->resolution_x, false),
size = info->height * info->width / 2;
PROCIMGINFO o;
chronograph watch;
o.info = *info;
if(info->pos.paper_side != PAPER_SIDE_BACK &&
info->pos.paper_side != PAPER_SIDE_FRONT)
linel *= 2;
o.info.prc_stage = get_position();
o.info.pos.paper_side = PAPER_SIDE_FRONT;
out.push_back(o);
o.info.pos.paper_side = PAPER_SIDE_BACK;
out.push_back(o);
if(info->width == linel) // gray
{
}
else // color
{
uint8_t *srcd = stream + info->width * (info->height - 1), // line reverse
*dstf = nullptr, // (uint8_t*)malloc(size),
*dstb = nullptr, // (uint8_t*)malloc(size),
*df = dstf, *db = dstb,
soff[] = {11, 10, 9, 2, 1, 0};
out[1].info.channels = out[0].info.channels = 3;
out[0].info.width /= out[0].info.channels * 2;
out[1].info.width /= out[1].info.channels * 2;
out[0].img.create(out[0].info.height, out[0].info.width, CV_8UC3);
out[1].img.create(out[1].info.height, out[1].info.width, CV_8UC3);
df = dstf = out[0].img.ptr();
db = dstb = out[1].img.ptr();
o.info.width = out[0].info.width;
o.info.channels = out[0].info.channels;
printf("rebuild (%d * %d * 8) to (%d * %d * 24), front = %p, back = %p, size = %u ...\n", info->width, info->height
, o.info.width, o.info.height, dstf, dstb, size);
for(int h = 0; h < info->height; ++h)
{
for(int w = 0; w < o.info.width; ++w)
{
int s = w / secl;
*df++ = srcd[(soff[s] + 0) * secl + (w % secl)];
*df++ = srcd[(soff[s] + 6) * secl + (w % secl)];
*df++ = srcd[(soff[s] + 3) * secl + (w % secl)];
*db++ = srcd[info->width / 2 + (soff[s] + 6) * secl + (w % secl)];
*db++ = srcd[info->width / 2 + (soff[s] + 0) * secl + (w % secl)];
*db++ = srcd[info->width / 2 + (soff[s] + 3) * secl + (w % secl)];
}
srcd -= info->width;
}
}
size = watch.elapse_ms();
out[0].info.prc_time = size;
out[1].info.prc_time = size;
}

View File

@ -9,8 +9,6 @@ class rebuild : public image_processor
{
bool rebuild_ = true;
int do_rebuild(PROCIMGINFO& in, std::vector<PROCIMGINFO>& out);
public:
rebuild();
@ -23,4 +21,7 @@ public:
public:
virtual int process(std::vector<PROCIMGINFO>& in, std::vector<PROCIMGINFO>& out) override;
public:
void do_rebuild(LPPACKIMAGE info, uint8_t* stream, std::vector<PROCIMGINFO>& out);
};

View File

@ -38,6 +38,7 @@ imgproc_mgr::imgproc_mgr(std::function<void(data_source_ptr)> sender
else
opts_ = new device_option(true);
load_processor(nullptr);
rebuild_.reset(new rebuild());
auto thrd = [&](void) -> void
{
@ -108,63 +109,77 @@ void imgproc_mgr::process(RAWIMG* img)
if(img->img)
{
std::vector<PROCIMGINFO> in, out;
PROCIMGINFO ele;
chronograph watch;
ele.ext_info = "";
ele.info = img->info;
ele.img = cv::Mat(ele.info.height, ele.info.width, CV_8UC1, (void*)img->data->ptr(), img->data->get_rest());
// ele.img.create(img->info.height, img->info.width, CV_8UC1);
// memcpy(ele.img.ptr(), img->data->ptr(), img->data->get_rest());
img->data->release();
in.push_back(ele);
rebuild_->do_rebuild(&img->info, img->data->ptr(), in);
utils::to_log(LOG_LEVEL_ALL, "Rebuild paper %d spend %llu milliseconds.\n", img->info.pos.paper_ind, watch.elapse_ms());
if(dump_img_)
{
send_image(&img->info, img->data->ptr(), img->info.width * img->info.height);
img->data->release();
for(auto& v: processors_)
{
send_image(in, false);
v->process(in, out);
in = std::move(out);
if(v->is_enable())
{
v->process(in, out);
in = std::move(out);
}
}
}
else
{
img->data->release();
for(auto& v: processors_)
{
v->process(in, out);
in = std::move(out);
if(v->is_enable())
{
v->process(in, out);
in = std::move(out);
}
}
}
send_image(in, true);
}
else
{
data_source_ptr ptr = imgproc_mgr::scan_finished_packet(scan_id_, img->info.reserve);
data_source_ptr ptr = imgproc_mgr::scan_finished_packet(scan_id_, img->info.data_size);
uint32_t wait = 0, que = 0;
ptr->set_session_id(session_id_);
while((que = add_busy_worker(0)) > 1)
{
if(wait++ == 0)
utils::to_log(LOG_LEVEL_DEBUG, "Received scan completed event while processing %u paper(s), wait ...\n", que - 1);
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
img_sender_(ptr);
ptr->release();
}
}
void imgproc_mgr::send_image(LPPACKIMAGE head, uint8_t* data, size_t size, void* info, size_t info_l)
{
dyn_mem_ptr mem(dyn_mem::memory(size));
image_packet_ptr ptr = nullptr;
printf("send image %d(%d-0x%04x) with size %u:\n", head->pos.paper_ind, head->pos.paper_side, head->prc_stage, size);
mem->put(data, size);
ptr = imgproc_mgr::image_sent_packet(head, mem, scan_id_, info, info_l);
mem->release();
ptr->set_session_id(session_id_);
img_sender_(ptr);
ptr->release();
}
void imgproc_mgr::send_image(std::vector<PROCIMGINFO>& imgs, bool clear_after_send)
{
printf("send image %d - %d:\n", imgs[0].info.pos.paper_ind, imgs[0].info.prc_stage);
for(auto& v: imgs)
{
uint32_t size = v.img.total() * v.img.channels();
dyn_mem_ptr mem(dyn_mem::memory(size));
// printf(" %d - image bits: %p + %u, src = %p([0] = %02x)\n", v.info.pos.paper_side, mem->ptr(), size, v.img.data, v.img.data[0]);
mem->put(v.img.data, size);
// if(clear_after_send)
// v.img.deallocate();
// printf(" consturct image packet ...\n");
image_packet_ptr ptr = imgproc_mgr::image_sent_packet(&v.info, mem, scan_id_, &v.ext_info[0], v.ext_info.length());
ptr->set_session_id(session_id_);
// printf(" sending image packet: %p + %u\n", ptr->ptr(), ptr->get_rest());
img_sender_(ptr);
ptr->release();
mem->release();
send_image(&v.info, v.img.ptr(), v.img.total() * v.img.channels()
, v.ext_info.empty() ? nullptr : &v.ext_info[0], v.ext_info.length());
if(clear_after_send)
v.img.release();
}
}
@ -191,7 +206,7 @@ int imgproc_mgr::load_processor(const char* path)
processors_.push_back(obj); \
}
ADD_IMG_PROCESSOR(rebuild);
// ADD_IMG_PROCESSOR(rebuild);
std::sort(processors_.begin(), processors_.end(), &imgproc_mgr::sort_processor_by_pos);
@ -217,7 +232,7 @@ int imgproc_mgr::process(LPPACKIMAGE info, dyn_mem_ptr data, bool img)
if(img)
ri.info = *info;
else
ri.info.reserve = (uint32_t)(long)info;
ri.info.data_size = (uint32_t)(long)info;
ri.img = img;
prc_que_.save(ri, true);

View File

@ -16,6 +16,8 @@
typedef std::shared_ptr<std::vector<char>> dcptr;
class device_option;
class rebuild;
class imgproc_mgr : public sane_opt_provider
{
typedef struct _raw_img
@ -25,6 +27,7 @@ class imgproc_mgr : public sane_opt_provider
bool img;
}RAWIMG;
refer_guard<rebuild> rebuild_;
volatile bool run_ = true;
bool dump_img_ = false;
uint32_t scan_id_ = 0;
@ -46,6 +49,7 @@ class imgproc_mgr : public sane_opt_provider
uint32_t add_busy_worker(int inc = 1);
void thread_worker(void);
void process(RAWIMG* img);
void send_image(LPPACKIMAGE head, uint8_t* data, size_t size, void* info = nullptr, size_t info_l = 0);
void send_image(std::vector<PROCIMGINFO>& imgs, bool clear_after_send);
public:

View File

@ -64,6 +64,12 @@ async_scanner::async_scanner() : usb_(nullptr), cfg_mgr_(nullptr), scan_id_(0)
auto sender = [this](data_source_ptr img) -> void
{
if(img->ptr() && ((LPPACK_BASE)img->ptr())->cmd == PACK_CMD_SCAN_FINISHED_ROGER)
{
cis_->close();
utils::print_memory_usage("Memory usage when finished scanning", false);
}
usb_->write_bulk(img);
};
@ -456,8 +462,9 @@ dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, p
return nullptr;
}
uint32_t base_head_size = sizeof(PACK_BASE);
dyn_mem_ptr reply = dyn_mem::memory(base_head_size);
uint32_t base_head_size = sizeof(PACK_BASE);
dyn_mem_ptr reply = nullptr;
std::string config("");
img_cnt_ = 0;
scan_id_ = pack->pack_id;
@ -467,26 +474,14 @@ dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, p
auto receiver = [this](dyn_mem_ptr data, bool img, LPPACKIMAGE lpinfo) -> void
{
img_prcr_->process(lpinfo, data, img);
// if(img)
// {
// FILE* dst = fopen(("/tmp/scan_" + std::to_string(lpinfo->pos.paper_ind) + ".bmp").c_str(), "wb");
// if(dst)
// {
// std::string bih(utils::bitmap_info_header(lpinfo->width, lpinfo->height, lpinfo->bpp, lpinfo->resolution_x, lpinfo->resolution_y)),
// bfh(utils::bitmap_file_header((BITMAPINFOHEADER*)&bih[0]));
// fwrite(bfh.c_str(), 1, bfh.length(), dst);
// fwrite(bih.c_str(), 1, bih.length(), dst);
// fwrite(data->ptr(), 1, ((BITMAPINFOHEADER*)&bih[0])->biSizeImage, dst);
// fclose(dst);
// }
// data->release();
// }
};
utils::print_memory_usage("Memory usage before scanning", false);
*used = base_head_size;
reply->set_len(base_head_size);
img_prcr_->start_new_turn(scan_id_, session);
scan_err_ = cis_->open(receiver);
scan_err_ = cis_->open(receiver, &config);
reply = dyn_mem::memory(base_head_size + config.length() + 2);
reply->set_len(base_head_size + config.length() + 2);
if(scan_err_ == 0)
scan_err_ = cis_->start_scan();
if(scan_err_)
@ -494,6 +489,8 @@ dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, p
cis_->stop_scan();
}
BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, scan_err_);
((LPPACK_BASE)reply->ptr())->payload_len = config.length() + 2;
strcpy(((LPPACK_BASE)reply->ptr())->payload, config.c_str());
*used |= INT32_MAX + 1;
return reply;

View File

@ -30,7 +30,16 @@ static void sigHandler(int sig)
_exit(0);
}
static std::string get_command(void)
{
std::string cmd("");
char in[2] = {0};
while((in[0] = getchar()) != 0x0a)
cmd += in;
return std::move(cmd);
}
int main()
{
@ -45,25 +54,20 @@ int main()
{
exit(-1);
}
/* kill pid / killall name */
signal(SIGKILL, sigHandler);
scanner = new async_scanner();
int err = scanner->last_error();
if(err == 0)
while(err == 0)
{
while(1)
{
if(getchar() == 'e')
{
if(getchar() == 'x')
{
if(getchar() == 'i')
{
if(getchar() == 't')
break;
}
}
}
}
std::string cmd(get_command());
if(cmd == "exit")
break;
if(cmd == "mem")
utils::print_memory_usage(" Memory usage", false);
}
async_scanner* tmp = scanner;

View File

@ -384,6 +384,7 @@ dyn_mem::dyn_mem(void* buf, size_t size)
dyn_mem::~dyn_mem()
{
notify_progress(space_, len_, 0);
if (buf_)
{
free(buf_);

View File

@ -301,10 +301,11 @@ typedef struct _pack_img
uint32_t bpp : 6; // bits per pixel. (image-collector set)
uint32_t bppc : 6; // bits per pixel in this channel, equal to 'bpp' if pos.channel_ind == 0x0f. (image-collector set)
uint32_t compression : 6; // image data compression, see 'img_compression'. (image-collector set)
uint32_t reserve : 2; // unused now
uint32_t reserved : 2; //
uint32_t prc_stage : 14; // position of image processor, 0 is raw from CIS directly
uint32_t prc_time : 18; // spent time in milliseconds of image-process prc_stage
uint32_t info_size; // image information size in bytes, information part is used for quality of JPEG, pallete of BMP .... (image-collector set)
uint64_t prc_stage : 16; // position of image processor, 0 is raw from CIS directly
uint64_t data_size : 48; // image data size in 'data' with bytes. (image-collector set)
uint32_t data_size; // image data size in 'data' with bytes. (image-collector set)
// char data[0]; // two parts: image info (info_size) + image data (data_size)
STRUCT_CONSTRUCTOR(_pack_img)

View File

@ -1087,6 +1087,67 @@ namespace utils
return err;
}
int get_memory_usage(uint64_t* peak, uint64_t* now, uint64_t* phymem, uint32_t pid)
{
if(pid == -1)
pid = GetCurrentProcessId();
#if OW_WIN
#else
char cmd[40] = {0};
std::string result(""), tag("");
size_t pos = 0;
sprintf(cmd, "cat /proc/%u/status | grep Vm", pid);
result = get_command_result(cmd);
if(result.empty())
return -1;
if(peak)
{
tag = "VmPeak";
pos = result.find(tag);
if(pos != std::string::npos)
sscanf(result.c_str() + pos, (tag + ": %llu kB").c_str(), peak);
else
*peak = 0;
*peak *= 1024;
}
if(now)
{
tag = "VmSize";
pos = result.find(tag);
if(pos != std::string::npos)
sscanf(result.c_str() + pos, (tag + ": %llu kB").c_str(), now);
else
*now = 0;
*now *= 1024;
}
if(phymem)
{
tag = "VmRSS";
pos = result.find(tag);
if(pos != std::string::npos)
sscanf(result.c_str() + pos, (tag + ": %llu kB").c_str(), phymem);
else
*phymem = 0;
*phymem *= 1024;
}
#endif
return 0;
}
void print_memory_usage(const char* tips, bool to_log_file)
{
uint64_t peak = 0, now = 0, phy = 0;
get_memory_usage(&peak, &now, &phy);
if(to_log_file)
to_log(LOG_LEVEL_DEBUG, "%s: Peak = %llu, Now = %llu, Phy = %llu\n", tips, peak, now, phy);
else
printf("%s: Peak = %llu, Now = %llu, Phy = %llu\n", tips, peak, now, phy);
}
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block)
{
int ret = 0;

View File

@ -64,6 +64,8 @@ namespace utils
int move_file(const char* from, const char* to);
int make_file_size(const char* file, uint64_t size); // truncate or extend file size to 'size', create if not exist
int get_memory_usage(uint64_t* peak, uint64_t* now, uint64_t* phymem, uint32_t pid = -1);
void print_memory_usage(const char* tips, bool to_log_file);
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block);
unsigned int get_page_size(unsigned int* map_unit = nullptr);
@ -220,6 +222,40 @@ public:
virtual int32_t release(void);
};
template<class T>
class refer_guard
{
T *obj_ = nullptr;
void clear(void)
{
if(obj_)
obj_->release();
obj_ = nullptr;
}
public:
refer_guard()
{}
refer_guard(T* obj) : obj_(obj)
{}
~refer_guard()
{
clear();
}
public:
void reset(T* obj)
{
clear();
obj_ = obj;
}
T* operator->(void)
{
return obj_;
}
};
// time utility
class chronograph
{

View File

@ -82,6 +82,9 @@ enum scanner_err
SCANNER_ERR_DEVICE_NOT_READY, // 设备未准备好(执行某操作的前置条件未准备好)
SCANNER_ERR_DEVICE_GET_STATUS_FAILED, // 获取电机板状态失败
SCANNER_ERR_DEVICE_FEEDER_POS, // 送纸器到位信号未触发
SCANNER_ERR_DEVICE_CIS_OUT_OF_MEM, // CIS缓冲区被耗尽
SCANNER_ERR_DEVICE_CIS_STREAM, // 获取CIS图像数据失败
SCANNER_ERR_DEVICE_HD_001, // 设备硬件访问错误
SCANNER_ERR_DEVICE_HD_002, // 设备硬件访问错误
SCANNER_ERR_DEVICE_HD_003, // 设备硬件访问错误

View File

@ -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=20240119")
add_defines("VER_BUILD=41")
add_defines("VER_DATE=20240123")
add_defines("VER_BUILD=21")
target("conf")
set_kind("phony")