激情综合丁香-激情综合六月-激情综合婷婷亚洲图片-激情综合图区-激情综合网五月

英創工控主板CAN FD編程及使用介紹

 2021-10-25     作者:黃志超         
文章標簽:C/C++ESM8000系列CAN

  CAN FD (CAN with Flexible Data rate)可以認為是傳統CAN總線的升級版本,主要是對傳統CAN總線協議的數據長度和傳輸速度上做了升級。CAN FD的數據幀可以支持最長64數據字節的長度,而傳統CAN總線的數據長度為8字節。在傳輸速度上,標稱(仲裁)比特率與傳統CAN總線一致,最快支持到1M比特率,但是數據比特率則取決于現場總線環境,理論可以實現高達5 Mbit/s的數據比特率,同時CAN FD也是兼容傳統CAN總線的。網上也有許多介紹CAN FD的資料,有興趣的的話可以搜索更加詳細的資料查看。


  英創公司推出的ESM8000主板上帶有兩路支持CAN FD協議的CAN總線,另外基于ESM8000主板,英創公司還推出了支持6路CAN FD協議的CAN總線擴展方案,關于這套方案具體可以參考《ESM8000異構CPU實時應用——6路CAN-FD的實現》。不管是哪一種方案,英創公司都提供了現成驅動,將每一路CAN總線都映射為linux系統中的標準CAN設備。而用戶通過標準的socketcan編程,就可以實現對每一路CAN總線的操作。Linux系統提供的socketcan已經對CAN FD提供了完整的支持,并且同時能夠兼容原來的傳統CAN總線,接下來我們就介紹具體的編程方法。


  在socketcan中為了支持CAN FD,需要使用到數據幀結構canfd_frame,這個數據結構中同時支持了傳統CAN總線的數據幀與CAN FD的數據幀。在使能了CAN FD功能后,通過canfd_frame就可以進行收發數據。CAN總線使用的幀的結構體定義在include/linux/can.h頭文件中,其中原來傳統CAN總線的數據幀can_frame具體內容如下:


/* CAN payload length and DLC definitions according to ISO 11898-1 */  
#define CAN_MAX_DLC 8  
#define CAN_MAX_DLEN 8  
  
/** 
 * struct can_frame - basic CAN frame structure 
 * @can_id:  CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition 
 * @can_dlc: frame payload length in byte (0 .. 8) aka data length code 
 *           N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1 
 *           mapping of the 'data length code' to the real payload length 
 * @__pad:   padding 
 * @__res0:  reserved / padding 
 * @__res1:  reserved / padding 
 * @data:    CAN frame payload (up to 8 byte) 
 */  
struct can_frame {  
    canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */  
    __u8    can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */  
    __u8    __pad;   /* padding */  
    __u8    __res0;  /* reserved / padding */  
    __u8    __res1;  /* reserved / padding */  
    __u8    data[CAN_MAX_DLEN] __attribute__((aligned(8)));  
};

 

  CAN FD協議的數據幀canfd_frame具體定義如下:


/* CAN FD payload length and DLC definitions according to ISO 11898-7 */  
#define CANFD_MAX_DLC 15  
#define CANFD_MAX_DLEN 64  
  
/** 
 * struct canfd_frame - CAN flexible data rate frame structure 
 * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition 
 * @len:    frame payload length in byte (0 .. CANFD_MAX_DLEN) 
 * @flags:  additional flags for CAN FD 
 * @__res0: reserved / padding 
 * @__res1: reserved / padding 
 * @data:   CAN FD frame payload (up to CANFD_MAX_DLEN byte) 
 */  
struct canfd_frame {  
    canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */  
    __u8    len;     /* frame payload length in byte */  
    __u8    flags;   /* additional flags for CAN FD */  
    __u8    __res0;  /* reserved / padding */  
    __u8    __res1;  /* reserved / padding */  
    __u8    data[CANFD_MAX_DLEN] __attribute__((aligned(8)));  
};

 

  通過對比很容易發現在canfd_frame中, can幀的id、can幀的數據長度以及can幀實際的數據和can_frame結構體中對應成員變量的偏移地址是完全一致的,只有數據的最大長度有所區別。所以傳統CAN總線的數據幀結構體可以直接拷貝到CAN FD的數據幀結構體中,這也允許了用戶通過canfd_fram結構體實現對不同結構數據幀的發送和接收。在同時存在傳統CAN數據幀和CAN FD數據幀的情況下用戶,也不會增加程序的復雜程度,通過判斷數據長度就能夠區別不同的數據幀結構。


  了解了數據幀結構體,接下來就是帶入到程序中實際操作了,我們首先需要啟動CAN總線,在Linux系統中可以通過ip(8)工具來進行設置。這里需要特別注意,在使用CAN FD的情況下,設備之間設置的比特率和采樣點必須一致,否則會無法通信。本次測試采用了德國PEAK公司的PCAN-USB FD設備和ESM8000主板連接進行收發數據,仲裁比特率設置為250K,數據傳輸比特率設置為2M,如下圖:


英創工控主板CAN FD編程及使用介紹.png

仲裁比特率                                                                                    數據傳輸比特率


  從上圖可以看到,250K波特率下采樣點在75%的位置,而2M波特率下采樣點在80%的位置。所以在ESM8000主板上也需要做同樣的設置,通過ip(8)工具可以很容易的設置,具體代碼如下:


/* 關閉can0 */  
system("ifconfig can0 down");  
/* 設置仲裁波特率和數據波特率,以及對應的采樣點 */  
system("ip link set can0 type can bitrate 250000 sample-point 0.75 dbitrate 2000000 dsample-point 0.8 fd on restart-ms 100");  
/* 啟動can0 */  
system("ifconfig can0 up");

 

  如果實際使用中,波特率和采樣點不同,只需要更改其中波特率和采樣點的設置即可,主板上的驅動會根據設置的值,自動計算出對應的參數并設置到CAN總線中。然后創建socketcan的套接字,這部分代碼和傳統CAN總線的socketcan操作完全一致:


/* 創建套節字 */  
s = socket(PF_CAN, SOCK_RAW, CAN_RAW);  
printf( "SOCK_RAW can sockfd:%d\n", s );  
if( s < 0 )  
{  
  return -1;  
}  
  
/* 是否開啟回環功能 */  
int loopback = 0; /* 0 = disabled, 1 = enabled (default) */  
setsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback));  
  
/* 賦值實際的設備名 */  
strcpy(ifr.ifr_name, "can0" );  
ret = ioctl(s, SIOCGIFINDEX, &ifr);  
if( ret < 0 )  
{  
  return -1;  
}  
addr.can_family = AF_CAN;  
addr.can_ifindex = ifr.ifr_ifindex;

 

  創建的CAN_RAW套接字對于CAN FD的支持默認是關閉的,可以能夠通過使能CAN_RAW_FD_FRAMES這個套接字選項來增加對CAN FD的支持,當CAN_RAW_FD_FRAMES選項被使能,就可以同時支持發送can和can fd數據幀了,具體代碼如下:


/* check if the frame fits into the CAN netdevice */  
if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {  
    perror("SIOCGIFMTU");  
    return 1;  
}  
  
if (ifr.ifr_mtu != CANFD_MTU) {  
    printf("CAN interface is not CAN FD capable - sorry.\n");  
    return 1;  
}  
  
enable_canfd = 1;  
/* interface is ok - try to switch the socket into CAN FD mode */  
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable_canfd, sizeof(enable_canfd))){  
    printf("error when enabling CAN FD support\n");  
    return 1;  
}  
  
/* 將can接口和can設備id綁定 */  
bind(s, (struct sockaddr *)&addr, sizeof(addr));

 

  到這里CAN設備的初始化就已經完成了,此時通過write和read函數,就可以通過對應的CAN接口進行數據通訊了,注意如果要支持CAN FD這里代入讀寫的數據幀結構體應該為canfd_frame。例程在這里實現了一個簡單的回發功能,先讀取設備的數據然后判斷數據幀的類型并回發,具體代碼如下:


for( i1=0; ;)  
{  
  /* 讀取數據 */  
  nbytes = read(s, &frame, sizeof(struct canfd_frame));  
  if (nbytes < 0) {  
    perror("can raw socket read");  
    return 1;  
  }  
  /* 判斷數據幀的類型 */  
  if (nbytes == CANFD_MTU) {  
    printf("got CAN FD frame with length %d\n", frame.len);  
    /* frame.flags contains valid data */  
    /* 這里只是簡單的回發 */  
    write(s, &frame, sizeof(struct canfd_frame));  
  } else if (nbytes == CAN_MTU) {  
    printf("got legacy CAN frame with length %d\n", frame.len);  
    /* frame.flags is undefined */  
    /* 這里只是簡單的回發 */  
    write(s, &frame, sizeof(struct can_frame));  
    } else {  
      fprintf(stderr, "read: invalid CAN(FD) frame\n");  
      return 1;  
    }  
}

 

  使用PCAN的測試效果如下圖:


英創工控主板CAN FD編程及使用介紹.png


  上圖中,上半部分為接收欄,下半部分為發送欄??梢钥吹轿覀兺ㄟ^PCAN同時發送了一個標準CAN幀和一個CAN FD幀,ESM8000主板收到后進行了回發,回發的也同樣是一個標準CAN幀和一個CAN FD幀,通過軟件上的Type上可以看到標識,CAN FD幀同時也支持了比特率切換,按照我們之前的設置,CAN FD幀的數據部分就應該以2M的比特率進行的傳輸,下圖是通訊過程中,用示波器抓取的一次波形,可以看到前后仲裁比特率,和中間數據比特率的對比:


英創工控主板CAN FD編程及使用介紹.png


  感興趣的客戶可以聯系英創的工程師獲取完整的測試代碼。

文章標簽:C/C++ESM8000系列CAN
主站蜘蛛池模板: 91探花在线播放| 麻豆传媒在线视频| 女女互添下身免费视频| 大色香蕉色视频大全| 免费观看欧美性生| 国产一级一片| 91精品欧美一区二区综合在线| 午夜国产在线| 久久精品毛片| 成人福利在线视频| 欧美国产永久免费看片| 黄色aaa毛片| 国内成人精品亚洲日本语音| 亚洲欧洲精品国产区| 99久久免费国产特黄| 久久91精品国产91久久跳舞| 日韩美aaa特级毛片| 免费一区二区| 国产黄色a级| 337q日本大胆欧美人术艺术| 国产精品香蕉| 青草久操| 日韩欧美精品综合一区二区三区| 一级爱片| 丝袜高跟在线| 亚洲最新视频在线观看| 国产成人一区二区三区在线视频 | 女视频www女中国| 深夜做爰性大片中文| 97青青草视频| ak福利午夜在线观看| a级黄色影院| 日本r级在线| 亚洲精品欧美一区二区三区| 欧洲美女大片免费播放器视频| 国产欧美亚洲精品第一区| 国产精品成人免费观看| 99久久综合狠狠综合久久| 久久综合九色综合97手机观看| 一本一本久久a久久精品综合麻豆 一本一道波多野结衣一区二区 | 免费又爽又黄禁片观看1000|