| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640 |
- /******************************************************************************
- 版权所有:
- 文件名称: 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]; //应用可根据优先级申请的长帧缓冲区
- 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;
- }
- usleep(10);
- }
- }
- 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);
- //初始化缓冲区
- 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, 10);
- 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)
- {
- print_msg("RX_CAN:",pd,pd[3] + CAN_LONGFRAME_HEAD_LEN);
- }
- // 回调处理此长帧
- 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
- /*------------------------------ 文件结束 -------------------------------------
- */
|