1

I implemented a CAN bus communication for writing and read operations with linux. I am using socketCan library. Write function works correctly. I have problems with my reading function:

int can_receive(void)
{
    struct can_frame frameRead;
    //struct sockaddr_can addr;
    //struct ifreq ifr;
    //struct timeval tv;

    //socklen_t len = sizeof(addr);
    int8_t nbytesReceive;
    //nbytesReceive = 16;
    LE_INFO("while");
    /*
    while(nbytesReceive != -1)
    {
        if((nbytesReceive = recvfrom(sdr, &frameRead, sizeof(struct can_frame), 0, (struct sockaddr *)&addr, &len)) != sizeof(struct can_frame))
        {
            LE_INFO("Socket reading error, nbytesReceive = %d", nbytesReceive);
            return SOCK_READING_ERROR;
        }
        else
        {
            ifr.ifr_ifindex = addr.can_ifindex;
            ioctl(sdr, SIOCGIFNAME, &ifr);
            ioctl(sdr, SIOCGSTAMP, &tv);
            LE_INFO( "     Receive message %02X %02X %02X %02X %02X %02X %02X %02X %02X", frameRead.can_id, frameRead.data[0], frameRead.data[1], frameRead.data[2], frameRead.data[3]
, frameRead.data[4], frameRead.data[5], frameRead.data[6], frameRead.data[7] );
        }
    }*/
    LE_INFO("SDR is: %d ", sdr);
    nbytesReceive = read(sdr, &frameRead, sizeof(frameRead));
    
    LE_INFO("nbytes is: %d ", nbytesReceive);
      while(nbytesReceive != 0)
      
    {

        if ((nbytesReceive = read(sdr, &frameRead, sizeof(frameRead))) != sizeof(frameRead))
        {
            LE_INFO("Socket reading error, nbytesReceive = %d", nbytesReceive);
            return SOCK_READING_ERROR;
        }
        else
        {
            LE_INFO("Receive message %X %X %X %X %X %X %X %X %X", frameRead.can_id, frameRead.data[0], frameRead.data[1], frameRead.data[2], frameRead.data[3]
, frameRead.data[4], frameRead.data[5], frameRead.data[6], frameRead.data[7]);
}
                     
    }
    return 0;

}

I implemented while in two ways in order to understand what happens (one is a comment). I obtain always socket error, so the first condition of while loop. I inizialized CAN_socket in this way:

// SOCKET FOR READING
sdr = socket(PF_CAN, SOCK_RAW, CAN_RAW);
LE_INFO("sdr è: %d", sdr);
if ((sdr = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)

{
    LE_INFO("sdr errato");
    return SOCKET_ERROR;
}

addr.can_family = AF_CAN;

strcpy(ifr.ifr_name, name);
if (ioctl(sdr, SIOCGIFINDEX, &ifr) < 0)
{
    return SOCK_IOCTL_ERROR;
}

addr.can_ifindex = ifr.ifr_ifindex;


if (bind(sdr, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
    return SOCK_BINDING_ERROR;
}

// Filter
struct can_filter rfilter[7]; int i = 0;
rfilter[i].can_id  = CHG_TX_STS;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id   = CHG_TX_ACT;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id   = BMS_CHRGR_CTL;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id   = BMS_SOC_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id   = BMS_BATTP_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id   = BMS_BATP_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id   = BMS_BATU_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
setsockopt(sdr, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));

// SET SOCKET BUFFER SIZE
setsockopt(sdr, SOL_CAN_RAW, SO_RCVBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));

Can kindly someone help me to understand where am I wrong, since I cannot read anything? I want to clarify that on therminal by candump command I can read CAN signals correctly, so the problem is in the software. Any help is appreciated Regards.

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
kevin94
  • 37
  • 5

1 Answers1

0

Sorry, I solved. It was necessary to set a delay time because, as the code is made, the generated condition is directly that of error. By putting a delay I can receive the message generated by the request I sent (the error is also there because I have no other messages running in runtime, being a simulator and not a real ECU). Thank you all

kevin94
  • 37
  • 5
  • Static delays are usually just a workaround. You might get better results if you explicitly wait for input being available. Have a look at [`poll`](https://www.man7.org/linux/man-pages/man2/poll.2.html) or [`select`](https://www.man7.org/linux/man-pages/man2/select.2.html) functions for potentially better choices. – Aconcagua Jun 13 '21 at 13:06