[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 メーリングリストの案内