如何测量CAN总线速率

[复制链接]
查看11 | 回复6 | 2021-1-27 06:46:20 | 显示全部楼层 |阅读模式
各位大侠,最近师兄给了个任务要求测量CAN总线的波特率,用的是TI的SBC8600芯片,上面跑的是linux。我之前网上找到了canutils的源码,利用cansend发送数据,candump接受数据,但是如何测量总线波特率呢?cansend发送数据只能够一次发送八个字节,而循环发送最多也只能发送32次,否则就会出现writenospaceavailable。
不知道该具体如何弄,跪求指导!谢谢!
分 -->
回复

使用道具 举报

千问 | 2021-1-27 06:46:20 | 显示全部楼层
自己顶一下。
可能问题还是没说清楚。现在基本思路解决了,但是利用socketCAN的时候还是有问题。贴一下代码:

externintoptind,opterr,optopt;
staticvoidprint_usage(char*prg)
{
fprintf(stderr,
"Usage:%s[][Options]\n"
"canconsistofupto8bytesgivenasaspaceseparatedlist\n"
"Options:\n"
"-i,--identifier=IDCANIdentifier(default=1)\n"
"-r--rtrsendremoterequest\n"
"-e--extendedsendextendedframe\n"
"-f,--family=FAMILYProtocolfamily(defaultPF_CAN=29)\n"
"-t,--type=TYPESockettype,seeman2socket(defaultSOCK_RAW=3)\n"
"-p,--protocol=PROTOCANprotocol(defaultCAN_RAW=1)\n"
"-lsendmessageinfinitetimes\n"
"--loop=COUNTsendmessageCOUNTtimes\n"
"-v,--verbosebeverbose\n"
"-h,--helpthishelp\n"
"--versionprintversioninformationandexit\n",
prg/*,PF_CAN,SOCK_RAW,CAN_RAW*/);
}
enum{
VERSION_OPTION=CHAR_MAX+1,
};
intmain(intargc,char**argv)
{
structcan_frameframe={
.can_id=1,
};
structifreqifr;
structsockaddr_canaddr;
char*interface;
//intfamily=PF_CAN,type=SOCK_RAW,proto=CAN_RAW;
intfamily=29,type=3,proto=1;
intloopcount=1,infinite=0;
ints,opt,ret,i,dlc=0,rtr=0,extended=0;
intverbose=0;
structtimevaltstart,tend;
floattimeuse;
structoptionlong_options[]={
{"help",no_argument,0,'h'},
{"identifier",required_argument,0,'i'},
{"rtr",no_argument,0,'r'},
{"extended",no_argument,0,'e'},
{"family",required_argument,0,'f'},
{"protocol",required_argument,0,'p'},
{"type",required_argument,0,'t'},
{"version",no_argument,0,VERSION_OPTION},
{"verbose",no_argument,0,'v'},
{"loop",required_argument,0,'l'},
{0,0,0,0},
};
while((opt=getopt_long(argc,argv,"hf:t:p:vi:lre",long_options,NULL))!=-1){
printf("optvalueis%d\n",opt);
switch(opt){
case'h':
printf("hisexectued,optindis%d\n",optind);
print_usage(basename(argv[0]));
exit(0);
case'f':
printf("fisexecuted,optindis%d\n",optind);
family=strtoul(optarg,NULL,0);
break;
case't':
printf("tisexecuted,optindis%d\n",optind);
type=strtoul(optarg,NULL,0);
break;
case'p':
printf("pisexecuted,optindis%d\n",optind);
proto=strtoul(optarg,NULL,0);
break;
case'v':
printf("visexecuted,optindis%d\n",optind);
verbose=1;
break;
case'l':
printf("lisexecuted,optindis%d\n",optind);
printf("optargisacharp,itsvalueis%s\n",optarg);
if(optarg)
//loopcount=strtoul(optarg,NULL,0);
{
loopcount=strtoul(optarg,NULL,0);
printf("loopcountvalueis%d\n",loopcount);
}
else
infinite=1;
break;
case'i':
printf("iisexecuted,optindis%d\n",optind);
printf("optargis%s\n",optarg);
frame.can_id=strtoul(optarg,NULL,0);
printf("frame.can_idis%d\n",frame.can_id);
printf("optindis%d\n",optind);
break;
case'r':
printf("risexecuted,optindis%d\n",optind);
rtr=1;
break;
case'e':
printf("eisexecuted,optindis%d\n",optind);
extended=1;
break;
//caseVERSION_OPTION:
//printf("cansend%s\n",VERSION);
//exit(0);
default:
printf("defaultisexecuted,optindis%d\n",optind);
fprintf(stderr,"Unknownoption%c\n",opt);
break;
}
}
printf("optindis%d\n",optind);
if(optind==argc){
printf("optind==argc,optindis%d\n",optind);
print_usage(basename(argv[0]));
exit(0);
}
printf("optindis%d\n",optind);
if(argv[optind]==NULL){
printf("argv[optind]==NULL,optindis%d\n",optind);
fprintf(stderr,"NoInterfacesupplied\n");
exit(-1);
}
printf("optindis%d\n",optind);
interface=argv[optind];
printf("interface=%s,family=%d,type=%d,proto=%d\n",
interface,family,type,proto);
s=socket(family,type,proto);
if(s
现在我运行每次到write函数的时候,刚开始发送没有问题,但是一旦我设置loop很大的时候就会出现write:nobufferspaceavailable.如果我改成send的话结果也是一样。求大侠们指导。我想测CAN速率方法应该是发送端设置一个发送时间,接收端设置一个接收时间,这样就能测出来了吧应该。
回复

使用道具 举报

千问 | 2021-1-27 06:46:20 | 显示全部楼层
再手动顶一下,求大牛指导
回复

使用道具 举报

千问 | 2021-1-27 06:46:20 | 显示全部楼层
当你读写操作的时候,数据会被先保存在一块buffer里当buffer满了或者超时的时候linux会强制IO发送数据,你的系统提示buffer已经满了说明你的数据吞吐量已经超过了IO负荷,也就是说读写速度已经到了极限。这里你或者减小loop次数或者每次loop中增加延时,或者修改kernel增加buffersize。
回复

使用道具 举报

千问 | 2021-1-27 06:46:20 | 显示全部楼层
引用3楼lalune的回复:当你读写操作的时候,数据会被先保存在一块buffer里当buffer满了或者超时的时候linux会强制IO发送数据,你的系统提示buffer已经满了说明你的数据吞吐量已经超过了IO负荷,也就是说读写速度已经到了极限。这里你或者减小loop次数或者每次loop中增加延时,或者修改kernel增加buffersize。
读写速度是可以设置的,但是我尝试减少loop次数,但是我运行多次此程序还是会出现此类问题,怀疑是buffer已满,必须清空,但是不知道该如何清空这个buffer。
回复

使用道具 举报

千问 | 2021-1-27 06:46:20 | 显示全部楼层
可以试试sync方法强制内存去写IO
回复

使用道具 举报

千问 | 2021-1-27 06:46:20 | 显示全部楼层
可以通过setsockopt来设置写buffer的大小
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行