flexcan write failure

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

flexcan write failure

740 Views
dingzhiyu
Contributor I

I use flexcan interface to send multiple frame datas of mpc8309, has small frame data send failure, why? help me,tks.

ps. TXF is 112 , but interrupt number and TX packets is110. 

[root@mpc8309som test]# cat /proc/net/can/stats

112 transmitted frames (TXF)
112 received frames (RXF)
112 matched frames (RXMF)

100 % total match ratio (RXMR)
0 frames/s total tx rate (TXR)
0 frames/s total rx rate (RXR)

100 % current match ratio (CRXMR)
0 frames/s current tx rate (CTXR)
0 frames/s current rx rate (CRXR)

100 % max match ratio (MRXMR)
37 frames/s max tx rate (MTXR)
37 frames/s max rx rate (MRXR)

0 current receive list entries (CRCV)
1 maximum receive list entries (MRCV)

[root@mpc8309som test]# cat /proc/interrupts
CPU0
16: 582 IPIC Level serial
17: 0 IPIC Level mpc8xxx_spi
19: 300 QEIC Level UCC Geth
20: 0 QEIC Level UCC Geth
21: 20 IPIC Level i2c-mpc
22: 3 IPIC Level i2c-mpc
23: 110 IPIC Level can0
34: 0 QEIC Level UCC Geth
38: 0 IPIC Level ehci_hcd:usb1
77: 711 IPIC Level fsl-elbc
LOC: 247908 Local timer interrupts
SPU: 0 Spurious interrupts
CNT: 0 Performance monitoring interrupts
MCE: 0 Machine check exceptions
[root@mpc8309som test]# ifconfig
can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:110 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:64
RX bytes:0 (0.0 b) TX bytes:880 (880.0 b)

0 Kudos
4 Replies

586 Views
dingzhiyu
Contributor I

below is test code :

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <libgen.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
//#include <linux/can.h>
#include <net/if.h>


typedef struct _CAN_S_ /* 发送帧数据缓冲区 */
{
unsigned char dLEN; /* 数据帧长度 */
unsigned char dID1; /* 标示符ID1~ID29 */
unsigned char dID2;
unsigned char dID3;
unsigned char dID4;
unsigned char mydata[8]; /* 数据 */
}stcCAN_S, *P_stcCAN_S;

stcCAN_S CAN_S[50];

#include "can.h"

#define PF_CAN 29

extern int optind, opterr, optopt;

static int skt = -1;

void orgnize_id()
{
int i, j;

CAN_S[0].dID1 = 0x00; // 80050088
CAN_S[0].dID2 = 0x85;
CAN_S[0].dID3 = 0x00;
CAN_S[0].dID4 = 0x08;
CAN_S[0].dLEN = 8;

CAN_S[1].dID1 = 0x80; // 80050088
CAN_S[1].dID2 = 0x05;
CAN_S[1].dID3 = 0x00;
CAN_S[1].dID4 = 0x88;
CAN_S[1].dLEN = 8;

for (i = 2; i < 36; i++)
{
j = i / 2;
CAN_S[i].dLEN = 8;

CAN_S[i].dID1 = 0x80;
CAN_S[i].dID2 = 0x05;
CAN_S[i].dID3 = j;

if (i%2 == 0) {
CAN_S[i].dID4 = 0x08;
}
else {
CAN_S[i].dID4 = 0x88;
}
}

CAN_S[36].dID1 = 0x80;
CAN_S[36].dID2 = 0x85;
CAN_S[36].dID3 = 0x12;
CAN_S[36].dID4 = 0x08;
CAN_S[36].dLEN = 2;
}

void orgnize_data()
{
int i;

CAN_S[0].mydata[0] = 0x20;
CAN_S[0].mydata[1] = 0x01;
CAN_S[0].mydata[2] = 0x05;
CAN_S[0].mydata[3] = 0x01;
CAN_S[0].mydata[4] = 0x00;
CAN_S[0].mydata[5] = 0xE0;
CAN_S[0].mydata[6] = 0x33;
CAN_S[0].mydata[7] = 0x0B;

CAN_S[1].mydata[0] = 0x01;
CAN_S[1].mydata[1] = 0x00;
CAN_S[1].mydata[2] = 0x01;
CAN_S[1].mydata[3] = 0x00;
CAN_S[1].mydata[4] = 0x00;
CAN_S[1].mydata[5] = 0x02;
CAN_S[1].mydata[6] = 0x12;
CAN_S[1].mydata[7] = 0x01;

CAN_S[2].mydata[0] = 0x30;
CAN_S[2].mydata[1] = 0x03;
CAN_S[2].mydata[2] = 0x30;
CAN_S[2].mydata[3] = 0x03;
CAN_S[2].mydata[4] = 0x80;
CAN_S[2].mydata[5] = 0x84;
CAN_S[2].mydata[6] = 0x7D;
CAN_S[2].mydata[7] = 0x00;

CAN_S[3].mydata[0] = 0xFB;
CAN_S[3].mydata[1] = 0x01;
CAN_S[3].mydata[2] = 0x18;
CAN_S[3].mydata[3] = 0x03;
CAN_S[3].mydata[4] = 0xF4;
CAN_S[3].mydata[5] = 0x01;
CAN_S[3].mydata[6] = 0x10;
CAN_S[3].mydata[7] = 0x03;

CAN_S[4].mydata[0] = 0x06;
CAN_S[4].mydata[1] = 0x02;
CAN_S[4].mydata[2] = 0x2B;
CAN_S[4].mydata[3] = 0x03;
CAN_S[4].mydata[4] = 0xF9;
CAN_S[4].mydata[5] = 0x01;
CAN_S[4].mydata[6] = 0x40;
CAN_S[4].mydata[7] = 0x03;

CAN_S[5].mydata[0] = 0xF1;
CAN_S[5].mydata[1] = 0x01;
CAN_S[5].mydata[2] = 0xEF;
CAN_S[5].mydata[3] = 0x02;
CAN_S[5].mydata[4] = 0xFB;
CAN_S[5].mydata[5] = 0x01;
CAN_S[5].mydata[6] = 0xF2;
CAN_S[5].mydata[7] = 0x02;

CAN_S[6].mydata[0] = 0x10;
CAN_S[6].mydata[1] = 0x02;
CAN_S[6].mydata[2] = 0x00;
CAN_S[6].mydata[3] = 0x03;
CAN_S[6].mydata[4] = 0xF9;
CAN_S[6].mydata[5] = 0x01;
CAN_S[6].mydata[6] = 0x2B;
CAN_S[6].mydata[7] = 0x03;

for (i = 7; i < 34; i++)
{
CAN_S[i].mydata[0] = 0x00;
CAN_S[i].mydata[1] = 0x40;
CAN_S[i].mydata[2] = 0x00;
CAN_S[i].mydata[3] = 0x40;
CAN_S[i].mydata[4] = 0x00;
CAN_S[i].mydata[5] = 0x40;
CAN_S[i].mydata[6] = 0x00;
CAN_S[i].mydata[7] = 0x40;
}

CAN_S[34].mydata[0] = 0x00;
CAN_S[34].mydata[1] = 0x40;
CAN_S[34].mydata[2] = 0x00;
CAN_S[34].mydata[3] = 0x00;
CAN_S[34].mydata[4] = 0xFF;
CAN_S[34].mydata[5] = 0xFF;
CAN_S[34].mydata[6] = 0xFF;
CAN_S[34].mydata[7] = 0xFF;

CAN_S[35].mydata[0] = 0xFF;
CAN_S[35].mydata[1] = 0xFF;
CAN_S[35].mydata[2] = 0xFF;
CAN_S[35].mydata[3] = 0xFF;
CAN_S[35].mydata[4] = 0xFF;
CAN_S[35].mydata[5] = 0xFF;
CAN_S[35].mydata[6] = 0xFF;
CAN_S[35].mydata[7] = 0xFF;

CAN_S[36].mydata[0] = 0xFF;
CAN_S[36].mydata[1] = 0xFF;
CAN_S[36].mydata[2] = 0xFF;
CAN_S[36].mydata[3] = 0xFF;
CAN_S[36].mydata[4] = 0x11;
CAN_S[36].mydata[5] = 0x22;
CAN_S[36].mydata[6] = 0x33;
CAN_S[36].mydata[7] = 0x44;
}


void print_usage(char *prg)
{
fprintf(stderr, "Usage: %s [can-interface]\n", prg);
}

void sys_usec_time(int type)
{
struct timeval tv;
struct timezone tz;
struct tm *p;

gettimeofday(&tv, &tz);

p = localtime(&tv.tv_sec);
if (type == 0)
printf("begin time: %d:%d:%d.%ld\n", p->tm_hour, p->tm_min, p->tm_sec, tv.tv_usec);
else
printf("end time: %d:%d:%d.%ld\n", p->tm_hour, p->tm_min, p->tm_sec, tv.tv_usec);

// printf("begin time: %d%d%d_%d:%d:%d.%ld\n", 1900+p->tm_year, 1+p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, tv.tv_usec);
}

void delay_us() // 500ns
{
int i;

for (i = 0; i < 1000; i++)
;
}

int main(int argc, char **argv)
{
int family = PF_CAN, type = SOCK_RAW, proto = CAN_RAW;
int opt;
struct sockaddr_can addr;
struct ifreq ifr;
struct can_frame frame;
struct can_frame rframe;
int nbytes, i;
int verbose = 0;
int can = 5;
int ret = 0;

orgnize_id();
orgnize_data();

if (optind == argc)
{
print_usage(basename(argv[0]));
exit(0);
}

printf("interface = %s, family = PF_CAN, type = SOCK_RAW, proto = CAN_RAW\n", argv[optind]);

if ((skt = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
perror("socket");
return 1;
}

addr.can_family = family;
strcpy(ifr.ifr_name, argv[optind]);
ioctl(skt, SIOCGIFINDEX, &ifr);
addr.can_ifindex = ifr.ifr_ifindex;

// fcntl(fd, F_SETFL, O_NONBLOCK);
if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("bind");
return 1;
}
tcflush(skt, TCIOFLUSH);
sleep(1);
printf("begin send!\n");

//while(1)
{
printf("begin send data: \n");
//sys_usec_time(0);
for (i = 0; i < 37; i++)
{
frame.can_dlc = CAN_S[i].dLEN; // APP_S.mysize;
frame.can_id = (CAN_S[i].dID1<<24) |
(CAN_S[i].dID2<<16) |
(CAN_S[i].dID3<<8) |
(CAN_S[i].dID4);
frame.can_id = (frame.can_id >> 3) | 0x80000000;

memcpy(frame.data, &CAN_S[i].mydata[0], CAN_S[i].dLEN);

ret = write(skt, &frame, sizeof(frame));
// ret = sendto(skt, &frame, sizeof(struct can_frame),
// 0, (struct sockaddr*)&addr, sizeof(addr));
if ( ret < 0){
if (errno == ENOBUFS) {
perror("ENOBUFS");
//goto retry;
} else {
perror("write failed");
// goto failure;
}
}
// delay_us();
// tcflush(skt, TCIOFLUSH);
// usleep(1); //tcflush(skt, TCIOFLUSH); //usleep(1);
}

for (i = 0; i < 37; i++)
{
frame.can_dlc = CAN_S[i].dLEN; // APP_S.mysize;
frame.can_id = (CAN_S[i].dID1<<24) |
(CAN_S[i].dID2<<16) |
(CAN_S[i].dID3<<8) |
(CAN_S[i].dID4);
frame.can_id = (frame.can_id >> 3) | 0x80000000;

memcpy(frame.data, &CAN_S[i].mydata[0], CAN_S[i].dLEN);

ret = write(skt, &frame, sizeof(frame));
// ret = sendto(skt, &frame, sizeof(struct can_frame),
// 0, (struct sockaddr*)&addr, sizeof(addr));
if ( ret < 0){
if (errno == ENOBUFS) {
perror("ENOBUFS");
//goto retry;
} else {
perror("write failed");
// goto failure;
}
}
// delay_us();
// tcflush(skt, TCIOFLUSH);
// usleep(1); //tcflush(skt, TCIOFLUSH); //usleep(1);
}
//tcflush(skt, TCIOFLUSH);
//sys_usec_time(1);
usleep(1000*1000);

printf("i: %d\n", i);

sleep(10);
//tcflush(skt, TCIOFLUSH);
printf("next loop!\n");
// usleep(1000*1000);
}

return 0;
}

0 Kudos

586 Views
dingzhiyu
Contributor I

I find the function is  empty of flexcan_set_bitrate.

static void flexcan_set_bitrate(struct flexcan_device *flexcan, int bitrate)
{
/* TODO:: implement in future
* based on the bitrate to get the timing of
* presdiv, pseg1, pseg2, propseg
*/
}

0 Kudos

586 Views
dingzhiyu
Contributor I

How do modify can bitrate in mpc8309 bsp? It is failure when I use ip tool.

0 Kudos

586 Views
Pavel
NXP Employee
NXP Employee

Look at the following page:

https://www.kernel.org/doc/Documentation/networking/can.txt

 

Linux TX packets are not FlexCAN frames.


Have a great day,
Pavel Chubakov

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos