libctb库是c++实现串口通信的第三方扩展库,该是直接提供源码的,可取https://www.iftools.com/start/index.en.php网站的download页面搜索libctb下载其源码,例如libctb-0.16.tar.gz。
其具体编译查看其解压目录下的build即可实现,在实践发现中在读取数据是,会出现数据被截断的情况,例如:
0102002160指令,读取返回0102,后面 数据被抛弃,经源码调试发现,其读取数据是正确的,但在计算长度时将00作为结束符,造成计算长度异常,现给出修改参考,给同样遇到该问题的读者
打开libctb-0.16\src\win32\serport.cpp文件,修改
int SerialPort::Read(char* buf,size_t len)
{
DWORD read;
int m = m_fifo->items();
while(len) {
if(m_fifo->get(buf) == 1) {
len--;
buf++;
}
else {
break;
}
}
if(!ReadFile(fd,buf,len,&read,&m_ov)) {
// if we use a asynchrone reading, ReadFile gives always
// FALSE
// ERROR_IO_PENDING means ok, other values show an error
if(GetLastError() != ERROR_IO_PENDING) {
// oops..., error in communication
return -1;
}
}
else {
// ok, we have read all wanted bytes
return (int)read + m;
}
return 0;
};
为
int SerialPort::Read(char* buf,size_t len)
{
DWORD read;
int m = m_fifo->items();
while(len) {
if(m_fifo->get(buf) == 1) {
len--;
buf++;
}
else {
break;
}
}
//printf("SerialPort::Read(%d,%d)..1..\n", m, len);
//byte _buf[64] = { 0 };
if(!ReadFile(fd,(LPVOID)buf,len,&read,&m_ov)) {
// if we use a asynchrone reading, ReadFile gives always
// FALSE
// ERROR_IO_PENDING means ok, other values show an error
if(GetLastError() != ERROR_IO_PENDING) {
// oops..., error in communication
//printf("SerialPort::Read error(%d)..2..\n", (int)GetLastError());
return -1;
}
}
else {
//memcpy(buf, _buf, (int)read + m);
//printf("SerialPort::Read(%d,%d,%d,%d)..3..\n", m, len,(int)read,strlen(buf));
// ok, we have read all wanted bytes
return (int)read + m;
}
//继续处置后续字符,防止被丢弃
int size = strlen(buf);
for (int i = size; i < len; i++)
{
if (0X00 != buf[i])
size = i+1;
}
//memcpy(buf, _buf, (int)read + m);
//printf("SerialPort::Read(%d,%d,%d,%d)..4..\n", m, len, (int)read, strlen(buf));
return size;
};
完成修改重新编译libctb的调用库, 在调用其Read函数时,可以再加一层保险,就不会出现本文描述的截断情况
char cache[128] = { 0 };
memset(cache, 0x00, 128);
Ret = Read(cache, 128); // 读应答数据 ascii,结尾字段丢失,明明有数据,却返回长度为0
readlen = (int)strlen(cache);
nrecs = (Ret < readlen ? readlen : Ret);
if (acssiif)
{
memcpy(atres, cache, nrecs);
}
else {
nrecs = PFunc::bytes2string((const unsigned char*)cache, (char*)atres, nrecs);//ascii to hex
}