BeagleBone Black CAN总线读写数据操作

来源:互联网 发布:机锋论坛淘宝店 编辑:程序博客网 时间:2024/05/22 06:18
进入BBB之后可以通过ifconfig -a来查看是否打开CAN总线了:
[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. root@BBB-CAN:~# ifconfig -a  
  2. can0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00    
  3.           UP RUNNING NOARP  MTU:16  Metric:1  
  4.           RX packets:25 errors:0 dropped:0 overruns:0 frame:0  
  5.           TX packets:62 errors:0 dropped:0 overruns:0 carrier:0  
  6.           collisions:0 txqueuelen:65535   
  7.           RX bytes:104 (104.0 B)  TX bytes:312 (312.0 B)  
  8.           Interrupt:71   
  9. ............  

如果没有看到can0之类的接口的话,估计是你的BBB CAN总线还没被打开,你可以去看这篇文章来打开你的CAN总线。http://blog.csdn.net/trbbadboy/article/details/17154825。使用CAN总线之前需要配置CAN属性(波特率等)并且启动CAN,也可以在该博客中看到。


BeagleBone Black的CAN总线使用socketcan,因此在你打开完CAN总线的socket之后的操作基本和你使用socket一样的。

socketcan的相关内容可以去看wiki。http://en.wikipedia.org/wiki/Socketcan


废话不多,直接来一个例子吧,是想CAN总线上发送0到7数据包(和cansend can0 0 1 2 3 4 5 6 7一样功能)。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * BeagleBone Black CAN Bus 
  3.  * trb 
  4.  * 2013-12-16 
  5.  * ©ynsoft.cn 
  6.  * 
  7.  * @see http://en.wikipedia.org/wiki/Socketcan 
  8.  */  
  9.   
  10. #include <stdio.h>  
  11. #include <stdlib.h>  
  12. #include <string.h>  
  13.   
  14. #include <netinet/in.h>  
  15. #include <arpa/inet.h>  
  16. #include <sys/socket.h>  
  17. #include <sys/ioctl.h>  
  18. #include <net/if.h>  
  19. #include <linux/can.h>  
  20. #include <linux/can/raw.h>  
  21.   
  22. int main(int argc, char *argv[]) {  
  23.     int sock_can = 0, i;  
  24.     struct sockaddr_can addr;  
  25.     static struct can_frame can_frame;  
  26.     struct ifreq ifr;  
  27.   
  28.     // 创造嵌套子  
  29.     if ((sock_can = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {  
  30.         perror("Create socket failed");  
  31.         exit(-1);  
  32.     }  
  33.   
  34.     // 设置CAN接口名称为can0  
  35.     strcpy(ifr.ifr_name, "can0");  
  36.     ioctl(sock_can, SIOCGIFINDEX, &ifr);  
  37.     addr.can_family = AF_CAN;  
  38.     addr.can_ifindex = ifr.ifr_ifindex;  
  39.   
  40.     // 绑定CAN总线  
  41.     if (bind(sock_can, (struct sockaddr *) &addr, sizeof(addr)) < 0) {  
  42.         perror("Bind failded");  
  43.         close(sock_can);  
  44.         exit(-2);  
  45.     }  
  46.     can_frame.can_id = 0x123;   // 设置CANID  
  47.     can_frame.can_dlc = 8;  // 数据长度为8  
  48.   
  49.     // 下面简单的设置数据为0到7  
  50.     for(i=0; i<8; ++i){  
  51.         can_frame.data[i] = i;  
  52.     }  
  53.   
  54.     // 发送 0 1 2 3 4 5 6 7, CAN-ID 0x123  
  55.     if(write(sock_can, &can_frame, sizeof(struct can_frame))<0){  
  56.         perror("Send failded");  
  57.         close(sock_can);  
  58.         exit(-3);  
  59.     }  
  60.     close(sock_can);  
  61.     return 0;  
  62. }  

接收也是差不多一样的,传入一个can_frame结构就行:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. len = read(sock_can_listen, &can_frame, sizeof(struct can_frame));  


如果返回的len小于0的话就是接收出错了。

接收成功之后can_frame的.can_id代表该数据包来自哪个CANID,.can_dlc是CAN数据长度(0-8),而.data里面就放着就收到的数据了。

最后,如果你需要通过代码而非命令行来设置CAN的相关属性的话推荐一个库,叫做libsocketcan,这个地方可以找到http://www.pengutronix.de/software/libsocketcan/download/

0 0
原创粉丝点击