整理反射内存卡资料整理.docx
《整理反射内存卡资料整理.docx》由会员分享,可在线阅读,更多相关《整理反射内存卡资料整理.docx(17页珍藏版)》请在冰豆网上搜索。
整理反射内存卡资料整理
一、反射内存卡基本特征
型号:
vmipci-5565-11000
1.板载内存128MB,地址空间:
0x0~0x7FFFFFF
2.4kFIFOs
3.TransmissionMode=Multimode
4.NoConformalCoating保形[角]涂料
二、中断式通信流程
图1中断式通信流程图
2.1特点:
一、发送方和接收方通过事件进行同步,CPU占用少;
二、发送方可以向多个指定的接收方发送数据,即1对多方式;也可以实现广播方式。
2.2注意事项:
1.当接收方调用RFM2gWaitForEvent函数后,将挂起当前线程。
直到有事件发生或等待超时才能恢复,因此接收部分的代码应采用多线程编程;
2.RFM2gSendEvent需要指定接收设备的NodeID,该参数由板卡上的跳线决定(EachRFM2gdeviceonanRFM2gnetworkisuniquelyidentifiedbyitsnodeID,whichismanuallysetbyjumpersonthedevicewhentheRFM2gnetworkisinstalled.ThedriverdeterminesthenodeIDwhenthedeviceisinitialized)。
本机的NodeID可以通过APIRFM2gNodeID获取;如果采取广播方式,则参数NodeID应指定为宏定义RFM2G_NODE_ALL;
3.数据读写有两种方式:
直接读写和内存映射。
直接读写的相关函数有:
RFM2gRead和RFM2gWrite。
内存映射的相关函数有:
RFMUserMemory和RFMUnMapUserMemory。
后者将板载内存按页(page)映射到程序的内存空间,对映射内存的操作将直接反应到板载内存上。
按照手册的解释:
使用内存映射后,数据的传输将使用PIO方式,不使用DMA方式。
而直接读写函数的数据传输将尽可能采取DMA方式。
三、代码
3.1收发一体的通信代码
(摘自例程rfm2g_send.c,为便于理解,去掉了其中的错误处理代码):
#include"rfm2g_windows.h"//屏蔽在Vs2005中编译时的警告
#include"rfm2g_api.h"//rfmAPI
#defineBUFFER_SIZE256//缓冲区大小256byte
#defineOFFSET_10x1000//写数据起始位置4k
#defineOFFSET_20x2000//读数据起始位置8k
#defineTIMEOUT60000//超时时间60s
#defineDEVICE_PREFIX"\\\\.\\rfm2g"//win系统的PCI设备名前缀
RFM2G_STATUSresult;//RFM2gAPI调用的返回值,成功为RFM2G_SUCCESS
RFM2G_CHARdevice[40];//完整的设备名由前缀和设备编号组成
RFM2GHANDLEHandle=0;//设备操作句柄,由RFM2gOpen返回
//构造设备名,如"\\\\.\\rfm2g1"
sprintf(device,"%s%d",DEVICE_PREFIX,numDevice);
//打开设备
result=RFM2gOpen(device,&Handle);
//使网络中断可用。
默认情况下,反射内存网的中断是不可用的,RFM2gEnableEvent函数使得接收设备可以响应网络中断。
如果发送方不需响应中断,则不必调用该函数
result=RFM2gEnableEvent(Handle,RFM2GEVENT_INTR2);
//将数据写入反射内存卡的板载内存。
result=RFM2gWrite(Handle,OFFSET_1,(void*)outbuffer,BUFFER_SIZE*4);
/*在板载内存的有效范围之内,从第二个参数指定起始地址开始写入数据。
写入的长度按字节计算。
字长换算法则:
1byte=1RFM2G_UINT8
1word=1RFM2G_UINT16=2*RFM2G_UINT8
1longword=1RFM2G_UINT32=4*RFM2G_UINT8
*/
//发网络中断
result=RFM2gSendEvent(Handle,otherNodeId,RFM2GEVENT_INTR1,0);
//等待中断
RFM2GEVENTINFOEventInfo;
EventInfo.Event=RFM2GEVENT_INTR2;//等待的网络中断类型
EventInfo.Timeout=TIMEOUT;//等待多久即超时
result=RFM2gWaitForEvent(Handle,&EventInfo);//调用后程序挂起
//读数据.与RFM2gWrite函数类似,需要事先分配读取缓冲和指定读取数据的长度
result=RFM2gRead(Handle,OFFSET_2,(void*)inbuffer,BUFFER_SIZE*4);
//关闭设备
RFM2gClose(&Handle);
//通用错误处理
if(result!
=RFM2G_SUCCESS)
{
printf("Error:
%s\n",RFM2gErrorMsg(result));
RFM2gClose(&Handle);
return(result);
}
3.2测试用代码段
3.2.1获取板卡配置信息
RFM2G_STATUSStatus;
RFM2GCONFIGConfig;
/*GettheboardConfiguration*/
Status=RFM2gGetConfig(Handle,&Config);
if(Status!
=RFM2G_SUCCESS)
{
printf("CouldnotgettheboardConfiguration.\n");
printf("Error:
%s.\n\n",RFM2gErrorMsg(Status));
return(-1);
}
/*Printboardconfiguration*/
printf("DriverPartNumber\"%s\"\n",Config.Name);
printf("DriverVersion\"%s\"\n",Config.DriverVersion);
printf("DeviceName\"%s\"\n",Config.Device);
printf("BoardInstance%d\n",Config.Unit);
printf("BoardID0x%02X\n",Config.BoardId);
printf("NodeID0x%02X\n",Config.NodeId);
printf("InstalledMemory%ud(0x%08X)\n",
Config.MemorySize,Config.MemorySize);
printf("MemoryOffset:
");
switch(Config.Lcsr1&0x0030000)
{
case0x00000000:
printf("0x00000000\n");
break;
case0x00010000:
printf("0x04000000\n");
break;
case0x00020000:
printf("0x08000000\n");
break;
case0x00030000:
printf("0x0c000000\n");
break;
default:
/*S/WError*/
printf("\n");
}
printf("BoardRevision0x%02X\n",Config.BoardRevision);
printf("PLXRevision0x%02X\n",Config.PlxRevision);
/*DisplayBoardConfiguration*/
printf("Config.Lcsr10x%08x\n",Config.Lcsr1);
printf("RFM2gConfiguration:
\n");
if(Config.Lcsr1&0x01000000)
{
printf("RogueMaster0Enabled\n");
}
if(Config.Lcsr1&0x02000000)
{
printf("RogueMaster1Enabled\n");
}
if(Config.Lcsr1&0x04000000)
{
printf("RedundantMode\n");
}
else
{
printf("FastMode\n");
}
if(Config.Lcsr1&0x08000000)
{
printf("LocalBusParityEnabled\n");
}
if(Config.Lcsr1&0x10000000)
{
printf("LoopbackEnabled\n");
}
if(Config.Lcsr1&0x20000000)
{
printf("Dark-on-DarkEnabled\n");
}
if(Config.Lcsr1&0x40000000)
{
printf("TransmitterDisabled\n");
}
/*PCIConfigurationInfo*/
printf("RFM2gPCIConfiguration:
\n");
printf("bus0x%02x\n",Config.PciConfig.bus);
printf("function0x%02x\n",Config.PciConfig.function);
printf("type0x%04x\n",Config.PciConfig.type);
printf("devfn0x%08x\n",Config.PciConfig.devfn);
printf("revision0x%02x\n",Config.PciConfig.revision);
printf("rfm2gOrBase0x%08x\n",Config.PciConfig.rfm2gOrBase);
printf("rfm2gOrWindowSize0x%08x\n",Config.PciConfig.rfm2gOrWindowSize);
printf("rfm2gOrRegSize0x%08x\n",Config.PciConfig.rfm2gOrRegSize);
printf("rfm2gCsBase0x%08x\n",Config.PciConfig.rfm2gCsBase);
printf("rfm2gCsWindowSize0x%08x\n",Config.PciConfig.rfm2gCsWindowSize);
printf("rfm2gCsRegSize0x%08x\n",Config.PciConfig.rfm2gCsRegSize);
printf("rfm2gBase0x%08x\n",Config.PciConfig.rfm2gBase);
printf("rfm2gWindowSize0x%08x\n",Config.PciConfig.rfm2gWindowSize);
printf("interruptNumber0x%02x\n",Config.PciConfig.interruptNumber);
3.2.2测试反射内存网连接
RFM2G_STATUSstatus;
/*Iftheringisintact,the"own-data"bitwillbeset*/
status=RFM2gCheckRingCont(cmd->Handle);
if(status==RFM2G_SUCCESS)
{
printf("TheReflectiveMemorylinkisintact.\n");
}
else
{
printf("Error:
%s.\n\n",RFM2gErrorMsg(status));
}
3.2.3DMA性能测试
RFM2G_INT32index;/*Selectsappropriatenomenclature*/
char*name;/*Localpointertocommandname*/
char*desc;/*Localpointertocommanddescription*/
RFM2G_STATUSStatus;
time_ttime1;/*ANSICtime*/
doublemBytePerSec=0;
intnumBytes=0;
intnumIterations=10000;
intcount;
inttimeToRunTest=2;/*Timetoruntestsinseconds*/
RFM2G_UINT32dmaThreshold;
/*GettheDMAThreshold*/
RFM2gGetDMAThreshold(Handle,&dmaThreshold);
printf("\nRFM2gPerformanceTest(DMAThresholdis%d)\n",dmaThreshold);
printf("---------------------------------------------------\n");
printf("BytesReadIOpsReadMBpsWriteIOpsWriteMBps\n");
for(numBytes=0;numBytes{
if(numBytes<32)
{
numBytes+=4;
}
elseif(numBytes<128)
{
numBytes+=32;
}
elseif(numBytes<2048)
{
numBytes+=128;
}
elseif(numBytes<4096)
{
numBytes+=512;
}
elseif(numBytes<16384)
{
numBytes+=4096;
}
elseif(numBytes<131072)
{
numBytes+=16384;
}
elseif(numBytes<262144)
{
numBytes+=65536;
}
else
{
numBytes+=262144;
}
numIterations=0;
if(time(&time1)==-1)
{
printf("ANSICtimefunctionreturnedERROR\n");
return(-1);
}
/*Waitforthetimertogettothebeginingofasecond*/
while(difftime(time(0),time1)==0)
{
/*Let'swait*/
count++;
}
/*Getthestarttime*/
time(&time1);
/*Theaccuracyoftheresultsisdependentontheamountoftime
thetestrunsandtheNumberofIO'spersecond.Thisisnota
precisetest,thepriorityofthistaskalongwiththelimited
resolution(1Sec)oftheANSICtimefunctionaffectsthe
precision.*/
while(difftime(time(0),time1){
Status=RFM2gRead(Handle,
0,/*rfmOffset*/
(void*)MemBuf,
numBytes);
if(Status!
=RFM2G_SUCCESS)
{
printf("RFM2gRead:
Failure\n");
printf("Error:
%s.\n\n",RFM2gErrorMsg(Status));
return(-1);
}
numIterations++;
}
/*CalculateMByte/Sec=Totalnumberofbytestransferred/(Time
inseconds*1024*1024)*/
mBytePerSec=(double)(numBytes*numIterations)/(timeToRunTest*
1024.0*1024.0);
printf("%8d%10d%6.1f",numBytes,
(numIterations/timeToRunTest),mBytePerSec);
numIterations=0;
time(&time1);
/*Waitforthetimertogettothebeginingofasecond*/
while(difftime(time(0),time1)==0)
{
/*Let'swait*/
count++;
}
/*Getthestarttime*/
time(&time1);
/*PerformtheIOuntiltheelapsedtimeoccurs*/
while(difftime(time(0),time1){
Status=RFM2gWrite(Handle,
0,/*rfmOffset*/
(void*)MemBuf,
numBytes);
if(Status!
=RFM2G_SUCCESS)
{
printf("RFM2gWrite:
Failure\n");
printf("Error:
%s.\n\n",RFM2gErrorMsg(Status));
return(-1);
}
numIterations++;
}
mBytePerSec=(double)(numBytes*numIterations)/(timeToRunTest*
1024.0*1024.0);
printf("%10d%6.1f\n",
(numIterations/timeToRunTest),mBytePerSec);
}/*for*/
3.3常用API
3.3.1RFM2gOpen()
SeveralprogramsandexecutionthreadsmayhavethesameRFM2ginterfaceopenatanygiventime.ThedriverandtheAPIlibraryarethread-safe;(该函数支持多线程)
Syntax
STDRFM2GCALLRFM2gOpen(char*DevicePath,RFM2GHANDLE*rh);
Parameters
●DevicePathPathtospecialdevicefile(I).Refertoyourdriver-specificmanualfortheformatofDevicePath.
●rhPointertoanRFM2GHANDLEstructure(IO).
3.3.2RFM2gClose()
OncetheRFM2ghandleisclosed,allofthefacilitiesusingthathandlearenolongeraccessible,includingthelocalRFM2gmemory,whichmaybemappedintotheapplicationprogram’svirtualmemoryspace.
Syntax
STDRFM2GCALLRFM2gClose(RFM2GHANDLE*rh);
Parameters
rhInitializedpreviouslywithacalltoRFM2gOpen()(I).
3.3.3RFM2gRead()
TheRFM2gdriverattemptstofulfilltheRFM2gRead()requestusingthebusmasterDMAfeatureavailableontheRFM2gdevice.ThedriverwillmovethedatausingtheDMAfeatureifthelengthoftheI/OrequestisatleastaslongastheminimumDMAthreshold.
IftheRFM2gdevicedoesnotsupportthebusmasterDMAfeature,oriftheI/Orequ