[Armadillo:08866] CAN通信のselect命令について
Yamamoto
email@hidden
2013年 5月 28日 (火) 15:12:16 JST
Yamamotoです。
度々、お世話になります。
Armadillo-460でCAN0,1を使用してCAN通信を行っていますが、受信待ちのselect命令で設定した時間でタイム
アウトしてくれないように思われます。
また、CAN0側の受信待ちselectではタイムアウトに倍の時間掛かっているように見えます。
何かご存知でしたら教えていただけませんでしょうか?
CAN1,0の順でオープン(接続先の都合で入れ替えて使用しています)
---------------------------------------------------------
static LONG Bf_CanFds[CAN_COMM_MAX] = {-1,-1};
static CHAR Bf_ucCanName[2][5]={"can1","can0"};
LONG CanOpen( USHORT usCanNo )
{
LONG slRet = RET_NG;
LONG slCanfds; /* can raw socket */
struct sockaddr_can addr;
struct ifreq ifr;
if ( usCanNo == 0 || usCanNo == 1 )
{
/* 正常CAN番号 */
/* オープンCAN(SocketCAN) */
if ((slCanfds = (LONG)socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
}
else
{
addr.can_family = AF_CAN;
/* CANデバイス名設定 */
strcpy(ifr.ifr_name, (UCHAR *)&Bf_ucCanName[usCanNo][0]);
if (ioctl( (int)slCanfds, SIOCGIFINDEX, &ifr) < 0)
{
}
else
{
addr.can_ifindex = ifr.ifr_ifindex;
/* disable default receive filter on this RAW socket */
/* This is obsolete as we do not read from the socket at all, butfor */
/* this reason we can remove the receive list in the Kernel to savea */
/* little (really a very little!) CPU usage. */
/* 受信CAN ID設定(フィルター設定) */
if ( usCanNo == CAN_COMM_DEV0 )
{
setsockopt( (int)slCanfds, SOL_CAN_RAW, CAN_RAW_FILTER, &Bf_rfilter0,
sizeof(Bf_rfilter0));
}
else
{
setsockopt( (int)slCanfds, SOL_CAN_RAW, CAN_RAW_FILTER, &Bf_rfilter1,
sizeof(Bf_rfilter1));
}
if (bind( (int)slCanfds, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
}
else
{
slRet = slCanfds;
/* Fds設定 */
Bf_CanFds[usCanNo] = slCanfds;
slRet = RET_OK;
}
}
}
}
else
{
/* CAN番号不正 */
}
return( slRet ) ;
}
---------------------------------------------------------
タイムアウトを10usに設定しているが、1,2msはWaitしているみたい。
かつcan0側のselectで10ms位掛かっているように見える。
(時間は全てtime関数のusec値を元に計算して確認しています。おおよそとは認識していますが)
---------------------------------------------------------
LONG CanRead( USHORT usCanNo, FMT_CAN_FRAM *bfCanMsg )
{
LONG slRet = RET_NG;
fd_set rdfs;
int nbytes,ret;
struct timeval timeout;
errno = 0;
if ( usCanNo == 0 || usCanNo == 1 )
{
/* 正常CAN番号 */
timeout.tv_sec = 0;
// timeout.tv_usec = 50000; /* Wait(us) 50ms */
timeout.tv_usec = 10; /* Wait(us) 500us */
FD_ZERO(&rdfs);
FD_SET(Bf_CanFds[usCanNo], &rdfs);
if ((ret = select(Bf_CanFds[usCanNo]+1, &rdfs, NULL, NULL, &timeout)) <= 0) {
/* 受信データなし */
slRet = 0;
}
else
{
/* 受信データあり */
nbytes = read(Bf_CanFds[usCanNo], bfCanMsg, sizeof(FMT_CAN_FRAM));
// nbytes = recv(Bf_CanFds[usCanNo], bfCanMsg, sizeof(FMT_CAN_FRAM),0);
if ( nbytes == sizeof(FMT_CAN_FRAM) )
{
/* 正常受信 */
slRet = nbytes;
}
else
{
/* 受信サイズ異常 */
}
}
}
else
{
/* CAN番号不正 */
}
return( slRet ) ;
}
---------------------------------------------------------
サンプルから作成して使用しましたので、関数の不適切な使用法が有るかもしれません。
よろしくお願いします。
armadillo メーリングリストの案内