imx6 socketcan 发送问题

参考cansend 的方法进行发送can 数据。

    //  我今天参考了 NXP 官网,用了旧一版的 libsocket, 但是我觉得总体上来说变话是没有的。
    //  参考: https://community.nxp.com/docs/DOC-1437
    //  进入 canutils-4.0.6  目录
    //  在 src 目录下, 可以看到 cansend.c 
    vim  src/cansend.c
    
    // 直接看到 main 函数
     48 int main(int argc, char **argv)                                                 
     49 {
     //     默认的一些参数             
     56     int family = PF_CAN, type = SOCK_RAW, proto = CAN_RAW; 
     58     int s, opt, ret, i, dlc = 0, rtr = 0, extended = 0;                   
     // ... ... 
            // 这里直接是获取了所有的参数并解析它                                            
     75     while ((opt = getopt_long(argc, argv, "hf:t:p:vi:lre", long_options, NULL)) != -1) {
     76         switch (opt) {                                                          
     77         case 'h':     // 打印帮助信息                                            
     78             print_usage(basename(argv[0]));                                     
     79             exit(0);                                                            
     80                                                                                 
     81         case 'f':     // 家族                                                         
     82             family = strtoul(optarg, NULL, 0);                                  
     83             break;                                                              
     84                                                                                 
     85         case 't':     // 类型                                                          
     86             type = strtoul(optarg, NULL, 0);                                    
     87             break;                                                              
     88                                                                                 
     89         case 'p':     // 协议                                                          
     90             proto = strtoul(optarg, NULL, 0);                                   
     91             break;                                                              
     92                                                                                 
     93         case 'v':     // 打印发送的数据                                                     
     94             verbose = 1;                                                        
     95             break;                                                              
     96                                                                                 
     97         case 'l':     // 循环次数                                                          
     98             if (optarg)                                                         
     99                 loopcount = strtoul(optarg, NULL, 0);                           
    100             else     // 或是是无数次                                                         
    101                 infinite = 1;                                                   
    102             break;                                                              
    103         case 'i':     // 指定接口  -ican0                                                           
    104             frame.can_id = strtoul(optarg, NULL, 0);                            
    105             break;                                                              
    106                                                                                 
    107         case 'r':      // 指定是否是远程帧                                                        
    108             rtr = 1;                                                            
    109             break;                                                              
    110                                                                                 
    111         case 'e':      // 扩展帧                                                         
    112             extended = 1;                                                       
    113             break;                                                              
    114                                                                                 
    115         case VERSION_OPTION:       // 打印版本信息                                             
    116             printf("cansend %s\n", VERSION);                                    
    117             exit(0);                                                            
    118                                                                                 
    119         default:                                                                
    120             fprintf(stderr, "Unknown option %c\n", opt);                        
    121             break;                                                              
    122         }                                                                       
    123     }   

    // ... ...
    134     interface = argv[optind];     // 指定接口, 这里的话第一个参数应该是要 -i 指定接口
    // ... ...
    139     s = socket(family, type, proto);   // 申请一个套接字,我引用了这里                                         
    140     if (s < 0) {                                                                
    141         perror("socket");                                                       
    142         return 1;                                                               
    143     }    

    //  指定家族                                                                       
    145     addr.can_family = family;                                                   
    146     strcpy(ifr.ifr_name, interface);                                            
    147     if (ioctl(s, SIOCGIFINDEX, &ifr)) {                                         
    148         perror("ioctl");                                                        
    149         return 1;                                                               
    150     }                                                                           
    151     addr.can_ifindex = ifr.ifr_ifindex;   

    // ... ...   绑定                                    
    153     if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {                  
    154         perror("bind");                                                         
    155         return 1;                                                               
    156     }                                                                           

    // 数据, 数据包的大小, 我修改了这里,这里我直接获取了qt界面上一个text 的属性。
    158     for (i = optind + 1; i < argc; i++) {                                       
    159         frame.data[dlc] = strtoul(argv[i], NULL, 0);                            
    160         dlc++;                                                                  
    161         if (dlc == 8)                                                           
    162             break;                                                              
    163     }                                                                           
    164     frame.can_dlc = dlc;     

    // 扩展帧                                                
    167     if (extended) {                                                             
    168         frame.can_id &= CAN_EFF_MASK;                                           
    169         frame.can_id |= CAN_EFF_FLAG;                                           
    170     } else {                                                                    
    171         frame.can_id &= CAN_SFF_MASK;                                           
    172     }                                                                           
    
    // 远程帧, 远程帧是没有数据发送的请注意                                                                             
    174     if (rtr)                                                                    
    175         frame.can_id |= CAN_RTR_FLAG;                                           

    // 这里是判断是否循环, 我参考了这里只发了一次,把循环条件去掉了。
    185     while (infinite || loopcount--) {                                           
    186         ret = write(s, &frame, sizeof(frame));                                  
    187         if (ret == -1) {                                                        
    188             perror("write");                                                    
    189             break;                                                              
    190         }                                                                       
    191     }         

    //      关闭套接字                                                           
    193     close(s);                                                                   
    194     return 0;                                                                   
    195 }                  

posted @ 2017-05-04 17:31  陈富林  阅读(1793)  评论(0编辑  收藏  举报