设为首页收藏本站
查看: 12148|回复: 1

Linux下can发送和接收应用程序

[复制链接]

34

主题

9

回帖

363

积分

中级会员

积分
363
conway 发表于 2014-8-28 11:27:02 | 显示全部楼层 |阅读模式
can接收应用程序:
[mw_shl_code=c,true]#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <getopt.h>

/**
* @brief: print usage message
* @Param: stream: output device
* @Param: exit_code: error code which want to exit
*/
void print_usage (FILE *stream, int exit_code)
{
    fprintf(stream, "Usage: option [ dev... ] \n");
    fprintf(stream,
            "\t-h  --help     Display this usage information.\n"
            "\t-d  --device   The device can[0-1]\n"
                    "\t-i  --id                  Set the can id that want to receive\n");
    exit(exit_code);
}

/**
* @brief: main function  
* @Param: argc: number of parameters
* @Param: argv: parameters list
*/
int main(int argc, char *argv[])  
{  
        int s, nbytes, i;
        char *device;
        int id, next_option, device_flag=0, id_flag=0;  
        struct sockaddr_can addr;  
        struct ifreq ifr;  
        struct can_frame frame;  
        struct can_filter rfilter[1];
        const char *const short_options = "hd:i:";
        const struct option long_options[] = {
                { "help",   0, NULL, 'h'},
                { "device", 1, NULL, 'd'},
                { "id", 1, NULL, 'i'},
                { NULL,     0, NULL, 0  }
        };
       
        while (1) {
                next_option = getopt_long (argc, argv, short_options, long_options, NULL);
                if (next_option < 0)
                        break;
                switch (next_option) {
                        case 'h':
                                print_usage (stdout, 0);
                                break;
                        case 'd':
                                device = optarg;
                                device_flag = 1;
                                break;
                        case 'i':
                                id = atoi(optarg);
                                id_flag = 1;
                                break;
                        case '?':
                                print_usage (stderr, 1);
                                break;
                        default:
                                abort ();
                }
        }
       
        if (!device_flag) {
                print_usage (stdout, 0);
                exit(0);       
        }
        /* create a socket */  
        s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
        strcpy(ifr.ifr_name, device);
        /* determine the interface index */  
        ioctl(s, SIOCGIFINDEX, &ifr);                    
        addr.can_family = AF_CAN;  
        addr.can_ifindex = ifr.ifr_ifindex;
        /* bind the socket to a CAN interface */   
        bind(s, (struct sockaddr *)&addr, sizeof(addr));
       
        if (id_flag) {     
                /* define the filter rules */   
                rfilter[0].can_id   = id;  
                rfilter[0].can_mask = CAN_SFF_MASK;  
                /* Set the filter rules */          
                setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
        }  
        while(1) {
                /* receive frame */  
                nbytes = read(s, &frame, sizeof(frame));            
                /* printf the received frame */  
                if (nbytes > 0) {
                        printf("%s  %#x  [%d]  ", ifr.ifr_name, frame.can_id, frame.can_dlc);
                        for (i = 0; i < frame.can_dlc; i++)
                                printf("%#x ", frame.data);
                        printf("\n");
                }  
        }  
        close(s);  
        return 0;  
}  [/mw_shl_code]
can发送应用程序:
[mw_shl_code=c,true]#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <getopt.h>

char *program_name;

/**
* @brief: print usage message
* @Param: stream: output device
* @Param: exit_code: error code which want to exit
*/
void print_usage (FILE *stream, int exit_code)
{
    fprintf(stream, "Usage: %s [ dev... ] \n", program_name);
    fprintf(stream,
            "\t-h  --help     Display this usage information.\n"
            "\t-d  --device   The device can[0-1]\n"
                    "\t-i  --id                  Set the can id that want to send\n");
    exit(exit_code);
}
/**
* @brief: Hexadecimal number converted to decimal number
* @Param: pHex: the Hexadecimal number that formularize string format
*/
int hex2dec(const char * phex)
{
    int dwhexnum=0;
        
    if ((phex[0] == '0') && (phex[1] == 'x' || phex[1] == 'X')) {
            phex = phex + 2;
    }
    for (; *phex!=0 ; phex++) {   
                 dwhexnum *= 16;
                 if ((*phex>='0') && (*phex<='9'))
                         dwhexnum += *phex-'0';
                 else if ((*phex>='a') && (*phex<='f'))
                         dwhexnum += *phex-'a'+10;
                 else if ((*phex>='A') && (*phex<='F'))
                         dwhexnum += *phex-'A'+10;
                 else {
                         printf("hex format error!\n");
                         exit(0);       
                 }                 
        }
     return dwhexnum;
}

/**
* @brief: main function  
* @Param: argc: number of parameters
* @Param: argv: parameters list
*/
int main(int argc, char *argv[])  
{  
    int s, nbytes, i;
    char *device;
    int id, next_option, device_flag=0, id_flag=0;   
        struct sockaddr_can addr;  
        struct ifreq ifr;  
        struct can_frame frame[1];
        const char *const short_options = "hd:i:";
        const struct option long_options[] = {
                { "help",   0, NULL, 'h'},
                { "device", 1, NULL, 'd'},
                { "id", 1, NULL, 'i'},
                { NULL,     0, NULL, 0  }
        };
       
        program_name = argv[0];
        while (1) {
                next_option = getopt_long (argc, argv, short_options, long_options, NULL);
                if (next_option < 0)
                        break;
                switch (next_option) {
                        case 'h':
                                print_usage (stdout, 0);
                                break;
                        case 'd':
                                device = optarg;
                                device_flag = 1;
                                break;
                        case 'i':
                                id = hex2dec(optarg);
                                id_flag = 1;
                                break;
                        case '?':
                                print_usage (stderr, 1);
                                break;
                        default:
                                abort ();
                }
        }
       
        if (!device_flag || !id_flag) {
                print_usage (stdout, 0);
                exit(0);       
        }
       
        /* create a socket */  
        s = socket(PF_CAN, SOCK_RAW, CAN_RAW);      
        strcpy(ifr.ifr_name, device );
        /* determine the interface index */  
        ioctl(s, SIOCGIFINDEX, &ifr);                     
        addr.can_family = AF_CAN;  
        addr.can_ifindex = ifr.ifr_ifindex;
        /* bind the socket to a CAN interface */  
        bind(s, (struct sockaddr *)&addr, sizeof(addr));              
        /* Set the filter rules */  
        setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);  
        /* generate CAN frames */
        frame[0].can_id = id;  
        frame[0].can_dlc = argc - 5;
        for(i = 0; i < frame[0].can_dlc; i++) {
                frame[0].data = hex2dec(argv[5 + i]);       
        }
         
        /* send CAN frames */  
        while(1) {  
                nbytes = write(s, &frame[0], sizeof(frame[0]));   
                if (nbytes < 0) {
            perror("can raw socket write");
                        return 1;
                }

                /* paranoid check ... */
                if (nbytes < sizeof(struct can_frame)) {
                        fprintf(stderr, "read: incomplete CAN frame\n");
                        return 1;
                }
                sleep(1);
        }  
        close(s);  
        return 0;  
} [/mw_shl_code]

回复

使用道具 举报

0

主题

2

回帖

15

积分

新手上路

积分
15
4008844442.net 发表于 2014-11-27 17:52:36 | 显示全部楼层
不错不错,楼主是个绝对高手












.top域名抢注 .top域名注册 .top域名申请 .top域名价格
http://www.4008844442.net/reg/domainapp.asp?productcode=d685
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录

本版积分规则

Archiver|手机版|小黑屋|米尔科技论坛   

GMT+8, 2024-4-30 13:54 , Processed in 0.051809 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表