| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648 |
- /******************************************************************************
- 版权所有:
- 文件名称: 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);
- 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
- /*------------------------------ 文件结束 -------------------------------------
- */
|