阅读:1848回复:4
流接口驱动中断的一个问题
我做过一个CAN总线的流接口驱动
全面来说是这样的,当收数收完以后,会有一个中断,通知CPU读取, 原来是用查询方式收数 现在改为中断 问题在这里, 中断处理线程,我按通常的做法放在CAN_INIT里面, 但是中断处里也就是收数啊,那CAN_READ怎么办,两者怎么建立联系 |
|
沙发#
发布于:2007-03-21 08:10
大哥们讲一下啊
|
|
板凳#
发布于:2007-03-21 08:35
附上程序,大哥们指点下
DWORD CAN_Init(DWORD Index) { GPIOInit(); /* gCANIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL); InterruptInitialize(SYSINTR_CAN, gCANIntrEvent, 0, 0); WaitForSingleObject(gCANIntrEvent, INFINITE); */ gCANIntrThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) CAN_IntrThread, 0, 0, &IDThread); return 1; }DWORD CAN_Read(DWORD hOpenContext,LPVOID pBuffer ,DWORD count) { MCP2510_Write(CANINTE, 0xf3); } LPVOID pBuffer ; DWORD count; U8 in_buff[6]; U8 out_buff[4]; U8 CanID[4]; static HANDLE gCANIntrEvent; static HANDLE gCANIntrThread; DWORD IDThread; void CAN_IntrHander(void) {int i; U32 id; unsigned char dlc; int rxRTR, isExt; int temp; U8 data_read[32]; if(count==9) { memcpy(CanID,pBuffer,4); count=8; Read: i = Can_Poll(); if((i==0)|(i==1)) { memset(data_read,0,sizeof(data_read) ) ; temp = Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt); // memcpy(data_read,read_buf,count); out_buff[0] = ((id>>24)&0xff); out_buff[1] = ((id>>16)&0xff); out_buff[2] = ((id>>8)&0xff); out_buff[3] = ((id)&0xff); if((out_buff[2]!=CanID[2]) || (out_buff[3]!=CanID[3])) { goto Read; }else { memcpy(pBuffer,data_read,count); } } else { // return 0; } }else if(count!=9) { i = Can_Poll(); if((i==0)|(i==1)) { memset(data_read,0,sizeof(data_read) ) ; temp = Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt); // memcpy(pBuffer,read_data,count); out_buff[0] = ((id>>24)&0xff); out_buff[1] = ((id>>16)&0xff); out_buff[2] = ((id>>8)&0xff); out_buff[3] = ((id)&0xff); } else { // return 0; } } // return count ; } //中断线程式************************************************************************* DWORD CAN_IntrThread(void) { gCANIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // InterruptDisable(SYSINTR_CAN); InterruptInitialize(SYSINTR_CAN, gCANIntrEvent, 0, 0); WaitForSingleObject(gCANIntrEvent, INFINITE); CAN_IntrHander(); InterruptDone(SYSINTR_CAN); } 这里我觉得关键就在于LPVOID pBuffer ,DWORD count这两个参数的问题 我觉得我写得有问题,大哥们说一下 |
|
地板#
发布于:2007-03-27 10:45
再发一个改过的,大家看看哪里有错误,还是丢数.
U8 in_buff[6]; U8 out_buff[4]; U8 CanID[4]; struct list { int id; int data_buff[8]; struct list *next; }; typedef struct list node; typedef node *link; link NEW; link pointer; link head; link temp=head.next; static HANDLE gCANIntrEvent; static HANDLE gCANIntrThread; LPVOID pBuffer; DWORD count; DWORD IDThread; DWORD CAN_Init(DWORD Index) { GPIOInit(); link Create_list ( head) { head=(link) malloc(sizeof(node)); if(head==NULL) RETAILMSG( DEBUGMODE,( TEXT( "MEMORY ALLOCATE FAILURE \n\r" ) ) ); else { //gCANIntrThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) CAN_IntrThread, 0, 0, &IDThread); head.next=NULL; pointer=head; while(1) { NEW=(link) malloc(sizeof(node)); gCANIntrThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) CAN_IntrThread, 0, 0, &IDThread); NEW.next=NULL; pointer.next=NEW; pointer=NEW; } } return head; } //gCANIntrThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) CAN_IntrThread, 0, 0, &IDThread); return 1; } BOOL CAN_Deinit(DWORD dwData) { Free_list(link head); InterruptDisable(SYSINTR_CAN); CloseHandle(gCANIntrEvent); CloseHandle(gCANIntrThread); return TRUE; } DWORD CAN_Read(DWORD hOpenContext,LPVOID pBuffer ,DWORD count) { int i; U32 id; unsigned char dlc; int rxRTR, isExt; int temp; U8 data_read[32]; if(count==9) { memcpy(CanID,pBuffer,4); count=8; Read: i = Can_Poll(); if((i==0)|(i==1)) { memset(data_read,0,sizeof(data_read) ) ; temp = Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt); // RETAILMSG (1, (TEXT("::: PBT_InitializeAddresses - Fail!!\r\n") )); // UART_printf("0x%x\r\n",data_read); // sprint( RETAILMSG(TRUE, (TEXT("can_data %u\r\n"), data_read)); out_buff[0] = ((id>>24)&0xff); out_buff[1] = ((id>>16)&0xff); out_buff[2] = ((id>>8)&0xff); out_buff[3] = ((id)&0xff); if((out_buff[2]!=CanID[2]) || (out_buff[3]!=CanID[3])) { goto Read; }else { memcpy(pBuffer,data_read,count); } } else { return 0; } }else if(count!=9) { i = Can_Poll(); if((i==0)|(i==1)) { memset(data_read,0,sizeof(data_read) ) ; temp = Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt); memcpy(pBuffer,data_read,count); out_buff[0] = ((id>>24)&0xff); out_buff[1] = ((id>>16)&0xff); out_buff[2] = ((id>>8)&0xff); out_buff[3] = ((id)&0xff); } else { return 0; } } return count ; } |
|
地下室#
发布于:2007-03-27 10:46
/***********************************************************
***********************************************************/ #include <windows.h> #include <types.h> #include <drv_glob.h> #include <nkintr.h> #include <oalintr.h> #include <MCP2510.h> //unsigned short ReadBuf[256] ; //TCHAR read_buf[256] ; //U8 read_buf[20]; U8 in_buff[6]; U8 out_buff[4]; U8 CanID[4]; /**************************************************************************** 【功能说明】延迟程序 ****************************************************************************/ static void Delay(USHORT count) { volatile int i, j = 0; volatile static int loop = 400000000/100000; for(;count > 0;count--) for(i=0;i < loop; i++) { j++; } } /**************************************************************************** 【功能说明】 设置GPIO为SPI模式 ****************************************************************************/ void GPIOInit(void) { rGPEUP |= (7 << 11); //GPE13、GPE12、GPE11禁止上拉 rGPECON &= (~ (0x3F << 22)); rGPECON |= (0x2A << 22); //set GPE11,12,13 as SPI0 rGPGCON &= (~ (0x3 << 4)); rGPGCON |= (1 << 4); //GPG2 as output rGPGUP |= (1 << 2); //GPG2禁止上拉 } /**************************************************************************** 【功能说明】初始化SPI,条件:begin为真 ****************************************************************************/ void SPIInit(int begin) { if(begin) { MCP2510_CS_H; rSPPRE = 0xff;//spi速度??????? rSPCON |= 0x18;//master and enable sck } else rSPCON = 0; } /**************************************************************************** 【功能说明】向SPI接口写入数据,并返回结果,如果只单独读出SPI内容,写入0xFF。 ****************************************************************************/ U8 Spi_Write( U8 Data ) { rSPTDAT = Data; while(! (rSPSTA & 1)); //判断SPI状态,为1指明总线闲 return (U8) rSPRDAT; MCP2510_Write(CANINTF,NO_IE);//清缓冲区 } /**************************************************************************** 【功能说明】向MCP2510指定地址写入一个字节 ****************************************************************************/ void MCP2510_Write( U8 address, U8 value) { MCP2510_CS_L; Spi_Write(MCP2510INSTR_WRITE); Spi_Write(address); Spi_Write(value); MCP2510_CS_H; } /**************************************************************************** 【功能说明】从MCP2510指定地址中读出一个字节 ****************************************************************************/ U8 MCP2510_Read( U8 address ) { U8 result; MCP2510_CS_L; Spi_Write(MCP2510INSTR_READ); Spi_Write(address); result = Spi_Write(0xFF); MCP2510_CS_H; return result; } /**************************************************************************** 【功能说明】修改指定地址寄存器的某些位 ****************************************************************************/ void MCP2510_WriteBits( U8 address, U8 data, U8 mask ) { MCP2510_CS_L; Spi_Write(MCP2510INSTR_BITMDFY); Spi_Write(address); Spi_Write(mask); Spi_Write(data); MCP2510_CS_H; } /**************************************************************************** 【功能说明】序列写入MCP2510数据 ****************************************************************************/ void MCP2510_Swrite( U8 address, U8* pdata, U8 nlength) { MCP2510_CS_L; Spi_Write(MCP2510INSTR_WRITE); Spi_Write((unsigned char)address); while(nlength--) { Spi_Write(* pdata++); } MCP2510_CS_H ; } /**************************************************************************** 【功能说明】序列读取MCP2510数据 ****************************************************************************/ void MCP2510_SRead( U8 address, U8* pdata, U8 nlength ) { MCP2510_CS_L; Spi_Write(MCP2510INSTR_READ); Spi_Write(address); while(nlength--) { * pdata++ = Spi_Write(0xFF); } MCP2510_CS_H; } /**************************************************************************** 【功能说明】软件复位MCP2510 ****************************************************************************/ void MCP2510_Reset() { MCP2510_CS_L; Spi_Write( MCP2510INSTR_RESET ); MCP2510_CS_H ; } /**************************************************************************** 【功能说明】状态读指令 以下图示为状态字位说明 7 6 5 4 3 2 1 0 // | | | | | | | | // | | | | | | | |___CANINTF.RX0IF // | | | | | | |_______CANINTF.RX1IF // | | | | | |___________TXB0CTRL.TXREQ // | | | | |_______________CANINTF.TX0IF // | | | |___________________TXB1CTRL.TXREQ // | | |_______________________CANINTF.TX1IF // | |___________________________TXB2CTRL.TXREQ // |_______________________________CANINTF.TX2IF ****************************************************************************/ U8 MCP2510_ReadStatus() { U8 result; MCP2510_CS_L; Spi_Write(MCP2510INSTR_RDSTAT); result = Spi_Write(0xFF) ; Spi_Write( 0 ) ; //数据重复输出 MCP2510_CS_H ; //if( MCP2510_DEBUG ) Uart_Printf( "StatusREG = 0x%x\n", result ) ; return result; } /**************************************************************************** 【功能说明】设置MCP2510的波特率,此处基本配置为底板晶振12MHz ****************************************************************************/ void MCP2510_SetBandRate(CanBandRate bandrate) { U8 value=0; U8 ReadBackCNT = 0; MCP2510_Write(MCP2510REG_CANCTRL, MODE_CONFIG); //if( MCP2510_DEBUG ) RETAILMSG(1,(TEXT( "MCP2510REG_CANCTRL = 0x%x\n"), MCP2510_Read(MCP2510REG_CANCTRL) )); while( ReadBackCNT<8 ) //确保进入配置模式 { value = ( MCP2510_Read( MCP2510REG_CANSTAT ) & 0xe0 ); if(value == MODE_CONFIG ){ break; } ReadBackCNT++ ; } if( ReadBackCNT == 8 ) //Set mcp2510's mode failed,redo it again { MCP2510_Reset(); MCP2510_Write(MCP2510REG_CANCTRL, MODE_CONFIG); //redo to set mcp2510 mode Delay( 150 ); value = ( MCP2510_Read(MCP2510REG_CANCTRL) & 0xe0 ); //read back mode from CANSTAT Register } switch(bandrate){ case BandRate_10kbps: MCP2510_Write(CNF1, SJW1|BRP50); //Synchronization Jump Width Length =1 TQ MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG3<<3)|SEG5); // Phase Seg 1 = 3, Prop Seg = 4 MCP2510_Write(CNF3, SEG3);// Phase Seg 2 = 3 break; case BandRate_100kbps: MCP2510_Write(CNF1, SJW1|BRP5); //Synchronization Jump Width Length =1 TQ MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG3); // Phase Seg 1 = 4, Prop Seg = 3 MCP2510_Write(CNF3, SEG4);// Phase Seg 2 = 4 break; case BandRate_125kbps: MCP2510_Write(CNF1, SJW1|BRP4); //Synchronization Jump Width Length =1 TQ MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG5<<3)|SEG3); // Phase Seg 1 = 5, Prop Seg = 3 MCP2510_Write(CNF3, SEG3);// Phase Seg 2 = 3 break; case BandRate_250kbps: MCP2510_Write(CNF1, SJW1|BRP2); //Synchronization Jump Width Length =1 TQ MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG3); // Phase Seg 1 = 4, Prop Seg = 3 MCP2510_Write(CNF3, SEG4);// Phase Seg 2 = 4 break; case BandRate_500kbps: MCP2510_Write(CNF1, SJW1|BRP1); //Synchronization Jump Width Length =1 TQ MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG3); // Phase Seg 1 = 4, Prop Seg = 3 MCP2510_Write(CNF3, SEG4);// Phase Seg 2 = 4 break; case BandRate_1Mbps: MCP2510_Write(CNF1, SJW1|BRP1); //Synchronization Jump Width Length =1 TQ MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG2<<3)|SEG1); // Phase Seg 1 = 2, Prop Seg = 1 MCP2510_Write(CNF3, SEG2);// Phase Seg 2 = 2 case BandRate_833kbps: MCP2510_Write(CNF1, SJW1|BRP6); //Synchronization Jump Width Length =1 TQ MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG3); // Phase Seg 1 = 4, Prop Seg = 3 MCP2510_Write(CNF3, SEG4);// Phase Seg 2 = 4 break; } } /**************************************************************************** 【功能说明】读取MCP2510 CAN总线ID 参数: address为MCP2510寄存器地址 can_id为返回的ID值 返回值 TRUE,表示是扩展ID(29位) FALSE,表示非扩展ID(11位) ****************************************************************************/ int MCP2510_Read_Can_ID( U8 address, U32* can_id) { U32 tbufdata; unsigned char* p=(unsigned char*)&tbufdata; MCP2510_SRead(address, p, 4); *can_id = (tbufdata<<3)|((tbufdata>>13)&0x7); //先移出SID2-SID0,再把它移到低三位 //或之后就是SID10~SID0 *can_id &= 0x7ff; //取标准的ID if ( (p[MCP2510LREG_SIDL] & TXB_EXIDE_M) == TXB_EXIDE_M ) { *can_id = (*can_id<<2) | (p[MCP2510LREG_SIDL] & 0x03); *can_id <<= 16; *can_id |= tbufdata>>16; return TRUE; } return FALSE; } /******************************************* 【功能说明】设置MCP2510 CAN总线ID 参数: address为MCP2510寄存器地址 can_id为设置的ID值 IsExt表示是否为扩展ID *******************************************/ void MCP2510_Write_Can_ID(U8 address, U32 can_id, int IsExt) { U32 tbufdata; if (IsExt) { can_id&=0x1fffffff; //29位 tbufdata=(can_id >>21) | ((can_id>>5) & 0xe000) | ((can_id>>8) & 0x300) | ((can_id<<8) & 0xff0000) | (can_id<<24) | 0x800; } else{ can_id&=0x7ff; //11位 tbufdata= (can_id>>3)|((can_id&0x7)<<13); } MCP2510_Swrite(address, (unsigned char*)&tbufdata, 4); } /*********************************************************** 【功能说明】读取MCP2510 接收的数据 参数: nbuffer为第几个缓冲区可以为3或者4 can_id为返回的ID值 rxRTR表示是否是RXRTR data表示读取的数据 dlc表示数据长度 返回值 TRUE,表示是扩展总线 FALSE,表示非扩展总线 ***********************************************************/ int MCP2510_Read_Can(U8 nbuffer, int* rxRTR, U32* can_id, U8* data , U8* dlc) { U8 mcp_addr = (nbuffer<<4) + 0x31, ctrl; int IsExt; IsExt=MCP2510_Read_Can_ID( mcp_addr, can_id); ctrl=MCP2510_Read(mcp_addr-1); *dlc=MCP2510_Read( mcp_addr+4); if ((ctrl & 0x08)) { *rxRTR = TRUE;//扩展 } else{ *rxRTR = FALSE; } *dlc &= DLC_MASK; MCP2510_SRead(mcp_addr+5, data, *dlc); return IsExt; } /*********************************************************************************** 【功能说明】查询是否收到数据 返回值:如果没有数据,则返回-1,否则,返回收到数据的缓冲区号 Note: 如果两个缓冲区都收到数据,则返回第一个缓冲区 ***********************************************************************************/ int Can_Poll() { if( MCP2510_ReadStatus()&RX0INT ) { return 0; } //if( MCP2510_ReadStatus()&RX1INT ) //{ // return 1; //} return -1; } /**************************************************************************** 【功能说明】从MCP2510读数据 ****************************************************************************/ int Can_Read(int n, U32* id, U8 *pdata, U8*dlc, int* rxRTR, int *isExt) { U8 byte; byte = MCP2510_Read(CANINTF); if(n==0) { if(byte & RX0INT) { *isExt=MCP2510_Read_Can(n+3, rxRTR, id, pdata, dlc); MCP2510_WriteBits(CANINTF, (U8)(~(RX0INT)), RX0INT); // Clear interrupt return TRUE ; } return FALSE; } else if(n ==1 ) { if(byte & RX1INT) { *isExt=MCP2510_Read_Can(n+4, rxRTR, id, pdata, dlc); MCP2510_WriteBits(CANINTF, (U8)(~(RX1INT)), RX1INT); // Clear interrupt return TRUE ; } return FALSE; } // RETAILMSG(1,(TEXT( "Error! Receive channel=0x%x\n"), n )) ; return FALSE; } /*********************************************************** 【功能说明】写入MCP2510 发送的数据 参数: nbuffer为第几个缓冲区可以为0、1、2 IsExt表示是否是扩展总线, FALSE表示非扩展总线 can_id为写入的ID值 rxRTR表示是否是RXRTR data表示要写入的数据 dlc表示数据长度 ***********************************************************/ void MCP2510_Write_Can( U8 nbuffer, int IsExt, U32 can_id, int rxRTR, U8* data,U8 dlc ) { U8 mcp_addr = (nbuffer<<4) + 0x31; MCP2510_Swrite(mcp_addr+5, data, dlc ); // write data bytes MCP2510_Write_Can_ID( mcp_addr, can_id,IsExt); // write CAN id if (rxRTR) dlc |= RTR_MASK; // if RTR set bit in byte MCP2510_Write((mcp_addr+4), dlc); // write the RTR and DLC } /*********************************************************************************** 【功能说明】发送数据 Note: 使用三个缓冲区循环发送,没有做缓冲区有效检测 ***********************************************************************************/ void Can_Write(U32 id, U8 *pdata, unsigned char dlc, int IsExt, int rxRTR) { unsigned char err ; static int ntxbuffer=0; MCP2510_Write_Can(ntxbuffer, IsExt, id, rxRTR, pdata, dlc); switch(ntxbuffer){ case 0: MCP2510_WriteBits(TXB0CTRL, (TXB_TXREQ_M|TXB_TXP10_M), 0xff) ; do { err = MCP2510_Read(TXB0CTRL) ; } while( (err &0x08)==0x08 ) ; // if( (err &0x70) != 0 ) RETAILMSG(1,(TEXT( " Can Send Err = 0x%x\n"), err ) ); ntxbuffer=1; break; case 1: MCP2510_WriteBits(TXB1CTRL, (TXB_TXREQ_M|TXB_TXP10_M), 0xff) ; do { err = MCP2510_Read(TXB1CTRL) ; } while( (err &0x08)==0x08 ) ; // if( (err &0x70) != 0 ) RETAILMSG(1,(TEXT( " Can Send Err = 0x%x\n"), err ) ); ntxbuffer=2; break; case 2: MCP2510_WriteBits(TXB2CTRL, (TXB_TXREQ_M|TXB_TXP10_M), 0xff) ; do { err = MCP2510_Read(TXB2CTRL) ; } while( (err &0x08)==0x08 ) ; // if( (err &0x70) != 0 ) RETAILMSG(1,(TEXT( " Can Send Err = 0x%x\n"), err ) ); ntxbuffer=0; break; } } /**************************************************************************** 【功能说明】关闭屏蔽滤波功能 ****************************************************************************/ void Can_Setup(void) { //MCP2510_WriteBits(RXB0CTRL, (RXB_BUKT|RXB_RX_ANY), 0xFF);//关闭屏蔽滤波功能,接收所有报文,允许滚存 MCP2510_WriteBits(RXB0CTRL, RXB_RX_ANY, 0xFF); //关闭屏蔽滤波功能,接收所有报文 //MCP2510_WriteBits(RXB1CTRL, RXB_RX_ANY, 0xFF); //关闭屏蔽滤波功能,接收所有报文 } /**************************************************************************** 【功能说明】对MCP2510进行初始化,设置波特率。 ****************************************************************************/ void Init_MCP2510(CanBandRate bandrate) { SPIInit(1); MCP2510_Reset(); MCP2510_Write(CANINTE, NO_IE); //禁止所有中断 MCP2510_SetBandRate(bandrate); MCP2510_Write(CLKCTRL, MODE_NORMAL| CLKEN | CLK8);//标准模式 } /*以下为流接口驱动程序,上次应用程序应参考此接口函数*/ /**************************************************************************** 【功能说明】CAN动态链接库的入口函数定义。 ****************************************************************************/ BOOL WINAPI CAN_DllEntry(HINSTANCE DllInstance, INT Reason, LPVOID Reserved) { switch(Reason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } /**************************************************************************** 【功能说明】打开CAN驱动程序,由系统CreateFile()函数打开CAN,返回驱动程序引用事例句柄。 参数:DWORD dwData,CAN驱动的句柄,由CAN_Init函数创建的时候返回。 DWORD dwAccess,传给驱动程序使用的地址。 DWORD dwShareMode,在本函数中用来传递波特率。 ****************************************************************************/ DWORD CAN_Open( DWORD dwData, DWORD dwAccess, DWORD dwShareMode) { switch(dwShareMode) { case 0: Init_MCP2510(BandRate_10kbps); break; case 1: Init_MCP2510(BandRate_100kbps); break; case 2: Init_MCP2510(BandRate_125kbps); break; case 3: Init_MCP2510(BandRate_250kbps); break; case 4: Init_MCP2510(BandRate_500kbps); break; case 5: Init_MCP2510(BandRate_1Mbps); break; case 6: Init_MCP2510(BandRate_833kbps); break; default: break; } Can_Setup(); return 1; } /**************************************************************************** 【功能说明】关闭CAN驱动程序,应用程序调用CloseHandle来停止使用流接口驱动, 若调用成功返回TRUE,反之返回FALSE。 参数:DWORD dwData,驱动的引用事例句柄,由CAN_Init函数创建。 ****************************************************************************/ BOOL CAN_Close(DWORD dwData) { // RETAILMSG(1,(TEXT( "CAN_Close\n"))) ; SPIInit(0); return TRUE; } /**************************************************************************** 【功能说明】初始化CAN,应用程序不能直接调用此函数,通过ActivateDeviceEx函数 来调用若调用成功返回1。 参数:DWORD Index,指向字符串的指针,为流接口驱动在注册表的位置。 ****************************************************************************/ DWORD CAN_Init(DWORD Index) { GPIOInit(); int i; U32 id; unsigned char dlc; int rxRTR, isExt; int temp; U8 data_read[32]; while(1) { i = Can_Poll(); if((i==0)|(i==1)) { Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt); RETAILMSG(TRUE, (TEXT("can_data %u\r\n"), data_read)); } } return 1; } /**************************************************************************** 【功能说明】用于设备管理器来卸载CAN驱动程序,应用程序不能直接调用此函数,通过 DeactivateDevice函数来调用 ****************************************************************************/ BOOL CAN_Deinit(DWORD dwData) { return TRUE; } /**************************************************************************** 【功能说明】读接口程序,应用程序通过调用ReadFile函数来调用。 参数:DWORD hOpenContext,CAN_Open函数返回的句柄。 LPVOID pBuffer,一个缓冲区地址用于从CAN读数据。 DWORD count,需要读缓冲区的长度 ****************************************************************************/ DWORD CAN_Read(DWORD hOpenContext,LPVOID pBuffer ,DWORD count) { int i; U32 id; unsigned char dlc; int rxRTR, isExt; int temp; U8 data_read[32]; if(count==9) { memcpy(CanID,pBuffer,4); count=8; Read: i = Can_Poll(); if((i==0)|(i==1)) { memset(data_read,0,sizeof(data_read) ) ; temp = Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt); // RETAILMSG (1, (TEXT("::: PBT_InitializeAddresses - Fail!!\r\n") )); // UART_printf("0x%x\r\n",data_read); // sprint( RETAILMSG(TRUE, (TEXT("can_data %u\r\n"), data_read)); out_buff[0] = ((id>>24)&0xff); out_buff[1] = ((id>>16)&0xff); out_buff[2] = ((id>>8)&0xff); out_buff[3] = ((id)&0xff); if((out_buff[2]!=CanID[2]) || (out_buff[3]!=CanID[3])) { goto Read; }else { memcpy(pBuffer,data_read,count); } } else { return 0; } }else if(count!=9) { i = Can_Poll(); if((i==0)|(i==1)) { memset(data_read,0,sizeof(data_read) ) ; temp = Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt); memcpy(pBuffer,data_read,count); out_buff[0] = ((id>>24)&0xff); out_buff[1] = ((id>>16)&0xff); out_buff[2] = ((id>>8)&0xff); out_buff[3] = ((id)&0xff); } else { return 0; } } return count ; } /**************************************************************************** 【功能说明】写接口程序,应用程序通过调用WriteFile函数来调用。 参数:DWORD hOpenContext,CAN_Open函数返回的句柄。 LPCVOID pSourceBytes,指向要写的数据缓冲的指针。 DWORD NumberOfBytes,定义从pSourceBytes写道CAN的字节数。 ****************************************************************************/ DWORD CAN_Write(DWORD hOpenContext,LPCVOID pSourceBytes,DWORD NumberOfBytes) { unsigned char * pTmp ; U32 ID_data = 0x0; int rxRTR, Ext,i, isExt; U32 id; unsigned char dlc; U8 data_read[32]; i = Can_Poll(); if((i==0)|(i==1)) { Can_Read(i, &id, data_read, &dlc, &rxRTR, &isExt); } pTmp = (unsigned char *)pSourceBytes ; ID_data = in_buff[5]|(in_buff[4]<<8)|(in_buff[3]<<16)|(in_buff[2]<<24); Ext = in_buff[0]; rxRTR = in_buff[1]; Can_Write( ID_data, (unsigned char *)pTmp, NumberOfBytes, Ext, rxRTR); return 1; } /**************************************************************************** 【功能说明】移动设备的数据指针。应用程序调用SetFilePointer函数移动设备数据 指针时,系统会调用CAN_Seek函数。 ****************************************************************************/ DWORD CAN_Seek(DWORD hOpenContext, long Amount,WORD Type) { // RETAILMSG(1,(TEXT("ucDragon seek----\r\n"))); return 1; } /**************************************************************************** 【功能说明】此函数通常用于向设备发送一个命令,应用程序使用DeviceIoControl 函数来通知系统调用此函数,在本驱动中用来扩展流接口,用于应用层跟 底层驱动交互数据。 参数:DWORD dwOpenData,CAN的上下文句柄,由CAN_Open函数创建和返回。 DWORD dwCode,定义完成此次的I/O控制操作,在本驱动中用来传递 读写控制指令,0为写操作,1为读操作。 PBYTE pBufIn,缓冲区指针指向需要传给驱动程序使用的数据,本驱动中 用来向驱动传递32位的ID号。 DWORD dwLenIn,要传给驱动使用数据的长度,本驱动中用来向驱动传递 是否扩展帧和远程帧信息,在本产品中一般只需值为0。 PBYTE pBufOut,缓冲区指针指向驱动程序传给应用程序使用的数据,本驱动中 用来向应用程序传递32位的ID号。 DWORD dwLenOut,要传给应用成熟使用数据的长度。 PDWORD pdwActualOut,用于返回实际处理数据的长度。 ****************************************************************************/ BOOL CAN_IOControl(DWORD dwOpenData, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut) { if(dwCode==0) { switch(dwLenIn) { // case 0: in_buff[0] = 0; //标志帧 in_buff[1] = 0;break; //不是远程帧 case 1: in_buff[0] = 0; in_buff[1] = 1;break; case 2: in_buff[0] = 1; //扩展帧 in_buff[1] = 0;break; //非远程帧 case 3: in_buff[0] = 1; in_buff[1] = 1;break; default: break; } in_buff[2] = pBufIn[0]; //传递ID,总共4个字节 31~24 in_buff[3] = pBufIn[1]; //传递ID,总共4个字节 23~16 in_buff[4] = pBufIn[2]; //传递ID,总共4个字节 15~8 in_buff[5] = pBufIn[3]; //传递ID,总共4个字节 7~0 } else { pBufOut[0] = out_buff[0]; //传递ID,总共4个字节 31~24 pBufOut[1] = out_buff[1]; //传递ID,总共4个字节 23~16 pBufOut[2] = out_buff[2]; //传递ID,总共4个字节 15~8 pBufOut[3] = out_buff[3]; //传递ID,总共4个字节 7~0 } return TRUE; } |
|