When trying the CAN Bus sample application for sending data I get the error message:
write() returned with errors, No buffer space available
Has anyone else seen this, if so is there a workaround?
When trying the CAN Bus sample application for sending data I get the error message:
write() returned with errors, No buffer space available
Has anyone else seen this, if so is there a workaround?
Hi David,
I have not checked the sample application but This works for me:
data definition:
//CAN
struct ifreq S_can_ifr;
struct sockaddr_can S_can_addr;
struct can_frame S_can_frame;
int i16_can_socket;
struct can_filter S_can_rx_filter[5];
Initialization routine:
void vfn_Init_CAN()
{
// Preconfigurar can0 en boot de SBC
//ip link set can0 type can bitrate 500000
//ifconfig can0 up
//bit-rate can only be modified when the device is down
//If you type “ifconfig can0” you can see if it is up or down
//The open() callback should return a 0 in case of success or any nonzero value
//in case of failure. The close() callback (which is void) must always succeed.
// The socketCAN version can be retrieved like that:
// # cat /proc/net/can/version
// The socketCAN statistics can be retrieved like that:
// # cat /proc/net/can/stats
memset(&S_can_ifr, 0x0, sizeof(S_can_ifr));
memset(&S_can_addr, 0x0, sizeof(S_can_addr));
memset(&S_can_frame, 0x0, sizeof(S_can_frame));
// open CAN_RAW socket
i16_can_socket = socket(PF_CAN, SOCK_RAW, CAN_RAW);
// convert interface sting "can0" into interface index
strcpy(S_can_ifr.ifr_name, "can0");
ioctl(i16_can_socket, SIOCGIFINDEX, &S_can_ifr);
// setup address for bind
S_can_addr.can_ifindex = S_can_ifr.ifr_ifindex;
S_can_addr.can_family = PF_CAN;
// set baud rate
//S_can_ifr.ifr_ifru.ifru_ivalue = 500000;
//ioctl(i16_can_socket, SIOCSCANBAUDRATE, &S_can_ifr);
S_can_rx_filter[0].can_id = 0x229;
S_can_rx_filter[0].can_mask = CAN_SFF_MASK;
S_can_rx_filter[1].can_id = 0x230;
S_can_rx_filter[1].can_mask = CAN_SFF_MASK;
S_can_rx_filter[2].can_id = 0x231;
S_can_rx_filter[2].can_mask = CAN_SFF_MASK;
S_can_rx_filter[3].can_id = 0x234;
S_can_rx_filter[3].can_mask = CAN_SFF_MASK;
S_can_rx_filter[4].can_id = 0x235;
S_can_rx_filter[4].can_mask = CAN_SFF_MASK;
setsockopt(i16_can_socket, SOL_CAN_RAW, CAN_RAW_FILTER, &S_can_rx_filter, sizeof(S_can_rx_filter));
//To disable the reception of CAN frames on the selected CAN_RAW socket:
//setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
//To set the filters to zero filters is quite obsolete as not read
//data causes the raw socket to discard the received CAN frames. But
//having this 'send only' use-case we may remove the receive list in the
//Kernel to save a little (really a very little!) CPU usage.
// bind socket to the can0 interface
bind(i16_can_socket, (struct sockaddr *)&S_can_addr, sizeof(S_can_addr));
}
void vfn_End_CAN()
{
close(i16_can_socket);
}
I work with two threads: CAN_TX and CAN_RX:
void * vfn_CAN_TX()
{
//while (ui8_sys_state==SM_RUNNING)
//for(ui8_j=0;ui8_j<10;ui8_j++)
while (ui8_sys_state==SM_RUNNING)
{
i16_rtc_fd=open(“/dev/rtc”,O_RDONLY);
ret_val=rtc_time_read(i16_rtc_fd, &rtc_tm);
close(i16_rtc_fd);
printf(“%d-%d-%d, %02d:%02d:%02d
“, rtc_tm.tm_mday, rtc_tm.tm_mon+1, rtc_tm.tm_year+1900, rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
//fprintf(ptr_file_txt,”%d; %d; %d-%d-%d; %02d:%02d:%02d
“, ui8_j, ui8_j+10, rtc_tm.tm_mday, rtc_tm.tm_mon+1, rtc_tm.tm_year+1900, rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
//fprintf(ptr_file_json,”[%d, %d]”,1999+ui8_j,ui8_j/2);
//if (ui8_j<9)
//{
//fprintf(ptr_file_json,", ");
//}
// first fill, then send the CAN frame
S_can_frame.can_id = 0x215;
S_can_frame.can_dlc = 8;
S_can_frame.data[0]=(char)rtc_tm.tm_mday;
S_can_frame.data[1]=(char)(rtc_tm.tm_mon+1);
S_can_frame.data[2]=(char)(rtc_tm.tm_year+1900-2000);
S_can_frame.data[3]=(char)rtc_tm.tm_hour;
S_can_frame.data[4]=(char)rtc_tm.tm_min;
S_can_frame.data[5]=(char)rtc_tm.tm_sec;
S_can_frame.data[6]=0;
S_can_frame.data[7]=0;
write(i16_can_socket,&S_can_frame,sizeof(S_can_frame));
//usleep(250000); //0.25s
sleep(1);
}
}
void * vfn_CAN_RX()
{
//for(ui8_k=0;ui8_k<20;ui8_k++)
//while (ui8_sys_state==SM_RUNNING)
while (ui8_sys_state==SM_RUNNING)
{
// Read messages from the CAN bus
// Filters set at S_can_rx_filter
read(i16_can_socket,&S_can_frame,sizeof(S_can_frame));
switch(S_can_frame.can_id)
{
case 0x235: //RTC_DATA_CFG
{
// tm->tm_mday = 26; //26
// tm->tm_mon = 2 -1; //feb
// tm->tm_year = 2010 -1900; //2010
// tm->tm_hour = 7;
// tm->tm_min = 33;
// tm->tm_sec = 55;
printf("CAN ID 0x235 -> RTC_DATA_CFG
");
// read configuration data
rtc_tm.tm_mday=S_can_frame.data[0];
rtc_tm.tm_mon=S_can_frame.data[1]-1;
rtc_tm.tm_year=2000+S_can_frame.data[2]-1900;
rtc_tm.tm_hour=S_can_frame.data[3];
rtc_tm.tm_min=S_can_frame.data[4];
rtc_tm.tm_sec=S_can_frame.data[5];
i16_rtc_fd=open("/dev/rtc",O_RDONLY);
rtc_time_set(i16_rtc_fd, &rtc_tm);
close(i16_rtc_fd);
}
break;
case 0x234: //STOP
{
printf("CAN ID 0x234 -> STOP
");
ui8_sys_state=SM_STOP;
}
break;
default:
{
// Any other id which is defined in S_can_rx_filter
//printf("ID%X
",S_can_frame.can_id);
}
break;
}
sleep(1);
}
}
Good luck!
alvaro