| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650 |
- /******************************************************************************
- 版权所有:
- 文件名称: flexcan.c
- 文件版本: 01.01
- 创建作者: sunxi
- 创建日期: 2025-09-28
- 功能说明: FLEXCAN驱动
- 其它说明:
- 修改记录:
- */
- /*------------------------------- 头文件 --------------------------------------
- */
- #include "bspconfig.h"
- #include "rt_printf.h"
- #include "ustimer.h"
- #include "rt.h"
- #include "flexcan.h"
- #include <string.h>
- #include <sys/mman.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <linux/can.h>
- #include <linux/can/raw.h>
- #include <sys/prctl.h>
- #include <unistd.h>
- #ifdef BSP_CAN_ENABLE
-
- /*------------------------------- 宏定义 --------------------------------------
- */
- #define CAN_FIFO
- // 优先级
- #define CAN_PRIO_MAX 4
- // 短帧BUF
- #define CAN_FRAME_NUM 256 // CAN短帧BUF数量
- #define CAN_FRAME_LEN 16 // CAN短帧BUF长度
- #define CAN_FRAME_HEAD_LEN 8 // CAN短帧帧头长度
- #define CAN_FRAME_DATA_LEN 8 // CAN短帧数据长度
- // 长帧BUF
- #define CAN_LONGFRAME_NUM 16 // CAN长帧BUF数量
- #define CAN_LONGFRAME_LEN CAN_FRAME_LEN_MAX // CAN长帧BUF长度
- #define CAN_LONGFRAME_HEAD_LEN 4 // CAN长帧头长度
- #define CAN_LONGFRAME_DATA_LEN (CAN_LONGFRAME_LEN-CAN_LONGFRAME_HEAD_LEN) // CAN长帧数据长度
- // 帧标志,数字越小,优先级越高
- #define CAN_FRAME_SINGLE 0 // 单帧(既是起始帧,又是结束帧)
- #define CAN_FRAME_END 1 // 结束帧
- #define CAN_FRAME_MIDDLE 2 // 中间帧
- #define CAN_FRAME_BEGIN 3 // 开始帧
- //帧ID中各个域的位偏移
- #define CAN_FRAME_OFFSET_SN 0 // 帧序号偏移
- #define CAN_FRAME_OFFSET_MARK 6 // 帧标志偏移
- #define CAN_FRAME_OFFSET_SRC 8 // 帧源地址偏移
- #define CAN_FRAME_OFFSET_DST 12 // 帧目的地址偏移
- #define CAN_FRAME_OFFSET_TYPE 16 // 帧类型偏移
- #define CAN_FRAME_OFFSET_PRIOR 23 // 帧优先级偏移(帧优先级是帧类型的高2位)
- #define CAN_FRAME_OFFSET_LEN 16 // 帧长度偏移
- #define CAN_FRAME_MASK_SN 0X3F // 帧序号屏蔽位
- #define CAN_FRAME_MASK_MARK 0X03 // 帧标志屏蔽位
- #define CAN_FRAME_MASK_SRC 0X0F // 帧源地址屏蔽位
- #define CAN_FRAME_MASK_DST 0X0F // 帧目的地址屏蔽位
- #define CAN_FRAME_MASK_TYPE 0XFF // 帧类型屏蔽位
- #define CAN_FRAME_MASK_PRIOR 0X03 // 帧优先级屏蔽位(帧优先级是帧类型的高2位)
- #define CAN_FRAME_MASK_LEN 0X0F // 帧长度屏蔽位
- //缓冲区为空
- #define CAN_BUF_EMPTY(ring) ((ring)->head == (ring)->tail)
- //缓冲区满
- #define CAN_BUF_FULL(ring, size) (((unsigned char)((ring)->head - (ring)->tail))==((unsigned char)(size-1)))
- //缓冲区剩余空间
- #define CAN_BUF_SPACE(ring, size) (((unsigned char)((ring)->tail - (ring)->head) -1) & (unsigned char)(size-1))
- //强制中断寄存器
- #define REG_MCF_INTFRCL1 (*( volatile unsigned int*)(0xFC04C014))
- // 调试开关
- // #define CAN_DEBUG
- #ifdef CAN_DEBUG
- # define can_printf(x...) rt_printf(x)
- #else
- # define can_printf(x...)
- #endif
- // 打印报文
- #ifdef CAN_DEBUG
- # define can_print_mem(x...) print_mem_time(x)
- #else
- # define can_print_mem(x...)
- #endif
- /*------------------------------ 类型结构 -------------------------------------
- */
- typedef enum
- {
- CAN_1,
- CAN_2,
- CAN_RES
- }can_type;
- //CANFD 基地址
- static unsigned int g_rt_canfd_baseaddr[RT_CAN_NUM][RT_CAN_DEV_TYPE]=
- {
- {RT_M_CAN0, RT_M_RAM0, RT_M_TOP0, RT_M_DMA0},
- {RT_M_CAN1, RT_M_RAM1, RT_M_TOP1, RT_M_DMA1},
- {RT_M_CAN2, RT_M_RAM2, RT_M_TOP2, RT_M_DMA2},
- {RT_M_CAN3, RT_M_RAM3, RT_M_TOP3, RT_M_DMA3},
- };
- // 保证所有结构的大小都是4的倍数
- //长帧缓冲区
- struct can_longframe_buf
- {
- unsigned char head;//头位置
- unsigned char tail;//尾位置
- unsigned char reserverd[2];
- unsigned char buf[CAN_LONGFRAME_NUM][CAN_LONGFRAME_LEN];
- };
- //缓冲区描述符
- struct can_buf
- {
- unsigned char head; //头位置
- unsigned char tail; //尾位置
- unsigned char frameno; //帧序号
- unsigned char reserverd;
- unsigned char buf[CAN_FRAME_NUM][CAN_FRAME_LEN];
- };
- //CAN统计信息数据结构
- struct can_dev_stats{
- uint32_t rx_shortframes; //接收短帧数
- uint32_t tx_shortframes; //发送短帧数
- uint32_t rx_longframes; //接收长帧数
- uint32_t tx_longframes; //发送长帧数
- uint32_t rx_dropped; //接收缓冲区满溢出次数
- uint32_t tx_dropped; //发送缓冲区满溢出次数
- uint32_t hw_bus_errors;
- uint32_t overrun;
- uint32_t max_mbcnt; //统计最大的未处理的MB个数
- uint32_t max_proctime; //处理MB的最大时间
- };
- #if 0
- //短帧描述符
- struct can_shortframe_des
- {
- unsigned char info;
- unsigned char flag1;
- unsigned char srcaddr;
- unsigned char dstaddr;
- unsigned char frameno;
- unsigned char data[8];
- unsigned char reserved[3];
- };
- #endif
- //时间戳差值数据结构
- struct can_timestamp
- {
- unsigned short timestamp; //时间戳差值,该差值是指当前时间戳与有数据的MB的时间戳差值
- short caniflg_bit; //MB下标即是那一个MB
- };
- //flexcan 设备数据结构
- struct can_dev
- {
- int can_sock;
- uint32_t no;
- uint32_t base_addr;
-
- struct can_dev_stats stats; //网络统计信息
-
- struct can_timestamp ts[CAN_MB]; //记录各时间戳差值
- struct can_buf tx_buf[CAN_PRIO_MAX]; //发送缓冲区
- struct can_buf rx_buf[CAN_PRIO_MAX]; //接收缓冲区
- struct can_longframe_buf longframe_buf_rx[CAN_PRIO_MAX]; //接收长帧缓冲区
- };
- /* Message type access macros.*/
- #define FLEXCAN_SET_MODE_RETRIES 255
- /* Message Buffer 0 configure as Tx */
- #define SEND_BUF 15
- #define SEND_BUF_BIT (1<<SEND_BUF)
- /* Structure of the message buffer */
- struct can_mb
- {
- volatile u32 can_dlc;
- volatile u32 can_id;
- u8 data[8];
- };
- struct can_regs
- {
- volatile u32 canmcr; /* FLEXCAN 0x00 */
- volatile u32 canctrl; /* FLEXCAN 0x04 */
- volatile u32 cantimer; /* FLEXCAN 0x08 */
- volatile u32 reserved1;
- volatile u32 canrxgmsk; /* FLEXCAN 0x10 */
- volatile u32 canrx14msk; /* FLEXCAN 0x14 */
- volatile u32 canrx15msk; /* FLEXCAN 0x18 */
- volatile u32 canerrcnt; /* FLEXCAN 0x1C */
- volatile u32 canerrstat; /* FLEXCAN 0x20 */
- volatile u32 reserved2;
- volatile u32 canimask; /* FLEXCAN 0x28 */
- volatile u32 reserved3;
- volatile u32 caniflg; /* FLEXCAN 0x30 */
- volatile u32 reserved4[19];
- struct can_mb cantxfg[CAN_MB];
- volatile u32 reserved5[448];
- volatile u32 rximr[CAN_MB];
- };
- /* @clock_src:
- 1 = The FLEXCAN clock source is the onchip Bus Clock.
- 0 = The FLEXCAN clock source is the chip Oscillator Clock.*/
- struct can_platform_data
- {
- unsigned int clock_src; /* FLEXCAN_CLKSRC_BUS or FLEXCAN_CLKSRC_XTAL */
- unsigned int clock_frq; /* can ref. clock, in Hz */
- };
- /*------------------------------ 全局变量 -------------------------------------
- */
- //flexcan设备
- int g_can_fd = -1;
- static int bexit = 0;
- static u8 g_can_tx_call[CAN_BUS_NUM] = {0};
- pthread_t can_tid[CAN_BUS_NUM];
- pthread_t can_tid_s[CAN_BUS_NUM];
- unsigned g_can_mapped_size;
- void *g_can_map_base[CAN_BUS_NUM], *g_can_virt_addr[CAN_BUS_NUM];
- static struct can_dev g_can_dev[CAN_BUS_NUM] __attribute__ ((aligned(4)));
- FN_CAN_RECV_CALLBACK g_can_recv_callback;
- u8 g_app_buf_tx[CAN_PRIO_MAX][CAN_FRAME_LEN_MAX]; //应用可根据优先级申请的长帧缓冲区
- static pthread_mutex_t printf_mutex;
- extern int g_print_can;
- extern int g_print_can_monitor;
- /*------------------------------ 函数声明 -------------------------------------
- */
- static void can_soft_recv_data(int sock);
- static int _can_set_reset_mode(struct can_dev *dev);
- static int _can_set_normal_mode(struct can_dev *dev);
- static int _can_set_bittiming(struct can_dev *dev);
- static void _can_chipset_init(struct can_dev *dev, int clock_src);
- static void _can_app_tx(int _no);
- static void _can_app_rx(struct can_dev *dev, struct can_frame *frame);
- void _can_isr_0(void);
- void _can_isr_1(void);
- void _can_isr_err_0(void);
- void _can_isr_err_1(void);
- int _can_irq_force(int no);
- int _can_irq_clear(int no);
- int _can_irq_is_force(int no);
- /*------------------------------ 内部函数 -------------------------------------
- */
- static int can_soft_send(int sock, struct can_frame frame)
- {
- int nbytes;
- int wlen = sizeof(struct can_frame);
- int times = 2;
- while(times --)
- {
- nbytes = write(sock, &frame, wlen);
- if (nbytes != wlen)
- {
- // rt_printf("Send Error frame(nbytes:%d, wlen:%d)\n", nbytes, wlen);
- usleep(200);
- continue;
- }
- else
- {
- //printf("Send frame(nbytes:%d, wlen:%d)\n", nbytes, wlen);
- return (0);
- }
- }
- return -1;
- }
- static int can_send_data(can_type type, unsigned char *buf, int len)
- {
- int i, j;
- int cnt;
- int sock;
- int ret = 0;
- struct can_frame frame;
- if(type == CAN_1)
- {
- // DEMO
- sock = g_can_dev[0].can_sock;
- frame.can_id = 0x100;
- }
- else {
- // DEMO
- sock = g_can_dev[1].can_sock;
- frame.can_id = 0x101;
- }
- for(i = 0; i < len; i += 8)
- {
- cnt = len - i;
- if(cnt > 8)
- frame.can_dlc = 8;
- else
- frame.can_dlc = cnt;
- for(j=0; j<frame.can_dlc; j++)
- {
- frame.data[j] = buf[i+j];
- }
- if(can_soft_send(sock, frame) < 0)
- {
- ret = -1;
- break;
- }
- }
- return ret;
- }
- static void *can_proc_send(void *arg)
- {
- int sock = *(int *)arg;
- int index = g_can_dev[0].can_sock == sock ? 0 : 1;
- if (index == 0) {
- prctl(PR_SET_NAME, "can_send_func0");
- } else {
- prctl(PR_SET_NAME, "can_send_func1");
- }
- while(!bexit)
- {
- if(main_mod_is_exit())
- {
- break;
- }
- switch (index) {
- case 0:
- // can_send_data(CAN_1, (unsigned char *)"hello stm32", strlen("hello stm32") - 1);
- _can_app_tx(0);
- break;
- case 1:
- _can_app_tx(1);
- // can_send_data(CAN_2, (unsigned char *)"hello stm32", strlen("hello stm32") - 1);
- break;
- default:
- break;
- }
- // xenomai内核中此处usleep(10)创建第二个线程会出问题
- // 延时太短导致CPU占用?改为1ms就正常了需验证动作时间
- usleep(1000);
- }
- }
- static void *can_proc_recv(void *arg)
- {
- int nready;
- int maxfd;
- fd_set readfds;
- int sock = *(int *)arg;
- FD_ZERO(&readfds);
- FD_SET(sock, &readfds);
- maxfd = sock;
- int index = g_can_dev[0].can_sock == sock ? 0 : 1;
- if (index == 0) {
- prctl(PR_SET_NAME, "can_rev_func0");
- } else {
- prctl(PR_SET_NAME, "can_rev_func1");
- }
-
- while(!bexit)
- {
- if(main_mod_is_exit())
- {
- break;
- }
- nready = select(maxfd+1, &readfds, NULL, NULL, NULL);
- if(nready < 0)
- {
- perror("can select");
- break;
- }
- else if(nready == 0)
- {
- continue;
- }
- /* data is ready */
- if(FD_ISSET(sock, &readfds))
- {
- can_soft_recv_data(sock);
- }
- else { ; }
- }
- }
- static int can_open(char *can_name)
- {
- struct ifreq ifr;
- struct sockaddr_can addr;
- int sock;
- int ret = -1;
- int loopback = 0;
- // struct can_filter rfilter[1];
-
- /* open socket */
- sock = socket(PF_CAN, SOCK_RAW, CAN_RAW);
- if(sock < 0)
- {
- return ret;
- }
-
- strcpy(ifr.ifr_name, can_name);
- if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0)
- {
- goto err_can_open;
- }
- addr.can_family = AF_CAN;
- addr.can_ifindex = ifr.ifr_ifindex;
- // fcntl(sock, F_SETFL, O_NONBLOCK);
- if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
- {
- goto err_can_open;
- }
- //close loopback
- setsockopt(sock, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback));
- /*
- rfilter[0].can_id = 0x12;
- rfilter[0].can_mask = CAN_SFF_MASK;
- setsockopt(sock, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
- */
- return sock;
- err_can_open:
- close(sock);
- return ret;
- }
- static int can_soft_recv(int sock, struct can_frame *frame)
- {
- int nbytes;
- nbytes = read(sock, frame, sizeof(struct can_frame));
- if(nbytes)
- {
- ;//printf("[can_recv]dlc = %d, nbytes = %d\n", frame->can_dlc, nbytes);
- }
- return nbytes;
- }
- static void can_soft_recv_data(int sock)
- {
- static unsigned char tail = 0;
- int i;
- int can_id;
- unsigned char can_dlc;
- unsigned char *data;
- struct can_frame frame;
- int index = g_can_dev[0].can_sock == sock ? 0 : 1;
- if(can_soft_recv(sock, &frame) < 0)
- return ;
- frame.can_id = frame.can_id&CAN_EFF_MASK;
- can_dlc = frame.can_dlc;
- data = frame.data;
- // printf("CAN%d dlc = %d, can_id = %x\ndata:", index,frame.can_dlc, frame.can_id);
- // for(i=0; i<frame.can_dlc; i++)
- // printf("0x%02x ", frame.data[i]);
- // printf("\n");
- _can_app_rx(&g_can_dev[index],&frame);
- }
- /*------------------------------ 外部函数 -------------------------------------
- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
- */
- int can_init(void)
- {
- struct can_dev *dev;
- int i;
- off_t target;
- unsigned page_size, offset_in_page;
- unsigned width = 8 * sizeof(int);
- g_can_mapped_size = page_size = sysconf(_SC_PAGESIZE);
- offset_in_page = (unsigned)target & (page_size - 1);
- if (offset_in_page + width > page_size) {
- /* This access spans pages.
- * Must map two pages to make it possible: */
- g_can_mapped_size *= 2;
- }
- g_can_fd = open("/dev/mem", O_RDWR | O_SYNC);
- if (g_can_fd < 0)
- {
- printf("open(/dev/mem) failed.\n");
- return -1;
- }
- fflush(stdout);
- pthread_mutex_init(&printf_mutex, NULL);
- //初始化缓冲区
- memset(g_can_dev,0,sizeof(g_can_dev));
-
- for(i=0; i<CAN_BUS_NUM; i++)
- {
- dev = &g_can_dev[i];
- dev->no = i;
- target = g_rt_canfd_baseaddr[i][0];
- if(i==0)
- {
- /* CAN0 */
- g_can_map_base[i] = mmap (NULL, g_can_mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, g_can_fd, target & ~(off_t)(page_size - 1));
- if (g_can_map_base[i] == (void *)-1)
- {
- printf ("can[%d] dev null pointer!\n", i);
- }
- else
- {
- printf ("BSP can[%d] map Successfull!\n", i);
- }
- fflush(stdout);
-
- dev->base_addr = g_can_map_base[i];
-
- }
- else
- {
- /* CAN1 */
- g_can_map_base[i] = mmap (NULL, g_can_mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, g_can_fd, target & ~(off_t)(page_size - 1));
- if (g_can_map_base[i] == (void *)-1)
- {
- printf ("can[%d] dev null pointer!\n", i);
- }
- else
- {
- printf ("BSP can[%d] map Successfull!\n", i);
- }
- fflush(stdout);
-
- dev->base_addr = g_can_map_base[i];
-
- }
-
- /* set chip into reset mode */
- _can_set_reset_mode(dev);
- _can_set_bittiming(dev);
- // 申请实时中断
- if(i == 0)
- {
- rt_request_irq(CFG_CAN_VECTOR_BEGIN + 0,CFG_INT_LEVEL_CAN,_can_isr_0,"can_isr_0");
- rt_request_irq(CFG_CAN_VECTOR_BEGIN + 1,CFG_INT_LEVEL_CAN,_can_isr_err_0,"can_isr_err_00");
- rt_request_irq(CFG_CAN_VECTOR_BEGIN + 3,CFG_INT_LEVEL_CAN,_can_isr_err_0,"can_isr_err_01");
- }
- else
- {
- rt_request_irq(CFG_CAN_VECTOR_BEGIN + 4,CFG_INT_LEVEL_CAN,_can_isr_1,"can_isr_1");
- rt_request_irq(CFG_CAN_VECTOR_BEGIN + 5,CFG_INT_LEVEL_CAN,_can_isr_err_1,"can_isr_err_10");
- rt_request_irq(CFG_CAN_VECTOR_BEGIN + 7,CFG_INT_LEVEL_CAN,_can_isr_err_1,"can_isr_err_11");
- }
- // 获取CAN设备句柄
- if (i == 0) {
- g_can_dev[i].can_sock = can_open("can0");
- } else {
- g_can_dev[i].can_sock = can_open("can1");
- }
- // 创建CAN设备接收线程
- if (0 != pthread_create(&can_tid[i], NULL, can_proc_recv, (void *)&g_can_dev[i].can_sock))
- {
- return -2;
- }
- // 创建CAN设备发送线程
- if (0 != pthread_create(&can_tid_s[i], NULL, can_proc_send, (void *)&g_can_dev[i].can_sock))
- {
- return -3;
- }
- /* init and start flexcan */
- _can_chipset_init(dev, 0);
- _can_set_normal_mode(dev);
- }
- return 0;
- }
- int can_exit(void)
- {
- int i = 0;
- // exit can recv thread
- bexit = 1;
- for (i = 0; i < CAN_BUS_NUM; i++) {
- pthread_join(can_tid[i], NULL);
- pthread_join(can_tid_s[i], NULL);
- if (g_can_map_base[i]) {
- if (munmap(g_can_map_base, g_can_mapped_size) == -1) {
- printf("can[%d] dev munmap failed!", i);
- return -1;
- }
- }
- if (g_can_dev[i].can_sock >= 0) {
- close(g_can_dev[i].can_sock);
- }
- }
- if (g_can_fd >= 0)
- {
- close(g_can_fd);
- g_can_fd = -1;
- }
-
- rt_free_irq(CFG_CAN_VECTOR_BEGIN + 0);
- rt_free_irq(CFG_CAN_VECTOR_BEGIN + 1);
- rt_free_irq(CFG_CAN_VECTOR_BEGIN + 3);
- rt_free_irq(CFG_CAN_VECTOR_BEGIN + 4);
- rt_free_irq(CFG_CAN_VECTOR_BEGIN + 5);
- rt_free_irq(CFG_CAN_VECTOR_BEGIN + 7);
- pthread_mutex_destroy(&printf_mutex);
-
- return 0;
- }
- int can_regester_recv_callback(FN_CAN_RECV_CALLBACK fn)
- {
- g_can_recv_callback = fn;
- return 0;
- }
- u8 * can_request_tx_buf(u8 type)
- {
- int prior;
-
- //提取优先级
- prior=(type >> 6 ) & CAN_FRAME_MASK_PRIOR;
- return g_app_buf_tx[prior];
- }
- int can_send(u32 no,u8 *buf)
- {
- struct can_dev *dev;
- struct can_mb *pfm;
-
- int i,sf_num,sf_len ;
- int frame_mark; // 帧标识
- unsigned char prior; //应用优先级
- unsigned char *p;
- u32 len;
- // 检查参数
- if(no >= CAN_BUS_NUM)
- {
- return -1;
- }
- if(buf == NULL)
- {
- return -2;
- }
- // 检查地址
- if(buf[1]>= CAN_BUS_ADDR_NUM || buf[2] >= CAN_BUS_ADDR_NUM)
- {
- return -5;
- }
- // 检查长度
- len = buf[3];
- if(len > CAN_LONGFRAME_DATA_LEN)
- {
- return -6;
- }
- dev = &g_can_dev[no];
-
- //提取优先级
- prior=(buf[0] >> 6 ) & CAN_FRAME_MASK_PRIOR;
- // 将长帧转换为短帧
- //计算需要分为多少帧短帧
- sf_num=(len + CAN_FRAME_DATA_LEN - 1)/CAN_FRAME_DATA_LEN;
- if(sf_num == 0)
- {
- sf_num = 1;
- }
-
- //空间够吗?
- if(CAN_BUF_SPACE(&dev->tx_buf[prior], CAN_FRAME_NUM) < sf_num)
- {
- //发送溢出次数
- dev->stats.tx_dropped++;
- return -7;
- }
- // 打印报文
- if(g_print_can)
- {
- print_msg("TX_CAN:",buf,len+CAN_LONGFRAME_HEAD_LEN);
- }
-
- //帧序号递加
- dev->tx_buf[prior].frameno++;
- i=0;
- p= buf + CAN_LONGFRAME_HEAD_LEN;
- while(i<sf_num)
- {
- // 短帧数据长度
- sf_len = len>=CAN_FRAME_DATA_LEN?CAN_FRAME_DATA_LEN:len;
- // 帧标识
- if(sf_num == 1)
- {
- frame_mark = CAN_FRAME_SINGLE;
- }
- else
- {
- if(i == 0)
- {
- frame_mark = CAN_FRAME_BEGIN;
- }
- else if(i == (sf_num - 1))
- {
- frame_mark = CAN_FRAME_END ;
- }
- else
- {
- frame_mark = CAN_FRAME_MIDDLE;
- }
- }
-
- //指向当前头位置缓冲区
- pfm=(struct can_mb *)dev->tx_buf[prior].buf[dev->tx_buf[prior].head];
-
- //结构信息
- pfm->can_dlc=sf_len;//MB_CNT_CODE(0x08)|(1 << 21)|(1 << 22)|(sf_len << 16)
- // 帧ID
- pfm->can_id= (buf[0] << CAN_FRAME_OFFSET_TYPE)
- | (buf[1] << CAN_FRAME_OFFSET_DST)
- | (buf[2] << CAN_FRAME_OFFSET_SRC)
- | (frame_mark << CAN_FRAME_OFFSET_MARK)
- | (dev->tx_buf[prior].frameno & CAN_FRAME_MASK_SN);
- // 数据
- memcpy(pfm->data, p, sf_len);
- len -= sf_len; //剩余多少数据
- p += sf_len; //调整数据指针
- //头下标往后移
- dev->tx_buf[prior].head++;
-
- //下一短帧
- i++;
- }
- //统计发送长帧
- dev->stats.tx_longframes++;
- // 启动发送
- _can_irq_force(no);
- return (buf[3] + CAN_LONGFRAME_HEAD_LEN);
- }
- int can_recv(u32 no,u8 *buf,u32 len)
- {
- struct can_dev *dev;
- int i;
- int framelen;
- // 检查参数
- if(no >= CAN_BUS_NUM)
- {
- return -1;
- }
- if(buf == NULL)
- {
- return -2;
- }
- dev = &g_can_dev[no];
-
- //从0优先级开始,读取接收缓冲区的数据
- for(i=0;i<CAN_PRIO_MAX;i++)
- {
- //对应的长帧缓冲区没有长帧
- if(CAN_BUF_EMPTY(&dev->longframe_buf_rx[i]))
- continue;
-
- //长帧长度
- framelen=dev->longframe_buf_rx[i].buf[dev->longframe_buf_rx[i].tail][CAN_LONGFRAME_HEAD_LEN - 1] + CAN_LONGFRAME_HEAD_LEN;
- //拷贝数据到用户空间
- if(framelen <= len)
- {
- memcpy(buf, dev->longframe_buf_rx[i].buf[dev->longframe_buf_rx[i].tail], framelen);
-
- //调整尾位置
- dev->longframe_buf_rx[i].tail = (dev->longframe_buf_rx[i].tail+1) & (CAN_LONGFRAME_NUM-1);
- }
- else
- {
- rt_printf("can_recv:framelen=%d, len=%d\r\n",framelen,len);
- framelen=-3;
- }
-
- return framelen;
- }
-
- return 0;
- }
- int can_stat(void)
- {
- int i=0;
-
- rt_printf("flexcan communicate stat\r\n");
- for(i=0;i<CAN_BUS_NUM;i++)
- {
- rt_printf("flexcan%d:\r\n",i);
- rt_printf("tx_longframes:\t%u\r\n",g_can_dev[i].stats.tx_longframes);
- rt_printf("rx_longframes:\t%u\r\n",g_can_dev[i].stats.rx_longframes);
- rt_printf("tx_shortframes:\t%u\r\n",g_can_dev[i].stats.tx_shortframes);
- rt_printf("rx_shortframes:\t%u\r\n",g_can_dev[i].stats.rx_shortframes);
- rt_printf("tx_dropped:\t%u\r\n",g_can_dev[i].stats.tx_dropped);
- rt_printf("rx_dropped:\t%u\r\n",g_can_dev[i].stats.rx_dropped);
- rt_printf("hw_bus_errors:\t%u\r\n",g_can_dev[i].stats.hw_bus_errors);
- rt_printf("overrun:\t%u\r\n",g_can_dev[i].stats.overrun);
- }
-
- return 0;
-
- }
- int can_stat_reset(void)
- {
- int i=0;
-
- for(i=0;i<CAN_BUS_NUM;i++)
- {
- memset(&g_can_dev[i].stats,0,sizeof(g_can_dev[i].stats));
- }
- return 0;
- }
- /*------------------------------ 内部函数 -------------------------------------
- 内部函数以下划线‘_’开头,不需要检查参数的合法性.
- */
- /******************************************************************************
- 函数名称: _can_set_reset_mode
- 函数版本: 01.01
- 创建作者: xxxxxx
- 创建日期: 2010-09-25
- 函数说明: 复位FLEXCAN
- 参数说明:
- dev: flexcan 设备
-
- 返回值:成功返回0,失败返回1
- 修改记录:
- */
- static int _can_set_reset_mode(struct can_dev *dev)
- {
- // TODO: ocean
- return 1;
- }
- /******************************************************************************
- 函数名称: _can_set_normal_mode
- 函数版本: 01.01
- 创建作者: xxxxxx
- 创建日期: 2010-09-25
- 函数说明: 设置正常模式
- 参数说明:
- dev: flexcan 设备
-
- 返回值:成功返回0,失败返回1
- 修改记录:
- */
- static int _can_set_normal_mode(struct can_dev *dev)
- {
- // TODO: ocean
-
- return 1;
- }
- /******************************************************************************
- 函数名称: _can_set_bittiming
- 函数版本: 01.01
- 创建作者: xxxxxx
- 创建日期: 2010-09-25
- 函数说明: 波特率设置函数
- 使用外部晶振50M
- 配置为500K:
- reg = CANCTRL_PRESDIV(9) | CANCTRL_RJW(0);
- reg |= (CANCTRL_PROPSEG(2) |
- CANCTRL_PSEG1(3) |
- CANCTRL_PSEG2(1) |
- CANCTRL_SAMP(0));
- regs->canctrl |= reg;
- 配置为1M:
- reg = CANCTRL_PRESDIV(4) | CANCTRL_RJW(0);
- reg |= (CANCTRL_PROPSEG(3) |
- CANCTRL_PSEG1(2) |
- CANCTRL_PSEG2(1) |
- CANCTRL_SAMP(0));
- regs->canctrl |= reg;
- 参数说明:
- dev: flexcan 设备
-
- 返回值: 返回0
- 修改记录:
- */
- static int _can_set_bittiming(struct can_dev *dev)
- {
- /* Clear the old bittiming */
- char cmd_buf[256] = {0x00};
- sprintf(cmd_buf, "ip link set can%d down", dev->no);
- system(cmd_buf);
- /* 设置队列宽度 */
- memset(cmd_buf, 0, sizeof(cmd_buf));
- sprintf(cmd_buf, "ip link set can%d qlen %d", dev->no, 100);
- system(cmd_buf);
- /* 配置波特率为1M */
- memset(cmd_buf, 0, sizeof(cmd_buf));
- sprintf(cmd_buf, "ip link set can%d type can bitrate %d loopback off restart-ms %d", dev->no, 1000000, 100);
- system(cmd_buf);
- /* 启动can设备 */
- memset(cmd_buf, 0, sizeof(cmd_buf));
- sprintf(cmd_buf, "ip link set can%d up", dev->no);
- system(cmd_buf);
- return 0;
- }
- /******************************************************************************
- 函数名称: _can_chipset_init
- 函数版本: 01.01
- 创建作者: xxxxxx
- 创建日期: 2010-09-25
- 函数说明: 初始化flexcan
- 参数说明:
- dev: flexcan 设备
- clock_src: 时钟源,0表示外部晶振,1表示内部总线时钟
-
- 返回值:
- 修改记录:
- */
- /*
- * initialize flexcan:
- * - set clock source
- * - set output mode
- * - set baudrate
- * - enable interrupts
- * - start operating mode
- */
- static void _can_chipset_init(struct can_dev *dev, int clock_src)
- {
- }
- static void _can_app_tx(int _no)
- {
- int sock;
- int i=0;
- struct can_mb *pfm;
- struct can_frame frame;
- struct can_dev *dev = &g_can_dev[_no];
- // if(g_can_tx_call[_no] == 0)
- // return;
-
- // g_can_tx_call[_no] = 0;
- for(i=0;i<CAN_PRIO_MAX;i++)
- {
- //对应优先级的缓冲区是否有数据
- if(CAN_BUF_EMPTY(&dev->tx_buf[i]))
- {
- continue;
- }
- //当前位置的缓冲区
- pfm=(struct can_mb *)dev->tx_buf[i].buf[dev->tx_buf[i].tail];
- frame.can_id = pfm->can_id|CAN_EFF_FLAG; // 使用扩展帧ID
- frame.can_dlc = pfm->can_dlc;
- memcpy(frame.data,pfm->data,sizeof(frame.data));
- sock = g_can_dev[_no].can_sock;
- if(can_soft_send(sock, frame) < 0)
- {
- rt_printf("%s send err!\r\n", __func__);
- break;
- }
- //调整尾指针
- dev->tx_buf[i].tail++;
-
- //统计发送短帧总数加一
- dev->stats.tx_shortframes++;
- }
- }
- /******************************************************************************
- 函数名称: _can_int_tx
- 函数版本: 01.01
- 创建作者: xxxxxx
- 创建日期: 2010-09-25
- 函数说明: flexcan发送处理
- 参数说明:
- dev: flexcan 设备
-
- 返回值:
- 修改记录:
- */
- static void _can_int_tx(struct can_dev *dev)
- {
- int i=0;
- struct can_mb *pfm;
- int txbuf = SEND_BUF;
- volatile struct can_regs *regs = (volatile struct can_regs *)dev->base_addr;
-
- for(i=0;i<CAN_PRIO_MAX;i++)
- {
- int j=0;
- unsigned int code=0;
-
- //对应优先级的缓冲区是否有数据
- if(CAN_BUF_EMPTY(&dev->tx_buf[i]))
- {
- continue;
- }
-
- //当前位置的缓冲区
- pfm=(struct can_mb *)dev->tx_buf[i].buf[dev->tx_buf[i].tail];
-
- //检查是否可以发送. code==8说明上一次成功发送完毕,code==0是第一次将CODE配置0了即是MB_CNT_CODE(0)
- code= (regs->cantxfg[txbuf].can_dlc >> 24) & 0x0F;
- if(!((code==8) || (code==0)))
- {
- //rt_printf("bus is busy\r\n");
- break;
- }
-
- //写数据到寄存器
- regs->cantxfg[txbuf].can_dlc=pfm->can_dlc;
- regs->cantxfg[txbuf].can_id=pfm->can_id;
- for(j=0;j<8;j++)
- {
- regs->cantxfg[txbuf].data[j]=pfm->data[j];
- }
-
- /*Control/status word to hold Tx MB active */
- regs->cantxfg[txbuf].can_dlc |= MB_CNT_CODE(0x0c);
- //调整尾指针
- dev->tx_buf[i].tail++;
-
- //统计发送短帧总数加一
- dev->stats.tx_shortframes++;
-
- break;
- }
- }
- /******************************************************************************
- 函数名称: _can_frame_short2long
- 函数版本: 01.01
- 创建作者: xxxxxx
- 创建日期: 2010-09-25
- 函数说明: 短帧组长帧
- 参数说明:
- dev: flexcan 设备
- prior: 优先级
-
- 返回值:
- 修改记录:
- */
- static int _can_frame_short2long(struct can_dev *dev, int prior)
- {
- static unsigned char pos_rec[CAN_FRAME_NUM];
- int pos_index;
- int i,len,is_deal;
- struct can_mb *pfm;
- struct can_mb *pfmtmp;
- unsigned char *pd,*p;
- unsigned char tmppos=dev->rx_buf[prior].head-1;
- unsigned char srcaddr;
- unsigned char dstaddr;
- unsigned char frameno;
- unsigned char frame_type;
- unsigned char frame_len;
- unsigned int frame_mark;
- unsigned char srcaddrtmp;
- unsigned char dstaddrtmp;
- unsigned char framenotmp;
- unsigned char frame_type_tmp;
- //结束帧指针
- pfm=(struct can_mb *)dev->rx_buf[prior].buf[tmppos];
-
- srcaddr=(pfm->can_id >> CAN_FRAME_OFFSET_SRC) & CAN_FRAME_MASK_SRC;
- dstaddr=(pfm->can_id >> CAN_FRAME_OFFSET_DST) & CAN_FRAME_MASK_DST;
- frameno=pfm->can_id & CAN_FRAME_MASK_SN;
- frame_type=(unsigned char)(pfm->can_id >> CAN_FRAME_OFFSET_TYPE) & CAN_FRAME_MASK_TYPE;
- frame_len = pfm->can_dlc & CAN_FRAME_MASK_LEN;//(pfm->can_dlc >> CAN_FRAME_OFFSET_LEN) & CAN_FRAME_MASK_LEN;
- // 查找起始帧
- pos_index = 0;
- for(i=0;i<CAN_FRAME_NUM;i++)
- {
- // 短帧
- pfmtmp=(struct can_mb *)dev->rx_buf[prior].buf[tmppos];
- frame_mark = (pfmtmp->can_id >> CAN_FRAME_OFFSET_MARK)& CAN_FRAME_MASK_MARK;
- srcaddrtmp = (pfmtmp->can_id >> CAN_FRAME_OFFSET_SRC) & CAN_FRAME_MASK_SRC;
- dstaddrtmp = (pfmtmp->can_id >> CAN_FRAME_OFFSET_DST) & CAN_FRAME_MASK_DST;
- framenotmp = pfmtmp->can_id & CAN_FRAME_MASK_SN;
- frame_type_tmp = (unsigned char)(pfmtmp->can_id >> CAN_FRAME_OFFSET_TYPE) & CAN_FRAME_MASK_TYPE;
-
- // 是要找的短帧
- if((srcaddr == srcaddrtmp ) && ( dstaddr==dstaddrtmp) && (frameno==framenotmp) && (frame_type == frame_type_tmp))
- {
- // 记录短帧位置
- pos_rec[pos_index++] = tmppos;
-
- // 找到起始帧
- if((frame_mark == CAN_FRAME_BEGIN) || (frame_mark == CAN_FRAME_SINGLE) )
- {
- break;
- }
- }
-
- // 前一短帧
- tmppos--;
- }
- if(pos_index == 0)
- {
- rt_printf("_can_frame_short2long:pos_index=%d\r\n",pos_index);
- dev->stats.rx_dropped++;
- return -1;
- }
- if(i == CAN_FRAME_NUM)
- {
- #if 0
- rt_printf("_can_frame_short2long:i=%d,pos_index=%d.\r\n",i,pos_index);
- #endif
- dev->stats.rx_dropped++;
- return -11;
- }
- // 检查长度
- len = frame_len + (pos_index - 1)*CAN_FRAME_DATA_LEN;
- if(len > CAN_LONGFRAME_DATA_LEN)
- {
- rt_printf("_can_frame_short2long:i=%d\r\n",i);
- dev->stats.rx_dropped++;
- return -2;
- }
-
- //长帧缓冲区首指针
- pd=dev->longframe_buf_rx[prior].buf[dev->longframe_buf_rx[prior].head];
- p = pd;
-
- // 长帧头
- p[0] = (pfmtmp->can_id >> CAN_FRAME_OFFSET_TYPE);
- p[1] = dstaddrtmp;
- p[2] = srcaddrtmp;
- p[3] = len;
- // 长帧数据
- p += CAN_LONGFRAME_HEAD_LEN;
- while(pos_index--)
- {
- len = pos_index == 0 ? frame_len : 8;
- pfmtmp=(struct can_mb *)dev->rx_buf[prior].buf[pos_rec[pos_index]];
- memcpy(p, pfmtmp->data, len);
- // 置帧空标志
- pfmtmp->can_dlc = 0;
- p+=8;
- }
- // 打印报文
- if(g_print_can)
- {
- // 增加can报文打印互斥锁,避免CAN0、CAN1两个接收线程打印混乱的情况
- pthread_mutex_lock(&printf_mutex);
- print_msg("RX_CAN:",pd,pd[3] + CAN_LONGFRAME_HEAD_LEN);
- pthread_mutex_unlock(&printf_mutex);
- }
- // 回调处理此长帧
- is_deal = 0;
- if(g_can_recv_callback)
- {
- is_deal = g_can_recv_callback(dev->no,pd);
- }
- // 如果此长帧没有处理,调整头位置
- if(is_deal != 1)
- {
- if(CAN_BUF_SPACE(&dev->longframe_buf_rx[prior], CAN_LONGFRAME_NUM) == 0)
- {
- dev->stats.rx_dropped++;
- rt_printf("长帧溢出\r\n");
- }
- else
- {
- dev->longframe_buf_rx[prior].head=(dev->longframe_buf_rx[prior].head+1) & (CAN_LONGFRAME_NUM-1);
- }
- // 唤醒主循环处理此长帧
- mainloop_wakeup();
- }
- return 0;
- }
- /******************************************************************************
- 函数名称: _can_int_rx
- 函数版本: 01.01
- 创建作者: xxxxxx
- 创建日期: 2010-09-25
- 函数说明: flexcan接收中断处理
- 参数说明:
- dev: flexcan 设备
- i: 表示第几个接收MB
-
- 返回值:
- 修改记录:
- */
- void _can_bus_monitor(u8 *buf)
- {
- static s8 str[128];
- s8 *p;
- int i;
- sprintf(str,"CAN_RS:");
- p = str + 7;
- for(i=0;i<16;i++)
- {
- sprintf(p,"%02x ",buf[i]);
- p += 3;
- }
- sprintf(p,"\r\n");
- rt_printf(str);
-
- }
- static void _can_app_rx(struct can_dev *dev, struct can_frame *frame)
- {
- struct can_mb *pfm;
-
- int ctrl = frame->can_dlc;
- int canid= frame->can_id;
- u32 prior=(canid >> CAN_FRAME_OFFSET_PRIOR) & 0x03;
- u32 srcaddr = (canid >> CAN_FRAME_OFFSET_SRC) & CAN_FRAME_MASK_SRC;
- int k;
- // 取短帧BUF
- pfm=(struct can_mb *)dev->rx_buf[prior].buf[dev->rx_buf[prior].head];
- if(pfm->can_dlc)
- {
- #if 0
- print_mem("CAN_BUF_FULL: ",(u8*)pfm,16);
- #endif
- dev->stats.overrun++;
- }
-
- // 得到内容
- pfm->can_dlc = ctrl;
- pfm->can_id = frame->can_id;
- for (k = 0; k < 8; k++)
- pfm->data[k] = frame->data[k];
- // 如果总线监视,打印短帧
- if(g_print_can_monitor)
- {
- _can_bus_monitor((u8*)pfm);
- }
- // 如果是自己发送的帧,直接返回
- if(srcaddr == 0)
- {
- // 置帧空标志
- pfm->can_dlc = 0;
- return;
- }
-
- //统计接收短帧总数
- dev->stats.rx_shortframes++;
-
- //调整当前位置
- dev->rx_buf[prior].head++;
- //是结束帧就开始组长帧
- if(((canid >> CAN_FRAME_OFFSET_MARK) & CAN_FRAME_MASK_MARK) < 0x02)
- {
- //统计接收长帧总数
- dev->stats.rx_longframes++;
-
- //短帧组长帧
- _can_frame_short2long(dev, prior);
- }
- }
- static void _can_int_rx(struct can_dev *dev, int i)
- {
- volatile struct can_regs *regs = (volatile struct can_regs *)dev->base_addr;
- struct can_mb *mb = (struct can_mb *)®s->cantxfg[i];
- struct can_mb *pfm;
-
- int ctrl = mb->can_dlc;
- int canid=mb->can_id;
- u32 prior=(canid >> CAN_FRAME_OFFSET_PRIOR) & 0x03;
- u32 srcaddr = (canid >> CAN_FRAME_OFFSET_SRC) & CAN_FRAME_MASK_SRC;
- int k;
- // 取短帧BUF
- pfm=(struct can_mb *)dev->rx_buf[prior].buf[dev->rx_buf[prior].head];
- if(pfm->can_dlc)
- {
- #if 0
- print_mem("CAN_BUF_FULL: ",(u8*)pfm,16);
- #endif
- dev->stats.overrun++;
- }
-
- // 得到内容
- pfm->can_dlc = ctrl;
- pfm->can_id = mb->can_id;
- for (k = 0; k < 8; k++)
- pfm->data[k] =\
- regs->cantxfg[i].data[k];
- // 如果总线监视,打印短帧
- if(g_print_can_monitor)
- {
- _can_bus_monitor((u8*)pfm);
- }
- // 如果是自己发送的帧,直接返回
- if(srcaddr == 0)
- {
- // 置帧空标志
- pfm->can_dlc = 0;
- return;
- }
-
- //统计接收短帧总数
- dev->stats.rx_shortframes++;
-
- //调整当前位置
- dev->rx_buf[prior].head++;
- //是结束帧就开始组长帧
- if(((canid >> CAN_FRAME_OFFSET_MARK) & CAN_FRAME_MASK_MARK) < 0x02)
- {
- //统计接收长帧总数
- dev->stats.rx_longframes++;
-
- //短帧组长帧
- _can_frame_short2long(dev, prior);
- }
- }
- void _can_isr(int no)
- {
- struct can_dev *dev = &g_can_dev[no];
- volatile struct can_regs *regs = (volatile struct can_regs *)dev->base_addr;
-
- u32 oflags;
- // 得到中断标志
- oflags = regs->caniflg;
- // 处理发送软中断
- if(_can_irq_is_force(no))
- {
- // 应用程序启动发送
- oflags |= SEND_BUF_BIT;
- _can_irq_clear(no);
- }
- // 检查发送标志
- if(oflags & SEND_BUF_BIT)
- {
- // 清发送中断
- regs->caniflg = SEND_BUF_BIT;
- oflags &= (~SEND_BUF_BIT);
- // 发送一帧
- _can_int_tx(dev);
- }
- // 处理接收中断
- // 硬件overrun
- if(oflags & 0x80)
- {
- dev->stats.overrun++;
- }
- // 接收一帧
- if(oflags & 0x20)
- {
- _can_int_rx(dev,0);
- }
- // 清接收中断标志
- regs->caniflg = oflags;
- return ;
- }
- void _can_isr_err(int no)
- {
- struct can_dev *dev = &g_can_dev[no];
- volatile struct can_regs *regs = (struct can_regs *)dev->base_addr;
- u32 errstate = regs->canerrstat;
- regs->canerrstat = errstate;
- dev->stats.hw_bus_errors++;//统计出错信息
-
- return ;
- }
- void _can_isr_0(void)
- {
-
- _can_isr(0);
- }
- void _can_isr_1(void)
- {
-
- _can_isr(1);
- }
- void _can_isr_err_0(void)
- {
-
- _can_isr_err(0);
- }
- void _can_isr_err_1(void)
- {
-
- _can_isr_err(1);
- }
- int _can_irq_force(int no)
- {
- #ifdef __KERNEL__
- uint32_t flags;
- no *= 4;
- rt_irq_save(flags);
- REG_MCF_INTFRCL1 |= 1 << no;
- rt_irq_restore(flags);
- #else
- g_can_tx_call[no] = 1;
- #endif
- return 0;
- }
- int _can_irq_clear(int no)
- {
- uint32_t flags;
-
- no *= 4;
-
- rt_irq_save(flags);
- REG_MCF_INTFRCL1 &= ~(1 << no);
- rt_irq_restore(flags);
- return 0;
- }
- int _can_irq_is_force(int no)
- {
- no *= 4;
- if(REG_MCF_INTFRCL1 & (1 << no))
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- /*------------------------------ 测试函数 -------------------------------------
- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
- 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
- */
- #define LOOP_BEGIN 1
- int can_test(void)
- {
- static unsigned char buf_tx[CAN_LONGFRAME_LEN],buf_rx[CAN_LONGFRAME_LEN];
- static unsigned char loop = LOOP_BEGIN;
- static uint32_t us0 = 0,err_count=0;
-
- uint32_t us1;
- int i;
- int len_tx,len_rx;
- // 1S调用一次
- us1 = ustimer_get_origin();
- if(us1 - us0 < USTIMER_SEC*10)
- {
- return 0;
- }
- us0 = us1;
-
- // 发送一帧
- memset(buf_tx,0,sizeof(buf_tx));
- buf_tx[0] = loop;
- buf_tx[1] = 1;
- buf_tx[2] = 2;
- buf_tx[3] = loop;
-
- for(i=0; i<buf_tx[3]; i++)
- {
- buf_tx[CAN_LONGFRAME_HEAD_LEN + i] = i;
- }
- len_tx = can_send(0,buf_tx);
- // len_tx = can_send(1,buf_tx);
- // 延时5ms
- ustimer_delay(USTIMER_MS*50);
-
- // 接收一帧
- memset(buf_rx,0,sizeof(buf_rx));
- len_rx = can_recv(0,buf_rx,256);
- if((len_tx == len_rx) && (memcmp(buf_tx,buf_rx,len_tx) == 0))
- {
- rt_printf("can_test ok(%03d,err_count=%d):[len_tx=%d,len_rx=%d]\r\n",loop,err_count,len_tx,len_rx);
- }
- else
- {
- err_count++;
- rt_printf("can_test err(%03d,err_count=%d):[len_tx=%d,len_rx=%d]\r\n",loop,err_count,len_tx,len_rx);
- // can_print_mem("TX:",buf_tx,len_tx);
- // can_print_mem("RX:",buf_rx,len_rx);
- }
- // loop++;
- if(loop > CAN_LONGFRAME_DATA_LEN)
- {
- loop = LOOP_BEGIN;
- }
-
- return 0;
- }
- #endif
- /*------------------------------ 文件结束 -------------------------------------
- */
|