VxWorks下TSI721驱动开发
概述
基于X86主控单元和VxWorks 6.9操作系统开发TSI721板卡驱动,硬件板卡资料参考我的博客[Windows 下TSI721驱动软件使用](https://editor.csdn.net/md/?articleId=114711812),调试使用的启动方式为UEFI U盘启动。提供给用户的接口,也是参考Windows下官方的用户函数接口,保持用户对两种操作系统软件使用的方式方法一致。
邮箱:qinshimi_yue@foxmail.com
Vxworks下驱动
-
填充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
};
-
通过向tsi721PciDevIDList数组中添加记录,完成设备的注册;
/*
* List of supported device IDs.
*/
LOCAL struct vxbPciID tsi721PciDevIDList[] =
{
/* { devID, vendID } */
{ TSI721_DEVID, IDT_VENDORID },//板卡1
{ TSI721_DEVID, IDT_VENDORID } //板卡2 ,针对两个TSI721设备的可以加两个
};
-
Vxworks启动是会实例化tsi721PciDevIDList中的设备(不必人工干预);
-
在tsi721Funcs中注册的几个初始化函数中添加实际的设备驱动代码;
LOCAL struct drvBusFuncs tsi721Funcs =
{
tsi721InstInit, /* devInstanceInit */
tsi721InstInit2, /* devInstanceInit2 */
tsi721InstConnect /* devInstanceConnect */
};
- 在tsi721InstInit2中添加对TSI721设备的维护包,门铃,消息通信,DMA通信的初始化,以及挂载中断处理函数。
- 实现维护包读写操作;
- 实现门铃收发操作;
- 实现MSG消息通信;
- 实现NREAD ,NWRITE,NWRITE_R操作;
- 编写测试用例,测试这些基本接口。
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。