VxWorks下TSI721驱动开发

2 篇文章 0 订阅
2 篇文章 0 订阅

VxWorks下TSI721驱动开发

概述

	基于X86主控单元和VxWorks 6.9操作系统开发TSI721板卡驱动,硬件板卡资料参考我的博客[Windows 下TSI721驱动软件使用](https://editor.csdn.net/md/?articleId=114711812),调试使用的启动方式为UEFI  U盘启动。提供给用户的接口,也是参考Windows下官方的用户函数接口,保持用户对两种操作系统软件使用的方式方法一致。
	邮箱:qinshimi_yue@foxmail.com

Vxworks下驱动

  1.   填充vxbDevRegInfo,并通过vxbDevRegister进程注册驱动程序;
    
LOCAL struct vxbPciRegister tsi721PciRegistration =
    {
        {
        NULL,			/* pNext */
        VXB_DEVID_DEVICE,	/* devID */
        VXB_BUSID_PCI,		/* busID = PCI */
        VXB_VER_4_0_0,  	/* vxbVersion */
        "tsi721",		/* drvName */
        &tsi721Funcs,		/* pDrvBusFuncs */
        NULL,		/* pMethods */
        NULL,			/* devProbe */
        NULL	/* pParamDefaults */
        },
    NELEMENTS(tsi721PciDevIDList),
    tsi721PciDevIDList
    };

  1.   通过向tsi721PciDevIDList数组中添加记录,完成设备的注册;
    
/*
 * List of supported device IDs.
 */

LOCAL struct vxbPciID tsi721PciDevIDList[] =
    {
        /* { devID, vendID } */
       
        { TSI721_DEVID, IDT_VENDORID },//板卡1
        { TSI721_DEVID, IDT_VENDORID } //板卡2 ,针对两个TSI721设备的可以加两个

    };
  1.   Vxworks启动是会实例化tsi721PciDevIDList中的设备(不必人工干预);
    
  2.   在tsi721Funcs中注册的几个初始化函数中添加实际的设备驱动代码;
    
LOCAL struct drvBusFuncs tsi721Funcs =
    {
    tsi721InstInit,      /* devInstanceInit */
    tsi721InstInit2,     /* devInstanceInit2 */
    tsi721InstConnect    /* devInstanceConnect */
    };

  1. 在tsi721InstInit2中添加对TSI721设备的维护包,门铃,消息通信,DMA通信的初始化,以及挂载中断处理函数。
  2. 实现维护包读写操作;
  3. 实现门铃收发操作;
  4. 实现MSG消息通信;
  5. 实现NREAD ,NWRITE,NWRITE_R操作;
  6. 编写测试用例,测试这些基本接口。

TSI721接口列表

接口函数简要说明
TSI721DeviceOpen打开一个 Tsi721 设备。
TSI721DeviceClose关闭一个 Tsi721 设备。
TSI721RegisterRead从设备控制和状态寄存器(CSRs)空间的存储器映射寄存器读指定个数的32 位数据。。
TSI721RegisterWrite从设备控制和状态寄存器(CSRs)空间的存储器映射寄存器写指定个数的32 位数据。
TSI721GetLocalHostId获取本地 Tsi721 的目的 ID。。
TSI721SetLocalHostId设置本地 Tsi721 的目的 ID。
TSI721SrioMaintRead对指定目标 RapidIO 设备产生一个 32 位的 SRIO 维护读请求。
TSI721SrioMaintWrite对指定目标 RapidIO 设备产生一个 32 位的 SRIO 维护写请求。
TSI721SrioWrite使用指定的RapidIO 数据传输请求: NWRITE, NWRITE_R 和 SWRITE。
TSI721SrioRead使用 NREAD RapidIO 数据传输请求。
TSI721CfgR2pWin使用映射窗口 IBWIN 初始化 SR2PC 映射路径。
TSI721FreeR2pWin设备驱动释放指定映射窗口和该窗口对应的共享内存缓冲。
TSI721SrioDoorbellSend发送 RapidIO 门铃消息到指定的目标 RapidIO 设备。
TSI721SrioDoorbellGet获取 Tsi721 接收到的可用呼入门铃消息。
TSI721SrioMsgSend发送 RapidIO 邮箱(mailbox)消息到指定的目标 RapidIO 设备。
TSI721SrioMsgAddRcvBuffer接收MSG
TSI721SrioIbMsgDevIdSet设置 Tsi721 设备的消息目的 ID。
TSI721SrioIbMsgDevIdGet返回 Tsi721 设备的消息目的 ID。

测试用例

测试用例参考官方测试代码:evb_test.c ,其VxWorks版本如下:

/*++
Copyright (c) Integrated Device Technology, Inc.

    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
    KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
    PURPOSE.

File Name:

    evb_test.cpp

Description:

    This is a simple demo program intended for use on TSI721 Evaluation Board.
    It also can be used on any TSI721 based platform that provides a RapidIO switch
    connected to TSI721 SRIO port.

    This program demonstrates how to use IDT TSI721 API routines for provided Windows
    device driver. It performs minimal initialization steps to demonstrate DMA data transfers
    using an external loopback through the attached switch.

    NOTE: If inbound window initialization (TSI721CfgR2pWin) fails on a test system, DMA_BUF_SIZE
    has to be reduced. Normally this failure is caused by system's inability to allocate a common
    buffer of the specified size and alignment.
    
--*/


#include "tsi721api.h"

#include <sysLib.h>
#include <logLib.h>
#include <stdio.h>
#include <string.h>
#include <memLib.h>
#include <stdlib.h>


#define printf_s printf
#define DMA_BUF_SIZE (1 * 1024 * 1024)

#define RIO_DEV_ID_CAR              (0x000000)
#define RIO_SWITCH_PORT_INF_CAR     (0x000014)
#define RIO_COMPONENT_TAG_CSR       (0x00006C)

#define RIO_SWITCH_RTE_DESTID       (0x000070)
#define RIO_SWITCH_RTE_PORT         (0x000074)
#define RIO_SWITCH_PORT_CTL1(n)     (0x00015c + 0x20 * (n))

#define RIO_PORT_GEN_CTRL_CSR       (0x00013C)
#define RIO_PORT_N_ERR_STAT_CSR     (0x000158)

#define RIO_SWITCH_EM_PW_TGTID      (0x1028) /* Port-Write Target Device ID CSR (in CPS1432) */

#define CPS1432_DEV_ID              0x03750038

static VOID tsi721_db_start_thread(VXB_DEVICE_ID hDev) ;
static VOID tsi721_db_stop_thread(VOID) ;

static VOID tsi721_msgrcv_start_thread(DWORD dwMbox);
static VOID tsi721_msgrcv_stop_thread(VOID);

VOID tsi721_msg_send(VXB_DEVICE_ID hDev,DWORD  dwDestId, DWORD  dwMbox, DWORD  msgCount );
static VOID tsi721_msg_print(DWORD dwMbox,DWORD dwSrc,PVOID MsgBuf);

VXB_DEVICE_ID global_hDev ;
volatile BOOL g_bRunDbThread = FALSE;

volatile BOOL g_bRunMsgThread = FALSE;

int evb_test_main(DWORD devNum,DWORD destId,DWORD repeat)
{
    PVOID  obBuf = NULL; /* outbound data buffer */
    PVOID  ibBuf = NULL; /*  inbound data buffer  */
	VXB_DEVICE_ID hDev =NULL ;
	
    DWORD dwRegVal, dwPortInfo, dwTmp;
    DWORD dwDataSize;
    R2P_WINCFG r2pWinCfg;
    DMA_REQ_CTRL dmaCtrl;
    int rnum;
    DWORD  i, dwErr, pass;
	
	
	
    if (!TSI721DeviceOpen(&hDev, devNum, NULL)) {
        printf_s("(%d) Unable to open device tsi721_%d\n", __LINE__, devNum);
        return (ERROR);
    } 
     global_hDev = hDev ;
     
    obBuf =  memalign(DMA_BUF_SIZE,DMA_BUF_SIZE); /*4K 内存 对齐 */
    ibBuf =  memalign(DMA_BUF_SIZE,DMA_BUF_SIZE); 

    if ((obBuf == NULL) || (ibBuf == NULL))
        goto exit;
    
    memset(obBuf, 0,DMA_BUF_SIZE);
    memset(ibBuf,0, DMA_BUF_SIZE);
 
    if (destId == 0xff) {
        /* Get SRIO destID assigned to Tsi721 */
        TSI721GetLocalHostId(hDev, &destId);
        /* Assuming small SRIO system size (address) configuration) */
        destId = (destId >> 16) & 0xff;
    } else {
        /*  Set SRIO destID assigned to Tsi721 */
        dwErr = TSI721SetLocalHostId(hDev, destId);
        if (dwErr != ERROR_SUCCESS) {
            printf_s("(%d) Set Local Host ID failed, err = 0x%x\n", __LINE__, dwErr);
            goto exit;
        }
    }
    

    /*
     Check if SRIO port link is OK
    */
    dwErr = TSI721RegisterRead(hDev, RIO_PORT_N_ERR_STAT_CSR, 1, &dwRegVal);

    if (dwErr != ERROR_SUCCESS) {
        printf_s("(%d) Read port status failed, err = 0x%x\n", __LINE__, dwErr);
        goto exit;
    }

    if (dwRegVal & 0x00010100) {
        printf_s("Port is in error stopped state, status = 0x%08x\n", dwRegVal);
        printf_s("Please reset the board to run this test ...\n");
        goto exit;
    }

    if (dwRegVal & 0x02)
        printf_s("Port status OK, Local SRIO Destination ID = %d (0x%x)\n", destId, destId);
    else {
        printf_s("(%d) Port link status is not OK, status = 0x%08x\n", __LINE__, dwRegVal);
        goto exit;
    } 
    
    

    /*
     Check attached switch device
    */

    /* Read device ID register	*/

    dwErr = TSI721SrioMaintRead(hDev, 0, 0, RIO_DEV_ID_CAR, &dwRegVal);

    if (dwErr != ERROR_SUCCESS) {
        printf_s("(%d) Failed to read switch device ID, err = 0x%x\n", __LINE__, dwErr);

        /* Check if SRIO port link is OK */
        dwErr = TSI721RegisterRead(hDev, RIO_PORT_N_ERR_STAT_CSR, 1, &dwRegVal);

        if (dwErr != ERROR_SUCCESS) {
            printf_s("(%d) Read port status failed, err = 0x%x\n", __LINE__, dwErr);
        } else {
            printf_s("SRIO Port status = 0x%08x\n", dwRegVal);
        }

        goto exit;
    }

    dwErr = TSI721SrioMaintRead(hDev, 0, 0, RIO_SWITCH_PORT_INF_CAR, &dwPortInfo);

    if (dwErr != ERROR_SUCCESS) {
        printf_s("(%d) Failed to read switch port onfo CAR, err = 0x%x\n", __LINE__, dwErr);
        goto exit;
    }

    printf_s("Tsi721 attached to port %d of switch 0x%08x (%d ports)\n",
             dwPortInfo & 0xff, dwRegVal, (dwPortInfo >> 8) & 0xff);
    
    
    /*
     Initialize switch routing table for single loopback route
    */

    dwPortInfo &= 0xff; /* save attached switch port number  */

    dwErr = TSI721SrioMaintWrite(hDev, 0, 0, RIO_SWITCH_RTE_DESTID, destId);
    dwErr = TSI721SrioMaintWrite(hDev, 0, 0, RIO_SWITCH_RTE_PORT, dwPortInfo);

    dwErr = TSI721SrioMaintRead(hDev, 0, 0, RIO_SWITCH_RTE_PORT, &dwTmp);

    printf_s("destID 0x%x routed to port %d\n", destId, dwTmp);

    /*
     verify loopback routing
    */
    dwErr = TSI721RegisterRead(hDev, RIO_DEV_ID_CAR, 1, &dwRegVal);
    dwErr = TSI721SrioMaintRead(hDev, destId, 1, RIO_DEV_ID_CAR, &dwTmp);

    if (dwRegVal == dwTmp) 
        printf_s("Route check OK: regRd (0x%08x) == mntRd (0x%08x)\n", dwRegVal, dwTmp);
    else {
        printf_s("(%d) Route check failed. regRd (0x%08x) != mntRd (0x%08x)\n", __LINE__, dwRegVal, dwTmp);
        goto exit;
    }
    fflush(NULL);
    /*
    // Enable tsi721/switch ports data transfers.
    */

    dwErr = TSI721RegisterWrite(hDev, RIO_PORT_GEN_CTRL_CSR, 0xe0000000); /* set HOST, MAST_EN and DISC bits*/

    /*  Set INPUT_PORT_EN and OUTPUT_PORT_EN bits for the attached switch port  */

    /*  dwErr = TSI721SrioMaintRead(hDev, 0, 0, RIO_SWITCH_PORT_CTL1(dwPortInfo), &dwTmp); */
    dwErr = TSI721SrioMaintWrite(hDev, 0, 0, RIO_SWITCH_PORT_CTL1(dwPortInfo),0xd0600000);

    /* Enable Port-Write notifications  --预留 */
    
    
    /*
    // Initialize inbound SRIO-to-PCIe window (uses IB_WIN number 0)
    */
    void	*InboundTransAddress;
    InboundTransAddress = memalign(DMA_BUF_SIZE,DMA_BUF_SIZE);
    
    r2pWinCfg.BAddrHi = 0;   /* Upper part of base address of R2P window */
    r2pWinCfg.BAddrLo = 0;   /* Lower part of base address of R2P window  */
    r2pWinCfg.BAddrEx = 0;   /* Bits [65:64] of 66-bit base address	*/
    
    r2pWinCfg.TAddrHi =0 ;   /* Upper part of inbound translation address*/
    r2pWinCfg.TAddrLo =(DWORD)InboundTransAddress ;   /* Lower part of inbound translation address*/
        
    r2pWinCfg.Size = DMA_BUF_SIZE;  /* Size of window in bytes (32KB - 16GB) */
    printf_s("(%d)  RIOAddr =0x%x InboundAddress = 0x%x size=0x%x \n",  \
    					__LINE__, r2pWinCfg.BAddrLo,r2pWinCfg.TAddrLo, r2pWinCfg.Size );
	TSI721FreeR2pWin(hDev, 0);
    dwErr = TSI721CfgR2pWin(hDev, 0, &r2pWinCfg);
    if (dwErr != ERROR_SUCCESS) {
        printf_s("(%d) Failed to initialize IB_WIN_0, err = 0x%x\n", __LINE__, dwErr);
        goto exit;
    }
    


     tsi721_db_start_thread(hDev);  
    taskDelay(60);
    /*
    // Initialize doorbell notification receive thread
    */
    dwErr = TSI721SrioDoorbellSend(hDev, destId, 0x1234);
    dwErr = TSI721SrioDoorbellSend(hDev, destId, 0x1234);
    dwErr = TSI721SrioDoorbellSend(hDev, destId, 0x1234);
    dwErr = TSI721SrioDoorbellSend(hDev, destId, 0x1234);
    dwErr = TSI721SrioDoorbellSend(hDev, destId, 0x1234);
    dwErr = TSI721SrioDoorbellSend(hDev, destId, 0x1234);
    if (dwErr) {
        printf_s( "DATA_THR_%d: Error TSI721SrioDoorbellSend(): 0x%x (%d)\n",destId, dwErr, dwErr);
    }
    
    
    /*
    // Initialize message receive thread
    */
    /* make sure that inbound messaging destID matches assigned local destID. */
    TSI721SrioIbMsgDevIdSet(hDev, destId);

     tsi721_msgrcv_start_thread(0); 
    printf_s("Message receive thread is ready for MBOX0 ...\n");
    
    
    for (pass = 1; pass <= repeat || repeat == 0; pass++) {

        if (repeat != 1) {
            printf_s("\nPass %d\n", pass);
            printf_s("Press Q to stop cyclic test\n");
        }
        
        /*
        // Initialize write data
        */
        rnum = 0;

        for (i = 0; i < DMA_BUF_SIZE; i++)
            ((PUCHAR)obBuf)[i] = (UCHAR)(rnum + i);
        
        /*
        // Perform data write operation (data will be written into inbound memory)
        */

        dwDataSize = DMA_BUF_SIZE/2;

        dmaCtrl.bits.Iof = 0;
        dmaCtrl.bits.Crf = 0;
        dmaCtrl.bits.Prio = 0;
        dmaCtrl.bits.Rtype = LAST_NWRITE_R; /* Last packet NWRITE_R, all other NWRITE or SWRITE */
        dmaCtrl.bits.XAddr = 0; /*  bits 65:64 of SRIO address */

        printf_s("Writing %d bytes of data ....\n", dwDataSize);
        fflush(stdout);
        

        dwErr = TSI721SrioWrite(hDev, destId, 0, 0, obBuf, &dwDataSize, dmaCtrl);
        if (dwErr != ERROR_SUCCESS) {
            printf_s("(%d) SRIO_WR Failed, err = 0x%x\n", __LINE__, dwErr);
            goto exit_win;
        }

        /* Read back into different buffer */

        dwDataSize = DMA_BUF_SIZE/2;
        dmaCtrl.bits.Prio = 1;
        dmaCtrl.bits.Rtype = NREAD;
        
        printf_s("Reading %d bytes of data ....\n", dwDataSize);
        fflush(stdout);

        dwErr = TSI721SrioRead(hDev, destId, 0, 0, ibBuf, &dwDataSize, dmaCtrl);
        if (dwErr != ERROR_SUCCESS) {
            printf_s("(%d) SRIO_RD Failed, err = 0x%x\n", __LINE__, dwErr);
            goto exit_win;
        }

        rnum = memcmp(obBuf, ibBuf, DMA_BUF_SIZE/2);

        if (rnum == 0)
            printf_s("Data transfer test completed successfully\n");
        else {
            printf_s("ERROR: Data transfer test failed\n");
            goto exit_win;
        }

        fflush(stdout);    
        
        printf_s("Sending  messages to MBOX0 ...\n");
        tsi721_msg_send(hDev, destId, 0, 10);
        /*Msg Recv Test*/
        if(0)
        {
        	DWORD dwMsgBufSize = 0x1000 ;
        	PUCHAR msgBufPtr = NULL;
        	LPOVERLAPPED lpOvl;
			msgBufPtr = (PUCHAR)memalign(0x1000, 0x1000);
			if (msgBufPtr == NULL) {
				printf_s("ERR: Unable to allocate aligned buffer for IB_MSG\n");
				goto exit_win;
			}
        	
			lpOvl = (LPOVERLAPPED)malloc(sizeof(OVERLAPPED));
			
			dwErr = TSI721SrioMsgAddRcvBuffer(hDev, 0, msgBufPtr,
	                                            &dwMsgBufSize, lpOvl);
			
			 
	        if (OK != dwErr) {
	            printf_s("MSG_WAIT: IOCTL error 0x%x (%d)\n", dwErr, dwErr);
	            goto exit_win;
	        }
	        
	        tsi721_msg_print(0,dwMsgBufSize,msgBufPtr);
	        
	        free(msgBufPtr);
	        free(lpOvl);
	        
        	
        }
        
    }/* end for (pass = 1; pass <= repeat || repeat == 0; pass++) { */
    
    
    
    printf_s("\nTsi721 EVB Test finished.\n");
    
    
    /*
    // The pause below allows user to test asynchronous notification events
    // generated by external sources (Port-Writes, inbound doorbells and messages to MBOX0) 
    */
    printf_s("\nPress any key to exit ....\n");
    
    
  /*  getchar(); */
    

     
   exit_win:
 
   /* tsi721_db_stop_thread();
   tsi721_msgrcv_stop_thread() ;
   */
   /*
   // Free an inbound window mapping before exit
   */
   dwErr = TSI721FreeR2pWin(hDev, 0);
   exit:
   	   TSI721DeviceClose(hDev, NULL);
   	   free(obBuf);
   	   free(ibBuf);
    return (ERROR);
}



VOID sendDoorbell(int count)
{
	int i =0 ;
	  for(i=0;i<count;i++){
		 if(i%2048 ==0 )taskDelay(10);
	  TSI721SrioDoorbellSend(global_hDev, 1, i);
	  }
}

sendMsg(int count)
{
	tsi721_msg_send(global_hDev,1, 0 ,  count) ;
}

VOID
tsi721_msgrcv_thread(
    PVOID params
    )
{
	VXB_DEVICE_ID hDev = global_hDev;
    DWORD dwMbox = (DWORD)params;
    DWORD dwError;
    DWORD i;
    PUCHAR msgBufPtr = NULL;
    
	DWORD dwMsgBufSize = 0x1000 ;
	LPOVERLAPPED lpOvl;
	msgBufPtr = (PUCHAR)memalign(0x1000, 0x1000);
	if (msgBufPtr == NULL) {
		printf_s("ERR: Unable to allocate aligned buffer for IB_MSG\n");
		 
	}
	lpOvl = (LPOVERLAPPED)malloc(sizeof(OVERLAPPED));
	
	while(g_bRunMsgThread)
	{
		dwError = TSI721SrioMsgAddRcvBuffer(hDev, 0, msgBufPtr,
											&dwMsgBufSize, lpOvl);
		
		if (OK != dwError) {
		/*	printf_s("MSG_WAIT: IOCTL error 0x%x (%d)\n", dwError, dwError); */
		  continue ;
		}
		/* printf_s("TSI721SrioMsgAddRcvBuffer SrcId=  (%d)\n", lpOvl->MsgSrcId);
		 * *
		
		
		tsi721_msg_print(0, ( lpOvl->MsgSrcId<<16 )|dwMsgBufSize ,msgBufPtr);
		 */
	}
	
	g_bRunMsgThread = FALSE;
    free(msgBufPtr);
    free(lpOvl);
    
}



static VOID tsi721_msgrcv_start_thread(DWORD dwMbox)
{
	 int tsi721_msg;
	 g_bRunMsgThread = TRUE;
	 tsi721_msg = taskSpawn("tsi721_msgrcv_start_thread",201,0,10000,(FUNCPTR)tsi721_msgrcv_thread, (PVOID)dwMbox,0,0,0,0,0,0,0,0,0);
		
}
 
static VOID tsi721_msgrcv_stop_thread(VOID)
{
	 g_bRunMsgThread = FALSE;
	
}




VOID
tsi721_msg_send(
	VXB_DEVICE_ID hDev,
    DWORD  dwDestId,
    DWORD  dwMbox,
    DWORD  msgCount
    )
{
    OVERLAPPED ovl;
    DWORD dwError;
    PUCHAR msgBuf = NULL;
    DWORD dwBufLen;
    int i= 0 ;


    memset(&ovl, 0, sizeof(ovl));
	
    /*
    // Allocate single message buffer 4KB (has to be aligned to the page boundary)
    // NOTE: we will send messages shorter than allocated buffer but size can be increased
    // up to 4KB if required.
    */
    msgBuf = (PUCHAR)memalign(0x1000, 0x1000);
    if (msgBuf == NULL) {
        printf_s("ERR: Unable to allocate aligned buffer for IB_MSG\n");
        goto err_exit;
    }
    
    for(i=0;i<msgCount;i++)
    {
        dwBufLen = 128  ;
        if (dwBufLen > 0x1000)
            dwBufLen = 0x1000;

        memset(msgBuf, i, dwBufLen);
        msgBuf[0] =  i &0xFF ;
        msgBuf[1] =  (i>>8) &0xFF ;
        msgBuf[2] =  (i>>16) &0xFF ;
        msgBuf[3] =  (i>>24) &0xFF ;
        
        /*中断快速 任务优先级低,得不到执行 导致丢包。*/
        if(msgCount % 2048 == 0)
        	taskDelay(10);
        dwError = TSI721SrioMsgSend(hDev, 0, dwDestId, msgBuf, &dwBufLen, &ovl);

    
        if (ERROR_SUCCESS != dwError) {
            printf_s("MSG_SEND: IOCTL error: 0x%x (%d) \n", dwError, dwError);
            break;
        }
    }
    
    err_exit:
    	free(msgBuf);
    	return ;
}



static VOID tsi721_msg_print(
    DWORD dwMbox,
    DWORD dwSrc,
    PVOID MsgBuf
    )
{
    PUCHAR msgBuf = (PUCHAR)MsgBuf;
    static DWORD count = 0;

    printf_s("MSG[%d] from %d mbox%d sz=%d: 0x%02x %02x %02x %02x %02x %02x %02x %02x\n", ++count, dwSrc & 0xffff,
             dwMbox, (dwSrc >> 16) & 0xffff,
             msgBuf[0], msgBuf[1], msgBuf[2], msgBuf[3], msgBuf[4], msgBuf[5], msgBuf[6], msgBuf[7]);
}

#define DOBELL_SID(buf)			(((UINT8)buf[2] << 8) | (UINT8)buf[3])
#define DOBELL_TID(buf)			(((UINT8)buf[4] << 8) | (UINT8)buf[5])
#define DOBELL_INF(buf)			(((UINT8)buf[0] << 8) | (UINT8)buf[1])
    

VOID
tsi721_db_thread( PVOID params)
{
	VXB_DEVICE_ID hDev = (VXB_DEVICE_ID)params ;
	UINT8 DbBuf[512] ;
	DWORD DbSize=0 ;
	 DWORD dwErr;
	  while (g_bRunDbThread) {
		
		dwErr =  TSI721SrioDoorbellGet(global_hDev,   DbBuf, &DbSize) ;
		  if (dwErr) {
			/*	printf_s( "TSI721SrioDoorbellGet: Error  : 0x%x (%d)\n", dwErr, dwErr);
			 * 
			 */
			   continue ;
			}
		  /*
		  printf_s( "TSI721SrioDoorbellGet:size=%d  SID=%d TID=%d INFO=0x%x \n", 
				  DbSize, DOBELL_SID(DbBuf),DOBELL_TID(DbBuf),DOBELL_INF(DbBuf)	);
		        */		
	  }
	  
	    g_bRunDbThread = FALSE;
	    printf_s("DB_WAIT: Exit notification thread\n");
}

static VOID tsi721_db_start_thread(VXB_DEVICE_ID hDev)
{

	int tsi721_db ;
	g_bRunDbThread = TRUE ;
	tsi721_db = taskSpawn("tsi721_db_start_thread",99,0,80*1000,(FUNCPTR)tsi721_db_thread,hDev,0,0,0,0,0,0,0,0,0);
	
}

static VOID tsi721_db_stop_thread(VOID)
{
	 g_bRunDbThread = FALSE;
	
}

综述

我们的VxWorks TSI721驱动版本,基本支持RapidIO所有通信方式,接口名称参数基本和Windows版本一致,有意合作的可以留言或者私信QQ邮箱:qinshimi_yue@foxmail.com。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值