diff --git a/hardware/cis/FpgaComm.cpp b/hardware/cis/FpgaComm.cpp index 2cb5cb4..ffedd63 100644 --- a/hardware/cis/FpgaComm.cpp +++ b/hardware/cis/FpgaComm.cpp @@ -355,11 +355,15 @@ void FpgaComm::setDelayTime(int value) { WR_Reg(DelayTime); } -bool FpgaComm::update() +bool FpgaComm::update(std::vector* data) { bool good = true; + std::vector 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"); diff --git a/hardware/cis/FpgaComm.h b/hardware/cis/FpgaComm.h index 12defed..2752309 100644 --- a/hardware/cis/FpgaComm.h +++ b/hardware/cis/FpgaComm.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #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* data = nullptr); void enableJamCheck(bool b); void resetADC(); virtual bool write(unsigned int addr, unsigned int val); diff --git a/hardware/hardware.cpp b/hardware/hardware.cpp index f36db3f..30ebd30 100644 --- a/hardware/hardware.cpp +++ b/hardware/hardware.cpp @@ -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 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 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) +int scanner_hw::open(std::function image_handler, std::string* cfgjson) { std::string tips(""); + refer_guard cfg(new gb_json()); this->close(); int fh = 16380; @@ -630,6 +643,16 @@ int scanner_hw::open(std::function 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) 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) 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) // for(int i = 0; i < _countof(vals); ++i) // img_controller_->write(i, vals[i]); // } - img_controller_->update(); + + std::vector regs; + img_controller_->update(®s); + 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; } diff --git a/hardware/hardware.h b/hardware/hardware.h index 3a33135..03ada79 100644 --- a/hardware/hardware.h +++ b/hardware/hardware.h @@ -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> 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); + int open(std::function image_handler, std::string* cfgjson = nullptr); int start_scan(void); int stop_scan(void); int close(bool from_worker = false); diff --git a/hardware/motor/motorboard.h b/hardware/motor/motorboard.h index 5874960..1157aff 100644 --- a/hardware/motor/motorboard.h +++ b/hardware/motor/motorboard.h @@ -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 { diff --git a/imgproc/algs/rebuild.cpp b/imgproc/algs/rebuild.cpp index 052cbfb..25f5ccc 100644 --- a/imgproc/algs/rebuild.cpp +++ b/imgproc/algs/rebuild.cpp @@ -22,68 +22,6 @@ rebuild::rebuild() : image_processor("rebuild") rebuild::~rebuild() {} -int rebuild::do_rebuild(PROCIMGINFO& in, std::vector& 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& in, std::vector& 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& in, std::vector& out return ret; } +void rebuild::do_rebuild(LPPACKIMAGE info, uint8_t* stream, std::vector& 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; +} \ No newline at end of file diff --git a/imgproc/algs/rebuild.h b/imgproc/algs/rebuild.h index 76533c4..23c0107 100644 --- a/imgproc/algs/rebuild.h +++ b/imgproc/algs/rebuild.h @@ -9,8 +9,6 @@ class rebuild : public image_processor { bool rebuild_ = true; - int do_rebuild(PROCIMGINFO& in, std::vector& out); - public: rebuild(); @@ -23,4 +21,7 @@ public: public: virtual int process(std::vector& in, std::vector& out) override; + +public: + void do_rebuild(LPPACKIMAGE info, uint8_t* stream, std::vector& out); }; diff --git a/imgproc/imgprc_mgr.cpp b/imgproc/imgprc_mgr.cpp index d646f55..5d0dd5c 100644 --- a/imgproc/imgprc_mgr.cpp +++ b/imgproc/imgprc_mgr.cpp @@ -38,6 +38,7 @@ imgproc_mgr::imgproc_mgr(std::function 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 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& 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); diff --git a/imgproc/imgprc_mgr.h b/imgproc/imgprc_mgr.h index 6daaea1..3945511 100644 --- a/imgproc/imgprc_mgr.h +++ b/imgproc/imgprc_mgr.h @@ -16,6 +16,8 @@ typedef std::shared_ptr> 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_; 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& imgs, bool clear_after_send); public: diff --git a/scanner/async_scanner.cpp b/scanner/async_scanner.cpp index 6bc5dfe..52750ce 100644 --- a/scanner/async_scanner.cpp +++ b/scanner/async_scanner.cpp @@ -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; diff --git a/scanner/main.cpp b/scanner/main.cpp index 4fcc146..c9fcc04 100644 --- a/scanner/main.cpp +++ b/scanner/main.cpp @@ -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; diff --git a/sdk/base/data.cpp b/sdk/base/data.cpp index 470b989..371fdf4 100644 --- a/sdk/base/data.cpp +++ b/sdk/base/data.cpp @@ -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_); diff --git a/sdk/base/packet.h b/sdk/base/packet.h index 57a2c51..af75f32 100644 --- a/sdk/base/packet.h +++ b/sdk/base/packet.h @@ -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) diff --git a/sdk/base/utils.cpp b/sdk/base/utils.cpp index 229bfd1..aa5dd36 100644 --- a/sdk/base/utils.cpp +++ b/sdk/base/utils.cpp @@ -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; diff --git a/sdk/base/utils.h b/sdk/base/utils.h index e359fc2..a59807b 100644 --- a/sdk/base/utils.h +++ b/sdk/base/utils.h @@ -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 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 { diff --git a/sdk/huagao/hgscanner_error.h b/sdk/huagao/hgscanner_error.h index e1f58bc..0c733b5 100644 --- a/sdk/huagao/hgscanner_error.h +++ b/sdk/huagao/hgscanner_error.h @@ -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, // 设备硬件访问错误 diff --git a/xmake.lua b/xmake.lua index dafa75f..969993a 100644 --- a/xmake.lua +++ b/xmake.lua @@ -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")