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)
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;
}
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
*/
}
How do modify can bitrate in mpc8309 bsp? It is failure when I use ip tool.
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!
-----------------------------------------------------------------------------------------------------------------------