zynq_7010/zynq_7010_code/main.cpp

799 lines
20 KiB
C++

#include <cstdio>
#include <iostream>
#include <fstream>
#include "DevUtil.h"
#include "Motor.h"
#include <thread>
#include <string>
#include "FsmState.h"
#include "Scanner.h"
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/file.h>
#include "HGUsb.h"
#include <memory.h>
#include "UsbScanner.h"
#include "scanservices_utils.h"
#include <turbojpeg.h>
#include "JsonConfig.h"
#include <syslog.h>
#include "utilsfunc.h"
#include "correct_ultis.h"
#include <errno.h>
#include "MotorConfig.h"
#include <iomanip>
#include "usbdevice.h"
using json = nlohmann::json;
using namespace std;
shared_ptr<UsbScanner> m_scanner;
ofstream updatePkg;
static unsigned int total_length = 0;
extern int errno;
#define MY_PID_FILE "/tmp/scanservice_pid"
#define BUF_LEN_FOR_PID 64
#define WAITCONNECTMAXTIME 50
bool b_runloop = true;
static int write_pid_into_fd(int fd, pid_t pid)
{
int ret = -1;
char buf[BUF_LEN_FOR_PID] = {0};
/* Move cursor to the start of file. */
lseek(fd, 0, SEEK_SET);
sprintf(buf, "%d", pid);
ret = write(fd, buf, strlen(buf));
if (ret <= 0)
{ /* Write fail or write 0 byte */
if (ret == -1)
perror("Write " MY_PID_FILE " fail\n");
ret = -1;
}
else
{
LOG("Create " MY_PID_FILE " ok, pid=%d\n", pid);
ret = 0;
}
return ret;
}
static int create_pid_file(pid_t pid)
{
int fd, ret;
char buf[BUF_LEN_FOR_PID] = {0};
fd = open(MY_PID_FILE, O_WRONLY | O_CREAT | O_EXCL, 0666); /* rw-rw-rw- */
if (fd == -1)
{
perror("Create " MY_PID_FILE " fail\n");
return -1;
}
ret = flock(fd, LOCK_EX);
if (ret == -1)
{
perror("flock " MY_PID_FILE " fail\n");
close(fd);
return -1;
}
ret = write_pid_into_fd(fd, pid);
flock(fd, LOCK_UN);
close(fd);
return ret;
}
static int check_pid_file(int fd, pid_t pid)
{
int ret = -1;
pid_t old_pid;
char buf[BUF_LEN_FOR_PID] = {0};
ret = flock(fd, LOCK_EX);
if (ret == -1)
{
perror("flock " MY_PID_FILE " fail\n");
return -1;
}
ret = read(fd, buf, sizeof(buf) - 1);
if (ret < 0)
{ /* read error */
perror("read from " MY_PID_FILE " fail\n");
ret = -1;
}
else if (ret > 0)
{ /* read ok */
old_pid = atol(buf);
/* Check if old_pid is running */
ret = kill(old_pid, 0);
if (ret < 0)
{
if (errno == ESRCH)
{ /* old_pid is not running. */
ret = write_pid_into_fd(fd, pid);
}
else
{
perror("send signal fail\n");
ret = -1;
}
}
else
{ /* running */
LOG("Program already exists, pid=%d\n", old_pid);
ret = -1;
}
}
else if (ret == 0)
{ /* read 0 byte from file */
ret = write_pid_into_fd(fd, pid);
}
flock(fd, LOCK_UN);
return ret;
}
static int init_pid_file()
{
pid_t pid;
int fd, ret;
pid = getpid();
fd = open(MY_PID_FILE, O_RDWR);
if (fd == -1)
{ /* open file fail */
if (errno == ENOENT)
{ /* No such file. Create one for this program. */
ret = create_pid_file(pid);
}
else
{
perror("open " MY_PID_FILE " fail\n");
ret = -1;
}
}
else
{ /* pid file already exists */
ret = check_pid_file(fd, pid);
close(fd);
}
return ret;
}
static void sigHandler(int sig)
{
if (sig == SIGINT || sig == SIGTERM)
remove(MY_PID_FILE);
_exit(0);
}
int menu()
{
int choice;
cout << " **** Menu **** " << endl
<< endl;
cout << "(1) cap regs list." << endl;
cout << "(2) test write read regs" << endl;
cout << "(0) Quit. " << endl
<< endl;
cout << ": ";
cin >> choice;
return choice;
}
void initscanner()
{
m_scanner.reset(new UsbScanner());
if (!m_scanner.get())
LOG("init m_scanner failed\n");
}
int main(int argc, char *argv[])
{
if (-1 == init_pid_file())
{
exit(-1);
}
/* Ctrl + C */
if (signal(SIGINT, sigHandler) == SIG_ERR)
{
exit(-1);
}
/* kill pid / killall name */
if (signal(SIGTERM, sigHandler) == SIG_ERR)
{
exit(-1);
}
creat_sleep_fifo();
initscanner();
start_enter_lowpwoer();
if (argc == 2)
{
int t_arg1 = atoi(argv[1]);
if (t_arg1 == 236)
{
m_scanner->CreatCorrectData(0);
while (m_scanner->GetEvent().code != (int)HG_ScannerStatus::AUTO_FLAT_FINISHED)
{
std::this_thread::sleep_for(chrono::milliseconds(2));
}
}
}
while (b_runloop)
{
if (!m_scanner->is_connect())
{
printf("USB DISCONNECT DISCONNECT DISCONNECT DISCONNECT DISCONNECT DISCONNECT DISCONNECT\n");
b_runloop = false;
m_scanner->StopScan();
stop_countdown();
return 0;
}
USBCB usbcb = {0};
m_scanner->read_bulk(&usbcb, sizeof(usbcb));
if (usbcb.Command == 0)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
continue;
}
switch ((USBCommand)usbcb.Command)
{
case USBCommand::GET_DSP_STATUS:
{
USBCB sts = {1, 0, 0};
if (m_scanner->IsScanning()) //采集图像线程工作中
{
if (m_scanner->GetImagequeueEmpty())
{
auto evt = m_scanner->GetEventFront();
if (evt.code != (int)HG_ScannerStatus::NORMAL && evt.code != (int)HG_ScannerStatus::STOP_SCAN)
sts.Data = m_scanner->GetEvent().code; // 确保第一张扫描之前所发生的异常事件能够被通知
}
else
{
int evt = m_scanner->GetEventFront().code;
if (evt != (int)HG_ScannerStatus::NORMAL && evt != (int)HG_ScannerStatus::STOP_SCAN)
sts.Data = m_scanner->GetEvent().code; // 扫描中途的事件能够被通知
else
{
HG_JpegCompressInfo info = m_scanner->GetFrontImage();
sts.Data = (int)HG_ScannerStatus::HAVE_IMAGE;
sts.Length = info.DataLength;
}
}
}
else
{
if (!m_scanner->GetImagequeueEmpty())
{
HG_JpegCompressInfo info = m_scanner->GetFrontImage();
sts.Data = (int)HG_ScannerStatus::HAVE_IMAGE;
sts.Length = info.DataLength;
}
else
{
auto data = m_scanner->GetEvent();
if (data.code == (int)(HG_ScannerStatus::STOP_SCAN))
{
m_scanner->close_v4l2();
}
sts.Data = data.code;
if (data.code == (int)HG_ScannerStatus::AUTO_FLATTING || data.code == (int)HG_ScannerStatus::AUTO_FLAT_FINISHED)
{
sts.Length = data.msg.length();
m_scanner->write_bulk(&sts, sizeof(sts));
auto msg = data.msg;
m_scanner->write_bulk(&msg[0], msg.length());
break;
}
}
}
m_scanner->write_bulk(&sts, sizeof(sts));
}
break;
case USBCommand::GET_IMAGE:
{
HG_JpegCompressInfo info = m_scanner->GetImage();
if (info.pJpegData != nullptr && info.DataLength != 0 || info.error_code)
{
int tt = m_scanner->write_bulk((void *)&info, sizeof(int) * 8);
int index = 0;
int total = info.DataLength;
while (total > 0)
{
int dstlength = 1024 * 1024;
if (total <= dstlength)
{
dstlength = total;
total = 0; // jpeg图像小于1MB 则一次传输
}
else // 压缩大于1MB的图像 分包传输
total -= dstlength;
int tt = m_scanner->write_bulk(info.pJpegData + index, dstlength);
if (tt <= -1)
{
LOG("FAIL GET_IMAGE write bulk data error\n");
break;
}
else
index += tt;
}
}
}
break;
case USBCommand::START_COMMAND:
{
LOG("start scan scancount = %d\n", usbcb.Data);
m_scanner->StartScan(usbcb.Data);
}
break;
case USBCommand::STOP:
m_scanner->StopScan();
break;
case USBCommand::GET_FW_VERSION:
{
m_scanner->write_bulk((void *)m_scanner->GetFWVersion().c_str(), m_scanner->GetFWVersion().length());
}
break;
case USBCommand::CONFIGURED_DATA:
{
m_scanner->ClearErrorEvents();
m_scanner->ClearImages();
HG_ScanConfiguration config;
config.value = usbcb.Data;
m_scanner->ConfigScanParam(config);
std::string loginfo = "config scanner config data = " + to_string(usbcb.Data) + "\n";
LOG("CONFIGURED_DATA data = %d \n", config.value);
}
break;
case USBCommand::SEND_FW: // never support
break;
case USBCommand::GET_PAPERFEEDER_STATUS:
{
auto feed = m_scanner->FeederLoaded();
USBCB statesfeed = {(int)USBCommand::GET_PAPERFEEDER_STATUS, (feed ? 1 : 0), 0};
// USBCB statesfeed = {(int)USBCommand::GET_PAPERFEEDER_STATUS, 1, 0};
m_scanner->write_bulk(&statesfeed, sizeof(statesfeed));
LOG("GET_PAPERFEEDER_STATUS feeded %s\n", feed ? "TRUE" : "FALSE");
}
break;
case USBCommand::INIT_HARDWARE_SYS:
break;
case USBCommand::START_FLAT:
m_scanner->CreatCorrectData(usbcb.Data);
break;
case USBCommand::STOP_FLAT:
break;
case USBCommand::SEND_SERIAL:
if (usbcb.Length == 14) // 长度必须是14
{
LOG("SET SEND_SERIAL \n");
std::vector<unsigned char> str(14);
m_scanner->read_bulk(str.data(), 14);
m_scanner->UpdateScanInfo((int)USBCommand::SEND_SERIAL, str.data());
}
break;
case USBCommand::GET_SERIAL:
{
LOG("usb write bulk serial : %s length :%d \n", m_scanner->GetSerial().c_str(), m_scanner->GetSerial().length());
m_scanner->write_bulk((void *)m_scanner->GetSerial().c_str(), m_scanner->GetSerial().length());
}
break;
case USBCommand::CLEAR_HWERROR:
m_scanner->ClearHWError();
break;
case USBCommand::CLR_ROLLER_NUM:
case USBCommand::CLR_SCAN_NUM:
case USBCommand::SET_SLEEP_TIME:
case USBCommand::SET_SPEED_MODE:
{
m_scanner->UpdateScanInfo(usbcb.Command, &usbcb.Data);
}
break;
case USBCommand::SET_JUST_COF_H:
case USBCommand::SET_JUST_COF_V:
{
if (usbcb.Length == 0)
{
LOG("SET_JUST_COF_V -----------------\n");
auto info = GetScanInfoFromJson();
usbcb.Command == (int)USBCommand::SET_JUST_COF_H ? info.HRatio = usbcb.Data : info.VRatio = usbcb.Data;
SaveScaninfo(info);
}
else
{
auto infoC = GetFpgaparam(usbcb.Length, 1);
auto infoG = GetFpgaparam(usbcb.Length, 0);
if (usbcb.Command == (int)USBCommand::SET_JUST_COF_H)
{
infoC.HRatio = usbcb.Data;
infoG.HRatio = usbcb.Data;
}
else
{
infoC.VRatio = usbcb.Data;
infoG.VRatio = usbcb.Data;
}
SaveFpgaparam(infoC);
SaveFpgaparam(infoG);
}
}
break;
case USBCommand::SEND_COLOR_FLAT:
case USBCommand::SEND_COLORCORRECT_FLAT:
case USBCommand::SEND_GRAY_FLAT:
case USBCommand::SEND_GRAYCORRECT_FLAT:
{
int buffer[30] = {0};
m_scanner->read_bulk(&buffer, sizeof(int) * 30);
m_scanner->SetFlatParam(usbcb.Command, buffer);
}
break;
// case USBCommand::GET_FLAT_DATA:
// {
// LOG("enter GET_FLAT_DATA \n");
// int buffer[128];
// auto params = m_scanner->GetCaptureParams();
// LOG("size of params %d \n", sizeof(params));
// memcpy(buffer, &params, sizeof(params));
// m_scanner->write_bulk(&buffer, sizeof(int) * 128);
// }
// break;
case USBCommand::PRE_UPGRADE:
{
printf("正在准备升级中... \n");
updatePkg.open("/home/root/update.zip", ios::out | ios::binary);
m_scanner->SetLEDStatus(LedStatus::Updating);
total_length = usbcb.Length;
}
break;
case USBCommand::START_UPGRADE:
{
if (!updatePkg.is_open())
{
printf("准备升级文件失败...\r\n");
break;
}
printf("开始进行升级包下载...\r\n");
int total = usbcb.Length,
block = 0,
indx = 0;
char *bufferData = (char *)malloc(total * sizeof(char));
while (total > 0)
{
block = 1024 * 1024;
if (total < block)
block = total;
m_scanner->read_bulk(bufferData + indx, block);
total -= block;
indx += block;
}
updatePkg.write(bufferData, indx);//或者放上面分段写也是一样的,数据量太大的话
USBCB tmpUpdate = {(unsigned int)(USBCommand::START_UPGRADE), 0, 0};
tmpUpdate.Data = updatePkg.bad() ? 10 : 100;
m_scanner->write_bulk(&tmpUpdate, sizeof(tmpUpdate));
if (bufferData)
{
free(bufferData);
}
printf("升级包下载:%s...\r\n",tmpUpdate.Data == 10 ? "失败":"成功");
}
break;
case USBCommand::UPDATE_FINISHED:
{
printf("开始进行升级... \n");
m_scanner->SetLEDStatus(LedStatus::UpdateDone);
updatePkg.close();
system("sh /mnt/flash-disk/upgrade_firmware.sh &");
}
break;
case USBCommand::REBOOT:
{
if (usbcb.Data == 0)
system("reboot");
else
system("reboot loader");
}
break;
case USBCommand::GET_LOG_FILES_INFO:
{
ifstream logzipfiles;
logzipfiles.open("/var/log/syslog", std::ios_base::in | std::ios_base::binary);
if (!logzipfiles.is_open())
{
usbcb.Length = 0;
m_scanner->write_bulk(&usbcb, sizeof(usbcb));
}
else
{
logzipfiles.seekg(0, std::ios::end);
size_t length = logzipfiles.tellg();
logzipfiles.seekg(0, std::ios::beg);
usbcb.Length = length;
m_scanner->write_bulk(&usbcb, sizeof(usbcb));
char *bufferlog = new char[length];
logzipfiles.read(bufferlog, length);
m_scanner->write_bulk(bufferlog, length);
int index = 0;
while (length > 0)
{
int dstlength = 1024 * 1024;
if (length <= dstlength)
{
dstlength = length;
length = 0; // jpeg图像小于1MB 则一次传输
}
else // 压缩大于1MB的图像 分包传输
length -= dstlength;
int tt = m_scanner->write_bulk(bufferlog + index, dstlength);
if (tt == -1)
{
LOG("GET_LOG_FILES_INFO write bulk data error\n");
break;
}
else
index += tt;
}
logzipfiles.close();
delete[] bufferlog;
}
}
break;
case USBCommand::GET_UPDATE_RESULT:
{
int ret = get_devs_status("/mnt/flash-disk/update_status.txt");
printf("获取升级状态:%d\r\n",ret);
usbcb.Data = ret;
if (ret == -1)
{
usbcb.Data = 100;
}
m_scanner->write_bulk(&usbcb, sizeof(usbcb));
if (ret == SCANNER_ERR_UPDATE_OK)
{
printf("升级成功。。。\r\n");
}
//system("reboot");
}
break;
case USBCommand::CLEAR_LOG_FILES:
{
system("echo \"\" > /var/log/syslog");
}
break;
case USBCommand::GET_SCANN_NUM:
case USBCommand::GET_ROLLER_NUM:
case USBCommand::GET_JUST_COF_H:
case USBCommand::GET_JUST_COF_V:
case USBCommand::GET_CUO_ERROR:
case USBCommand::GET_DOU_ERROR:
case USBCommand::GET_JAM_ERROR:
case USBCommand::GET_SLEEP_TIME:
case USBCommand::GET_SPEED_MODE:
{
LOG("SET_JsonConfig ------------- \n");
USBCB tmp = {(int)usbcb.Command, 0, 0};
auto info = GetScanInfoFromJson();
if (usbcb.Command == (int)(USBCommand::GET_SCANN_NUM))
tmp.Data = info.TotalScanned;
else if (usbcb.Command == (int)(USBCommand::GET_ROLLER_NUM))
tmp.Data = info.RollerNum;
else if (usbcb.Command == (int)(USBCommand::GET_JUST_COF_H) || usbcb.Command == (int)(USBCommand::GET_JUST_COF_V))
{
if (usbcb.Length == 0)
tmp.Data = usbcb.Command == (int)(USBCommand::GET_JUST_COF_H) ? info.HRatio : info.VRatio;
else
{
auto camraparm = GetFpgaparam(usbcb.Length, 0);
tmp.Data = usbcb.Command == (int)(USBCommand::GET_JUST_COF_H) ? camraparm.HRatio : camraparm.VRatio;
}
}
else if (usbcb.Command == (int)(USBCommand::GET_CUO_ERROR))
tmp.Data = info.JamInNum;
else if (usbcb.Command == (int)(USBCommand::GET_DOU_ERROR))
tmp.Data = info.DoubleNum;
else if (usbcb.Command == (int)(USBCommand::GET_JAM_ERROR))
tmp.Data = info.JamOutNum;
else if (usbcb.Command == (int)(USBCommand::GET_SLEEP_TIME))
tmp.Data = info.SleepTime;
else if (usbcb.Command == (int)(USBCommand::GET_SPEED_MODE))
tmp.Data = info.SpeedMode;
m_scanner->write_bulk(&tmp, sizeof(tmp));
}
break;
case USBCommand::ACTIVE_SCANNER:
{
int ret = get_devs_status(SLEEP_STATUS_PATH);
printf("休眠状态:%s\r\n",ret == SCANNER_ERR_SLEEP?"设备休眠中...":"设备未休眠...") ;
usbcb.Data = ret == SCANNER_ERR_SLEEP ? 0x100 : 0x10;
m_scanner->write_bulk(&usbcb, sizeof(usbcb));
if (ret == SCANNER_ERR_SLEEP)
{
system("sh /mnt/flash-disk/low_power.sh 0");
}
}
break;
case USBCommand::SET_USB_INFOR_VIDPID:
{
VIDPID t_vidpid = {0};
t_vidpid.Value = (unsigned int)usbcb.Data;
auto info = GetScanInfoFromJson();
info.VID = t_vidpid.VID;
info.PID = t_vidpid.PID;
SaveScaninfo(info);
}
break;
case USBCommand::GET_USB_INFOR_VIDPID:
{
auto info = GetScanInfoFromJson();
VIDPID t_vidpid = {info.VID, info.PID};
t_vidpid.VID = info.VID;
t_vidpid.PID = info.PID;
LOG("GET_USB_INFOR_VIDPID + VID= %04x PID=0x%04x\n", info.VID, info.PID);
usbcb.Data = t_vidpid.Value;
m_scanner->write_bulk(&usbcb, sizeof(usbcb));
}
break;
case USBCommand::GETSYSINFO_LEN:
{
usbcb.Length = m_scanner->GetSysInfo().length();
printf("/usr/local/huago/sysinfo.json length = %d \n", usbcb.Length);
m_scanner->write_bulk(&usbcb, sizeof(usbcb));
}
break;
case USBCommand::GETSYSINFO:
{
auto str = m_scanner->GetSysInfo();
m_scanner->write_bulk(&str[0], str.length());
}
break;
case USBCommand::GETMOTORPARAM:
{
if (usbcb.Length <= 0)
break;
std::string jsonpath;
jsonpath.resize(usbcb.Length);
m_scanner->read_bulk(&jsonpath[0], usbcb.Length);
LOG("get json path = %s \n", jsonpath.c_str());
if (access(jsonpath.c_str(), F_OK) == 0) // 存在
{
ifstream i(jsonpath);
json j;
i >> j;
std::string str_js = j.dump();
USBCB rtinfo = {.Command = (unsigned int)USBCommand::GETMOTORPARMLEN, .Data = 0, .Length = str_js.length()};
m_scanner->write_bulk(&rtinfo, sizeof(rtinfo));
m_scanner->write_bulk(&str_js[0], str_js.length());
}
break;
}
case USBCommand::SETMOTORPARAM:
{
std::string jspath, jscontent;
jspath.resize(usbcb.Data);
jscontent.resize(usbcb.Length);
m_scanner->read_bulk(&jspath[0], usbcb.Data);
LOG("save json path =%s \n", jspath.c_str());
m_scanner->read_bulk(&jscontent[0], usbcb.Length);
// LOG("json content =%s \n", jscontent.c_str());
auto j = json::parse(jscontent);
ofstream ofs(jspath);
ofs << std::setw(4) << j << std::endl;
}
break;
case USBCommand::GET_FLAT_DATA:
{
FLAT_INFO flatinfo ;
flatinfo.value = usbcb.Data;
flatinfo.params.status = 100; ////正常状态
unsigned char *lut_buffer;
if (flatinfo.params.dpi != 0)
{
std::ifstream lut_item;
int dpi = flatinfo.params.dpi == 0x01 ? 200 : (flatinfo.params.dpi == 0x02 ? 300 : 600);
std::string mode = flatinfo.params.colormode ? "clr" : "gray";
std::string is_white_lut = flatinfo.params.is_whiteimage ? "white" : "bw";
std::string lut_path = "/mnt/flash-disk/huago/lut" + std::to_string(dpi) + mode + is_white_lut + ".bmp";
lut_item.open(lut_path, std::ios_base::in | std::ios_base::binary);
if (!lut_item.is_open())
{
flatinfo.params.datalen = 0;
flatinfo.params.status = 1; // 文件打开失败
}
else
{
lut_item.seekg(0, std::ios::end);
size_t length = lut_item.tellg();
lut_item.seekg(0, std::ios::beg);
flatinfo.params.datalen = length;
}
if (flatinfo.params.datalen != 0 && flatinfo.params.status == 100)
{
lut_buffer = new unsigned char[flatinfo.params.datalen];
if (lut_buffer)
lut_item.read((char *)lut_buffer, flatinfo.params.datalen);
else
{
flatinfo.params.status = 2; // OOM 异常
flatinfo.params.datalen = 0;
}
}
}
else
{
flatinfo.params.datalen = 0;
flatinfo.params.status = 3; // 未知dpi
}
usbcb.Data = flatinfo.value;
printf("flatinfo.params.status:%d\r\n" ,flatinfo.params.status);
printf("flatinfo.params.datalen:%d\r\n" ,flatinfo.params.datalen);
printf("flatinfo.value:%d\r\n",flatinfo.value);
m_scanner->write_bulk(&usbcb, sizeof(usbcb));
if (lut_buffer)
{
m_scanner->write_bulk(lut_buffer, flatinfo.params.datalen);
delete[] lut_buffer;
lut_buffer = NULL;
}
}
break;
case USBCommand::DEVICES_7010:
usbcb.Data = 1;
m_scanner->write_bulk(&usbcb, sizeof(usbcb));
break;
default:
usbcb.Data = 56833;
m_scanner->write_bulk(&usbcb, sizeof(usbcb));
break;
}
}
m_scanner->ClearErrorEvents();
m_scanner->ClearImages(); // 清空内存 释放压缩数据 避免内存堆积
m_scanner.reset();
LOG("reset scanner \n");
LOG("reset usb \n");
LOG("scanservice exit \n");
return 0;
}