This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-AM437X: How to configure CAN using "ip" command

Part Number: PROCESSOR-SDK-AM437X

Hello,

I have been trying to use the "ip" command to configure the CAN interface. When executed:

ip link set can0 type can bitrate 125000

Response:

ip: either "dev" is duplicate, or "type" is garbage

I have visited threads which mention missing iproute2. In particular:

https://e2e.ti.com/support/legacy_forums/embedded/linux/f/354/t/168202?tisearch=e2e-sitesearch&keymatch=iproute2

When following the resolution in the above thread, I found the relevant sections missing. 

What should I do to configure and use the CAN bus?

Thanks,

Peiman

  • Hi,

    Could you please tell me more about the board and TI SDK that you are using?

    Best Regards,

    Schuyler

  • Hi,

    Thank you for your response. I am using ti-processor-sdk-linux-am437x-evm-06.00.00.07. This is running on custom hardware similar to the AM437x IDK. 

    Some more information:

    1. On the custom hardware 'ifconfig -a' shows the can interface.
    2. "lsmod" shows:
      1. c_can_platform 16384 0
        c_can          20480 1 c_can_platform
        can_dev        24576 1 c_can

    3. When executing the following code, I can create and bind to a socket using "can0" successfully. The write fails. I am guessing this is because I haven't configured the CAN interface?
    	//Create an empty socket API with
    	//PF_CAN as the protocol family
    	int s;
    
    	cout << "Creating the socket: " << endl;
    	if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
    	{
    		result = SOCKET_ERROR;
    		return result;
    	}
    	cout << "Done.     Socket fd: " << s << endl << endl;
    
    	//----------------------------------------
    	//----------------------------------------
    	//Bind the socket to one of the interfaces
    	struct sockaddr_can addr;
    	struct ifreq ifr;
    	strcpy(ifr.ifr_name, (const char*)"can0");
    
    	ioctl(s, SIOCGIFINDEX, &ifr);
    
    	//memset(&addr, 0, sizeof(addr));
    	addr.can_family = AF_CAN;
    	addr.can_ifindex = ifr.ifr_ifindex;
    
    	cout << "Binding to addr: " << endl;
    	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    	{
    		return SOCKET_ERROR;
    	}
    	cout << "Done" << endl << endl;
    
    	//----------------------------------------
    	//----------------------------------------
    	//Writing CAN frames: To send a frame with the
    	//ID 0x101 and a two byte payload of 0x41, 0x42
    
    	struct can_frame frame;
    	frame.can_id  = 0x555;
    	frame.can_dlc = 2;
    	frame.data[0] = 0x41;
    	frame.data[1] = 0x42;
    
    	cout << "Writing 2 bytes to the socket: " << endl;
    	int nBytes = write(s, &frame, sizeof(struct can_frame));
    
    	cout << "wrote " << nBytes << " bytes." << endl;
    	if (nBytes != sizeof(struct can_frame))
    	{
    		cout << "Failed" << endl;
    		return DATA_TRANSFER_ERROR;
    	}
    

    Regards,

    Peiman

  • Hi,

    Have you seen this chapter in the SDK documentation? It has the steps necessary to initialize the driver.  In the TI filesystem there are some basic send/receive utilities (cansend/candump) that can be used to test the interface. 

    Best Regards,

    Schuyler