NVIDIA AGX Xavier启用CAN总结


1.参考Xavier官方刷机教程,将xavier置于Forece Recorery模式,Host主机安装SDK Manager

此处需要注意:TARGET OPERATING SYSTEM对应的版本一定要选择JetPack4.4, 否则can总线将无法正常启用

2.在Nvidia Jetson Xavier开发者套件上启用CAN总线,直接按照前辈的教程一步步走完全没问题。

(随便接的,比较丑)

3.安装can-utills测试一下收发正常,摘录的部分工程代码如下
socket_can.h

#include <pthread.h>

#include <stdint.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <string>

#include <linux/can.h>
#include <linux/can/raw.h>
#include <linux/can/error.h>
#include <linux/net_tstamp.h>

#define SET_CAN0_BAUDRATE "sudo ip link set can0 type can bitrate "
#define SET_CAN1_BAUDRATE "sudo ip link set can1 type can bitrate "
#define CAN_FD_ON " dbitrate 2000000 berr-reporting on fd on"
#define CAN0_OPEN "sudo ip link set up can0"
#define CAN1_OPEN "sudo ip link set up can1"
/* set transmit queue length: small value for slower device with a high latency, hight value is recommended for server connected with high-speed internet connections the perform large data transfers */
#define CAN0_LENGTH "sudo ip link set can0 txqueuelen 1000" 
#define CAN1_LENGTH "sudo ip link set can1 txqueuelen 1000"

#define CAN0_CLOSE "sudo ip link set down can0"
#define CAN1_CLOSE "sudo ip link set down can1"

// bool Write(const vector<can_frame>&);
// int Read(vector<can_frame::Frame>&);

static void* ReceiveFunc(void* param);
static void* TransmitFunc(void* param);

pthread_t thread_0_;
pthread_t thread_1_;
static int run_flag_;
// vector<can_frame> can_buf_1_;
// vector<can_frame> can_buf_2_;
// void* handle_ = nullptr;
uint32_t receive_msgs_count;

uint8_t kbaudrate_port0 = 500000; // 250000 1000000
uint8_t kbaudrate_port1 = 500000;
uint8_t raw_socket_;
struct ifreq ifr_;
struct sockaddr_can addr_;
const char bus_name0[5] = "can0";
const char bus_name1[5] = "can1";

};

socket_can.cpp

#include <socket_can.h>

#include <iostream>
#include <cstring>
using std::system;
using std::cout;
using std::endl;

int main(int argc, int** argv) {
// 初始化,打开can控制器
  system(CAN0_CLOSE);
  system(CAN1_CLOSE);
  system((SET_CAN0_BAUDRATE + std::to_string(kbaudrate_port0)).c_str());
  system((SET_CAN1_BAUDRATE + std::to_string(kbaudrate_port1)).c_str());
  system(CAN0_OPEN);
  system(CAN0_LENGTH);
  system(CAN1_OPEN);
  system(CAN1_LENGTH);
  
  raw_socket_ = socket(PF_CAN, SOCK_RAW, CAN_RAW); 
  addr_.can_ifindex = 0; /* 0 means any can interface */                          
  addr_.can_family = PF_CAN;   
  int ret = bind(raw_socket_, (struct sockaddr*)&addr_, sizeof(addr_);
  run_flag_ = 1;
  if(ret < 0) {
   cout << "Error while bind with socket" << endl;
   close(raw_socket_);
   run_flag_ = 0;
  }
  if(pthread_create(&thread_0_, NULL, ReceiveFunc, &run_flag_) != 0) {
  	std::perror("pthread_create ReceiveFunc error");
  }
  if(pthread_create(&thread_1_, NULL, TransmitFunc, &run_flag_)) {
  	std::perror("pthread_create ReceiveFunc error");
   }

  usleep(5000);
  close(raw_socket_);
  
 return 0; 
}

void* ReceiveFunc(void* param) {
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  const int timestamp_flag = SOF_TIMESTAMPING_RX_SOFTWARE;
  timeval socket_timestamp;
  can_frame frame_raw;
  socklen_t receive_length = sizeof(addr_);
  int* run = static_cast<int*>(param);
  setsockopt(raw_socket_, SOL_SOCKET, SO_TIMESTAMPING, &timestamp_flag, sizeof(timestamp_flag));

  while((*run)& 0x0f) {
      pthread_rwlock_wrlock(&socket_rwlock);
      int ret = recvfrom(raw_socket_, &frame_raw, sizeof(frame_raw), 0, (struct sockaddr*)&addr_, &receive_length);
      if(ret <= 0) { // ret is frame_raw.size()
          ROS_ERROR_STREAM("receive nothing or receive message fail!");
      }
      pthread_rwlock_unlock(&socket_rwlock);
      if(frame_raw.can_id == (uint)(0x120 & CAN_SFF_MASK) {
      	 receive_msgs_count++;
      	 cout << "Receive msgs 0x120:" << receive_msgs_count << endl;
      }
  }  
  pthread_exit(0);
}

void* TransmitFunc(void* param) {
can_frame transmit_msgs;
transmit_msgs.can_id = 0x501;
transmit_msgs.can_dlc = 5;
transmit_msgs.Data[0] = 0x11;
transmit_msgs.Data[1] = 0x22;
transmit_msgs.Data[2] = 0x33;
transmit_msgs.Data[3] = 0x44;
transmit_msgs.Data[4] = 0x55;
transmit_msgs.Data[5] = 0x66;

strcpy(ifr_.ifr_name, bus_name0); 
addr_.can_ifindex = ifr_.ifr_ifindex;
ioctl(raw_socket_, SIOGIFINDEX, &ifr_);
int nbytes = sendto(raw_socket_, &transmit_msgs, sizeof(struct can_frame), 0, (struct sockaddr*)&addr_, sizeof(addr_));
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM