私は少し初心者ですが、ttyACM0 を使用してデバイスから 64 バイトの AES 暗号化データを読み取るレガシー アプリを持っています。128 バイトを読み取る必要があります。シンプルに聞こえました。バッファなどのサイズを増やします。しかし、何を試しても、まだ64バイトしか読み取れません。その後、ハングするだけです。ターミナルと cdc-acm ドライバーを使用して、Windows での通信を確認しました。デバイスはフロー制御を使用しません。コードは独自のものであるためアップロードできませんが、以下にいくつかのスニペットを示します。
初期化: CACS_RefID::Initialise() { int iRet = 1; struct termios dev_settings;
if(( m_fdRefdev = open("/dev/ttyACM0", O_RDWR))<0)
{
g_dbg->debug("CACS_RefID::Failed to open device\n");
return 0;
}
g_dbg->debug("CACS_RefID::Initialse completed\n");
// Configure the port
tcgetattr(m_fdRefdev, &dev_settings);
cfmakeraw(&dev_settings);
//*tcflush
//tcflush(m_fdRefdev, TCIOFLUSH);
tcsetattr(m_fdRefdev, TCSANOW, &dev_settings);
return iRet;
}
実装:
int CACS_RefID::Readport_Refid(int ilen, char* buf)
{
int ierr=0, iret = 0, ictr=0;
fd_set fdrefid;
struct timeval porttime_refrd;
FD_ZERO(&fdrefid);
FD_SET(m_fdRefdev,&fdrefid);
porttime_refrd.tv_sec = 1;
porttime_refrd.tv_usec = 0; //10 Seconds wait time for read port
do
{
iret = select(m_fdRefdev + 1, &fdrefid, NULL, NULL, &porttime_refrd);
switch(iret)
{
case READ_TIMEOUT:
g_dbg->debug("Refid portread: Select timeout:readlen=%d \n",ilen);
ierr = -1;
break;
case READ_ERROR:
g_dbg->debug("Refid portread: Select error:readlen=%d \n",ilen);
ierr = -1;
break;
default:
iret = read(m_fdRefdev, buf, ilen);
g_dbg->debug("Refid portread: Read len(%d):%d\n",ilen,iret);
break;
}
}while((ierr == 0) && (iret<ilen) );
//Flush terminal content at Input and Output after every read completion
// tcflush(m_fdRefdev, TCIOFLUSH);
return ierr;
}
実装を実行する前に毎回初期化すると、128 バイトになりますが、データは 64 バイト後に破損します。それに取り組む前でさえ、私はたくさんの READ_ERROR を受け取ります。元の作成者は、デバイスが select() でブロックされることを期待していたようですが、そうではありません。
システムの ttyACM0 バッファ サイズに何らかの制限がありますか? ttyACM ドライバーでボーレートは重要ですか? read() は、すべてのバイトが読み取られた後に読み取りを停止しますか (最初の 64 バイトが使用可能で、次に空になり、さらにデータが増えると考えています)?
マニュアルページに注いでいますが、私は困惑しています。どんな助けでも大歓迎です。
ここに私の最新のものがあります:
int CACS_RefID::Get_GasTest_Result(int ilen)
{
int ierr=0, iret = 0, ictr=0, iread=0;
fd_set fdrefid;
struct timeval porttime_refrd;
porttime_refrd.tv_sec = 5;
porttime_refrd.tv_usec = 0; //10 Seconds wait time for read port
if (Get_GasTest_FirstPass == 0)
{
g_dbg->debug("GasTest_Result_firstPass\n");
memset(strresult, 0, sizeof(strresult)); //SLY clear out result buffer
iread=0;
Get_GasTest_FirstPass = 1;
}
do
{
iread = strlen(strresult);
FD_ZERO(&fdrefid);
FD_SET(m_fdRefdev,&fdrefid);
iret = select(m_fdRefdev + 1, &fdrefid, NULL, NULL, &porttime_refrd);
switch(iret)
{
case READ_TIMEOUT: //0
g_dbg->debug("Get_GasTest_Result: Select timeout\n");
ierr = -1;
break;
case READ_ERROR: //-1
g_dbg->debug("Get_GasTest_Result: Select error=%d %s \n", errno,strerror(errno)) ;
ierr = -1;
break;
}
iret = read(m_fdRefdev, (&strresult[0] + iread), (ilen-iread));
g_dbg->debug("Get_GasTest_Result: ilen=%d,iret=%d,iread=%d \n",ilen,iret,iread);
}while((ierr == 0) && (iread<ilen) );
return ierr;
注:選択エラーに関係なくデータを読み取っていますが、まだ64バイトしか取得していません。デバイス製造元に連絡しました。何か変なことが起きているに違いない。