您好,欢迎来到抵帆知识网。
搜索
您的当前位置:首页XPC环境下PCI板卡驱动

XPC环境下PCI板卡驱动

来源:抵帆知识网


项目名称:硬件在环

XPC环境下PCI板卡驱动

编写方法

编 写 人:张永光 编写时间:2010.4.12 部 门 名:APP组 审 核 人: 审核时间:

XPC环境下PCI板卡驱动编写方法

修订页

编号 1

1

章节名称 修订内容简述 修订日期 2009.4.12 修订前 修订后 版本号 版本号 修订人 批准人 全部 创建 张永光 XPC环境下PCI板卡驱动编写方法

目录

1

引言........................................................................................................................................... 3 1.1 编写目的 ....................................................................................................................... 3 1.2 背景 ............................................................................................................................... 3 1.3 定义 ............................................................................................................................... 3 1.4 参考资料 ....................................................................................................................... 3 2 驱动的编写方法 ....................................................................................................................... 4

2.1 什么是S-Function ........................................................................................................ 4 2.2 驱动创建方法 ............................................................................................................... 4 2.3 C S-Function 模板 ....................................................................................................... 5

2.3.1 驱动流程 ........................................................................................................... 5 2.3.2 预处理 ............................................................................................................... 8 2.3.3 mdlInitializeSizes .............................................................................................. 8 2.3.4 mdlInitializeSampleTimes ................................................................................. 9 2.3.5 mdlStart ........................................................................................................... 10 2.3.6 mdlOutputs ...................................................................................................... 11 2.3.7 mdlterminate ................................................................................................... 11 2.3.8 末尾的条件编译语句 ..................................................................................... 11

3 驱动编写示例 ......................................................................................................................... 12

3.1 编写C文件 ................................................................................................................ 12 3.2 封装成S-function ....................................................................................................... 15 4 软件相关信息 ......................................................................................................................... 20

4.1 程序文件列表 ............................................................................................................. 20 4.2 运行平台 ..................................................................................................................... 20 4.3 编程语言 ..................................................................................................................... 20 附录 ................................................................................................................................................ 21

2

XPC环境下PCI板卡驱动编写方法

1 引言

1.1 编写目的

本文详细介绍了如何使用Matlab的C MEX S-Function编写XPC环境下板卡驱动的方法。本文的主要目的是使相关开发人员阅读之后能够了解XPC的工作原理并能开发实际的驱动程序。

本文适合项目组领导者及相关项目设计,编码和测试人员参考。也适合想学习C MEX S-Function的人员

1.2 背景

XPC半实物仿真目标是个基于RTW的低端实时仿真和开发平台,可将Intel80x86/Pentium计算机转变为一个实时系统。不需第三方操作系统的支持,在计算机上配置输入输出设备就能和外部交换信息,进行硬件在环仿真和测控系统开发。 XPC实时系统包括1台主机和1台目标机。主机上用Matlab , Simulink完成建模,生成模型文件,然后调用Real-Time Workshop工具箱,生成包含设备驱动程序的xPC目标,通过通信电缆下载到目标机上;目标机启动时装载xPC工具箱提供的实时内核,该内核保证目标的实时高速运行,目标机上配有输入输出设备和外部交换信息。 XPC目标工具箱自带的驱动程序有如下局限性: (1)只支持一些知名厂商的部分设备,基本不支持国产设备; (2)对于支持的某些设备,不支持其某些功能,或支持的功能无法满足要求,这时须开发驱动程序。

1.3 定义

S-Function:system function,MATLAB的系统函数 C MEX S-Function:用c语言编写的S-Function

xPC:基于RTW的低端实时仿真和开发平台,可将Intel80x86/Pentium计算机转变为一个实时系统。

1.4 参考资料

【1】 MATLAB的help文件

【2】 基于MATLAB/Simulink的系统仿真技术与应用 【3】 基于MATLAB的硬件驱动开发

3

XPC环境下PCI板卡驱动编写方法

2 驱动的编写方法

2.1 什么是S-Function

S-Function是system-function的缩写。当MATLAB所提供的模型不能完全满足用户需要时,就可以通过S-Function提供给用户自己编写程序来满足自己要求模型的接口。 S-Function 使用一种特殊的调用格式让你可以与Simulink 方程求解器相互作用,这与发生在求解器和内置Simulink 块之间的相互作用非常相似。S-Function 的形式是非常通用的,且适用于连续、离散和混合系统。

S-function 提供了一种在Simulink 模型中增加自制块的手段,你可以使用MATLAB,C,C++,Ada,或Fortran 语言来创建自己的块。按照下面一套简单的规则,你可以在S-function 中实现自己的算法。在你编写一个S-Function 函数,并将函数名放置在一个S-Function 块中(在用户定义的函数块库中有效)之后,通过使用masking 定制用户界面。

2.2 驱动创建方法

(1) 用c语言编写一个驱动,保存为c文件,如DO1727.c;

(2) 编写好之后,在matlab下使用mex命令将编写好的c文件编译成mex文件,

提供给s-function模块使用,如: mex DO1727.c;

(3) 打开simulink,创建一个library,保存为一个mdl文件,如DO1727.mdl; (4) 在新建的library中,创建一个S-function,从simulink库中拖出一个S-function

Block到新建的library中;

(5) 配置好s-function,在S-function name中填写驱动的名字,S-function parameter

中填写需要输入的变量用,逗号分隔开来; (6) 通过mask对新建的block进行包装;

(7) 将保存好的mdl文件移动到matlabroot\oolbox\\rtw\argets\\xpc\arget\\build

\\xpcblocks\hirdpartydrivers文件夹中去;

(8) 为了能够将新建的驱动导入到simulink库中,需要创建一个m文件,在

matlabroot\oolbox\\rtw\argets\\xpc\arget\\build\\xpcblocks\hirdpartydrivers文件夹中找到sample_xpcblocks.m文件,将sample改为需要创建的库的名字,如advantech_xpcblocks.m,在文件中,修改out.Library = 'your_company_namelib'和out.Name = 'your_company_namelib Blockset',将your_company_namelib改为创建的库的名字,如

out.Library = 'advantech'; out.Name = 'advantech';

(9) 通过上述步骤,新建的驱动就已经被封装到simulink库中了,在matlab中输入

rehash toolbox,再重新打开simulink,就可以在simulink中找到刚刚封装进去的库。

4

XPC环境下PCI板卡驱动编写方法

(10) 为了能在xpc信息中看到自己添加的板卡,需要创建一个supported文件,从

matlabroot\oolbox\\rtw\argets\\xpc\arget\\build\\xpcblocks\hirdpartydrivers文件夹中找到your_company_namelib_supported.m,保存为*_supported.m,如advantech_supported.m,将文件里的数据结构前面的注释号去掉,将分号里的信息改成自己的板卡的信息,如

boards(1).VendorID = '13FE'; boards(1).DeviceID = '1727'; boards(1).SubVendorID = '13FE'; boards(1).SubDeviceID = 'A102'; boards(1).DeviceName = '1727'; boards(1).VendorName = 'advantech'; boards(1).DeviceType = 'advantech 1727';

前面四个可以从xpc信息中看到,后面三个是自己填写,可以添加任意个板卡信息,从boards(1)开始;

2.3 C S-Function 模板 2.3.1 驱动流程

Simulink 模型的执行分几个阶段进行。首先进行的是初始化阶段,在此阶段,Simulink 将库块合并到模型中来,确定传送宽度、数据类型和采样时间,计算块参数,确定块的执行顺序,以及分配内存。然后,Simulink 进入到“仿真循环”,每次循环可认为是一个“仿真步”。在每个仿真步期间,Simulink 按照初始化阶段确定的块执行顺序依次执行模型中的每个块。对于每个块而言,Simulink 调用函数来计算块在当前采样时间下的状态,导数和输出。如此反复,一直持续到仿真结束。

S-function的函数流程如下图所示,几个必需的函数用实线表示,其它用虚线表示:

5

XPC环境下PCI板卡驱动编写方法

仿真开始mdlInitializeSIzes设置输入、输出、状态、参数个数等mdlInitializeSampleTime初始化采样时间mdlStart仿真开始前调用一次,用户可以在此填入仿真开始前需要做的内容mdlInitializeConditions初始化状态变量Major time stepmdlProcessParameters当参数改变时调用该函数mdlGetTimeOfNextVarHit当采样时间改变时调用该函数mdlOutput计算输出Simulation LoopmdlUpdata更新离散状态当系统含有连续状态时调用。计算连续状态的导数和输出mdlDerivativesmdlOutputMajor time stepmdlDerivativesmdlOutputmdlZeroCrossings当检测到过零时调用mdlTerminate仿真结束时调用仿真结束图1 S-function流程图

6

XPC环境下PCI板卡驱动编写方法

C MEX 文件S-function 所需实现的只是由Simulink 定义的一组很少的回调函数,一个基本的C MEX S-function 内包含的回调函数如下图所示:

仿真开始mdlInitializeSizesmdlInitializeSampleTimes初始化mdlstartmdlOutputs仿真循环mdlTerminate

一个 C MEX S-function 的一般格式如下:

#define S_FUNCTION_NAME your_sfunction_name_here #define S_FUNCTION_LEVEL 2 #include \"simstruc.h\" static void mdlInitializeSizes(SimStruct *S) { } < 附加的S-function程序/代码> static void mdlTerminate(SimStruct *S) { } #ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */ 7

XPC环境下PCI板卡驱动编写方法

#include \"simulink.c\" /* MEX-file interface mechanism */ #else #include \"cg_sfun.h\" /* Code generation registration function */ #endif 当 Simulink 与S-function 相互作用时,Simulink 所调用的第一个程序是mdlInitializeSizes,随后调用的是其它S-function 函数(所有的函数名均以mdl 开头)。在仿真结束时,Simulink 调用mdlTerminate函数。

2.3.2 预处理

该范例以以下的定义开头:

#define S_FUNCTION_NAME DO1727 #define S_FUNCTION_LEVEL 2

第一条指定了 S-function 的名字(DO1727),第二条指定了该S-function 是按照level 2 的格式进行编写的,level 2 的格式可以自由的增加或减少输入输出口的数量。

2.3.3 mdlInitializeSizes

Simulink 调用mdlInitializeSizes 来获取输入端口和输出端口的数量、端口宽度、以及S-function 所需的任何其它对象(诸如状态数量)等有关信息。

这个函数包括的一些基本函数如下: ssSetNumSFcnParams(S, 0); /*设置S函数的参数个数(用参数数目代替其中的0) */ if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { /*检查S函数参数数目是否与设置的一致*/ return; /*如果不一致则直接返回*/ } ssSetNumContStates(S, 0); /*设置S函数的连续状态个数*/ ssSetNumDiscStates(S, 0); /*设置S函数的离散状态个数*/ if (!ssSetNumInputPorts(S, 1)) return; /*设置S函数的输入端口个数为1*/ ssSetInputPortWidth(S, 0, 1); 8

XPC环境下PCI板卡驱动编写方法

/*设置S函数输入端口的宽度,即维度,一般设置为1 */ ssSetInputPortRequiredContiguous(S, 0, true); /*设置各个输入端口中的元素是否存放在连续内存中*/ ssSetInputPortDirectFeedThrough(S, 0, 1); /*设置S函数存在直接反馈*/ /*直接馈通意味着输出直接受控于一个输入口的值。*/ if (!ssSetNumOutputPorts(S, 1)) return; /*设置S函数的输出端口个数为1*/ ssSetOutputPortWidth(S, 0, 1); /*设置S函数输出端口的宽度*/ ssSetNumSampleTimes(S, 1); /*设置抽样时间个数(抽样时间在mdlInitializeSampleTimes中定义)*/ ssSetNumRWork(S, 0); /*设置浮点数工作向量的长度*/ ssSetNumIWork(S, 0); /*设置整数工作向量的长度*/ ssSetNumPWork(S, 0); /*设置指针工作向量的长度*/ ssSetNumModes(S, 0); /*设置工作模式向量的长度*/ ssSetNumNonsampledZCs(S, 0); /*设置过零点检测状态的长度*/ ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE); /*指定sim状态与内置的模块一致*/ ssSetOptions(S, 0); /*设置S函数工作模式的选项*/ 2.3.4 mdlInitializeSampleTimes

Simulink 调用mdlInitializeSampleTimes来设置s-function的抽样时间和抽样时间偏移。

/*设置抽样时间*/ ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); /*设置抽样时间偏移*/ ssSetOffsetTime(S, 0, 0.0); 9

XPC环境下PCI板卡驱动编写方法

2.3.5 mdlStart

这里开始对板卡进行操作,主要是PCI板卡地址的获取和板卡寄存器的初始化。 对于PCI板卡,其地址是计算机自动分配的,如果硬件有变动,其地址也会变动,所以用户不能事先确定,地址一般是映射到I/O空间中去的,对板卡的操作都是通过直接读写其地址实现的。

首先要获取板卡的基址,xpc提供了一个函数rl32eGetPCIInfo来获取PCI设备的基址:

rl32eGetPCIInfo((unsigned short)Vendor_ID, (unsigned short)Device_ID, &pciinfo) Vendor_ID是设备的厂商标示,由PCI总线协会唯一指定,Device_ID是设备的设备标示,由厂商确定,pciinfo为保存设备信息的数据结构,如果找到设备,函数会返回0,并且把设备的一些信息存储到pciinfo中去,否则返回0。获取板卡标识的方法是把目标机引导到Windows 环境中,在设备管理器中查找相应设备的信息(有时需安装设备的Windows 驱动程序),在其“属性”的“详细信息”选项卡中的“设备范例ID”中会给出相应的信息。对PCI1727,设备范例前面部分为“ PCI\\VEN_ 13fe&DEV_ 1727”,其中,VEN 代表厂商(VENDOR),下划线后面的13fe是厂商标识,DEV 代设备(DEVICE),下划线后面的1727是设备标识。在“资源”选项卡中的输入输出信息中还可以直接看到PCI设备的基地址。

如果目标机上安装 2 个或2 个以上的同样设备,查找设备的基址时就需要用到函数rl32eGetPCIInfoAtSlot,方法是:

rl32eGetPCIInfoAtSlot ((unsigned short)Vendor_ID, (unsigned short)Device_ID, (unsigned short) Bus_Slot, &pciinfo)

与前述函数相比多了Bus_Slot 参数,它是由设备所占的总线号(Bus)和插槽号(Slot)2 个参数合成的双字节参数,这2 个参数值可在主机上的xpc信息中看到。

上述函数中的 pciinfo 是一个结构型变量,其结构如下: { unsigned long BaseAddress[6]; unsigned short AddressSpaceIndicator[6]; unsigned short MemoryType[6]; unsigned short Prefetchable[6]; unsigned short InterruptLine;}

其中,BaseAddress 字段存放最重要的基址信息。根据PCI协议,PCI BIOS 可给设备分配6 个基址,但其中有些基址是无效的。要确定哪些基址是有效的,可以采用如下方法:在调试xPC 驱动程序前,把目标机启动到Windows 下,运行设备自带的测试软件,测试软件会给出有用的基址;或从设备管理器中找到相应的硬件,查看其占用的资源,资源起始地址就是基址;由于这些资源在操作系统启动之前已经分配,因此与操作系统无关,在启动到Windows 或xPC 目标环境时一般也不变。

10

XPC环境下PCI板卡驱动编写方法

对I/O地址的读写主要通过下面几个函数实现: 表 1 I/O 空间的读写命令 命令 uint32_T rl32eInpDW(uint16_T port) uint16_T rl32eInpW (uint16_T port) uint8_T rl32eInpB (uint16_T port) Void rl32eOutpDW(uint16_T port, uint32_T value) Void rl32eOutpW(uint16_T port, uint16_T value ) Void rl32eOutpB(uint8_T port, uint8_T value ) 含义 读32位的双字 读16位的字 读8位的字节 写32位的双字 写16位的字 写8位的字节 2.3.6 mdlOutputs

在每个采样时间步长内,Simulink 调用mdlOutputs 来计算块的输出。这个函数的作用就是根据对板卡功能的需求对板卡进行操作,实现其功能,Output部分的编写是非常灵活和多样的,主要是对相关寄存器进行读写,因此需结合设备硬件板的特点和所需实现的功能进行。

2.3.7 mdlterminate

在malterminate ( )子函数中,执行结束仿真所需的所有动作,主要是重置硬件设备到理想的状态。如在mdlinitializesizes( )或mdlstart ( )中分配的内存,此时要释放。

2.3.8 末尾的条件编译语句

Matlab所示S函数模板中程序体的末尾5行语句是每个设备驱动程序必须包含的,且是固定句式。这些语句是为特定程序选择合适的代码。形式为: #ifdef MATLAB_MEX_FILE /* 如果本函数编译成MEX文件则链接simulink.c文件 */ #include \"simulink.c\" /* MEX文件的接口机理 */ #else /*否则,链接cg_sfun.h*/ #include \"cg_sfun.h\" /* 代码生成记录函数*/ #endif 11

XPC环境下PCI板卡驱动编写方法

3 驱动编写示例

S-function可以用多种语言编写,如M语言、C语言、Fortran,但是XPC Target驱动的S-function只能用C语言编写。

Simulink S-function 所需实现的只是由Simulink 定义的一组很少的回调函数,一个基本的C MEX S-function 内包含的回调函数如下所示:

函数 mdlInitializeSizes mdlInitializeSampleTimes mdlStart mdlOutputs mdlTerminate 描述 初始化S-function的输入、输出等属性 初始化S-function的采样时间和采样时间偏移 初始化硬件和S-function的状态 计算块的输出 结束仿真 3.1 编写C文件

这里以DI1727为例说明完整编写一个xpc Target 驱动的大致流程。这是一个非常简单的驱动,只需要从PCI板卡的Digital Input端口读取数据,然后通过S-function的输出口输出到xpc scope来观察结果或提供给其他的S-function使用。这个S-function Block没有输入口,有任意个输出口。可以根据需要配置,它需要两个外部输入的变量channel和sample time,即通道号和采样时间,channel的个数决定了这个S-function Block需要使用几个DI口。

预处理阶段的代码基本都是固定的模板,只有少量的地方需要修改。

首先是文件名和S-function的等级,对于文件名为di1727.c的驱动,需要定义S_FUNCTION_NAME为di1727,S_FUNCTION_LEVEL: #define S_FUNCTION_LEVEL 2 #undef S_FUNCTION_NAME #define S_FUNCTION_NAME di1727 接下来是一些头文件,这些基本都是固定的:

#include 12

XPC环境下PCI板卡驱动编写方法

#include #include \"simstruc.h\" #ifdef MATLAB_MEX_FILE #include \"mex.h\" #else #include #include \"io_xpcimport.h\" #endif 然后是输入变量的定义:

#define NUM_PARAMS (2) #define CHANNEL_ARG (ssGetSFcnParam(S,0)) #define SAMPLE_TIME_PARAM (ssGetSFcnParam(S,1)) /* Convert S Function Parameters to Varibles */ #define SAMPLE_TIME ((real_T) mxGetPr(SAMPLE_TIME_PARAM)[0]) CHANNEL_ARG和SAMPLE_TIME_PARAM分别对应两个输入变量,因为MATLAB中变量都是以向量的形式表示的,并且我们通过函数获得的参数或输入都是double类型的,如果要转换成整型必须要在获得值之后才转换,否则会出现错误,所以一个变量需要通过

mxGetPr(SAMPLE_TIME_PARAM)[0] 来读取。

mdlInitializeSizes中需要对S-function的参数进行初始化,首先是检测输入变量的数量是否正确:

ssSetNumSFcnParams(S, NUM_PARAMS); /*设置S函数的参数个数*/ if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) { mdlCheckParameters(S); if (ssGetErrorStatus(S) != NULL) { return; } } else { return; /* Parameter mismatch will be reported by Simulink */ } /*检查S函数参数数目是否与设置的一致*/ /*如果不一致则直接返回*/ 由于要根据channel的数量来确定S-function的输出口,需要进行以下配置:

13

XPC环境下PCI板卡驱动编写方法

if (!ssSetNumOutputPorts(S, mxGetNumberOfElements(CHANNEL_ARG))) return; /*设置S函数的输出端口个数为1*/ for (i=0;i接下来需要在mdlInitializeSampleTimes中设置采样时间和采样时间偏移:

ssSetSampleTime(S, 0, SAMPLE_TIME); /*设置抽样时间*/ ssSetOffsetTime(S, 0, SAMPLE_OFFSET); /*设置抽样时间偏移*/ 在mdlStart中主要是PCI基址的获取以及板卡的初始化,DI不需要对板卡进行初始化,只要获取地址就可以了:

PCIDeviceInfo pciinfo; char devName[20]=\"do1727\"; //int devId; if (rl32eGetPCIInfo((unsigned short)Vendor_ID,(unsigned short)Device_ID,&pciinfo)) { sprintf(msg,\"%s: board not present\", devName); ssSetErrorStatus(S,msg); return; 如果找到设备的话,rl32eGetPCIInfo会返回0,并且在pciinfo中存储相关信息,否则返回1,输出错误信息。

Digit Input是在mdlOutputs中完成的,首先需要创建一个变量来存储从DI口读取到的信息,然后通过S-function Block输出预先定义的通道上的信息:

real_T *y; uint_T tempPortData; tempPortData = (rl32eInpB((unsigned short)din_high)<<8)|(rl32eInpB((unsigned short)din_low)&0xff); 14

XPC环境下PCI板卡驱动编写方法

for (i=0;i> (((short)mxGetPr(CHANNEL_ARG)[i])-1))&0x01; } tempPortData中存储着从DI口的低地址din_low和高地址din_high中读取到的信息,然后将输出指针y指向当前输出口,和输入变量一样,输出变量也是一个数组,输出时将输出值赋给y[0]即可。

在调试过程中如果想观察某个变量的值,可以使用printf命令,会在xpc下位机中输出想看到的变量,具体用法和普通c语言的一样。

3.2 封装成S-function

在编写完驱动代码后,就可以包装成S-function,然后封装到simulink库中去了。 首先在MATLAB的命令窗口中输入编译代码: >>mex di1727.c

将其编译成Simulink可调用的动态库di1727.mexw32

然后在simulin中新建一个library,再从simulink的user-defined function中拖一个S-Function到新建的library中去,之后就开始对新建的S-function进行配置。

右键单击S-function选择S-function parameter,在第一项的S-function name中输入驱动的名字di1727,在第二项中输入S-function中的参数,就是驱动中设定的输入变量。

15

XPC环境下PCI板卡驱动编写方法

设置好参数后就需要对S-function进行包装,右键单击S-function选择Mask S-function,首先是对S-function的外观进行设计,在Icon Drawing commands中可以输入的名称等信息,:

16

XPC环境下PCI板卡驱动编写方法

然后是变量的设置,前面我们设计了两个变量,channels和sample time,需要添加进来,每个变量值可以使用edit,popup和checkbox三种方式,edit即自己输入,popup可以预设一些值用来选择。其他的两个标签Initialization和documentation是用于参数的检测和S-function的介绍。

一个mdl中可以创建多个s-function block,例如在advantech中可以创建DI1727,DO1727等,即在一个库下面创建多个s-function block

为了能够将新建的驱动导入到simulink库中,需要创建一个m文件,在matlabroot\oolbox\\rtw\argets\\xpc\arget\\build\\xpcblocks\hirdpartydrivers文件夹中找到sample_xpcblocks.m文件,将sample改为需要创建的库的名字,如advantech_xpcblocks.m,在文件中,修改out.Library = 'your_company_namelib'和out.Name = 'your_company_namelib Blockset',将your_company_namelib改为创建的库的名字,如

out.Library = 'advantech'; out.Name = 'advantech';

通过上述步骤,新建的驱动就已经被封装到simulink库中了,在matlab中输入rehash toolbox,再重新打开simulink,就可以在simulink中找到刚刚封装进去的库。

以上这些过程要保证当前的工作目录下包含mexw32文件,当然如果要使用上图中的Edit选项编辑源文件,还必须保证c文件在当前的工作目录下,在进行建模时也要保证当前的工作目录下包含mexw32文件。

17

XPC环境下PCI板卡驱动编写方法

为了能在xpc信息中看到自己添加的板卡,需要创建一个supported文件,从matlabroot\oolbox\\rtw\argets\\xpc\arget\\build\\xpcblocks\hirdpartydrivers文件夹中找到your_company_namelib_supported.m,保存为*_supported.m,如advantech_supported.m,将文件里的数据结构前面的注释号去掉,将分号里的信息改成自己的板卡的信息,如

boards(1).VendorID = '13FE'; boards(1).DeviceID = '1727'; boards(1).SubVendorID = '13FE'; boards(1).SubDeviceID = 'A102'; boards(1).DeviceName = '1727'; boards(1).VendorName = 'advantech'; boards(1).DeviceType = 'advantech 1727'; boards(2).VendorID = '13FE'; boards(2).DeviceID = '1710'; boards(2).SubVendorID = '13FE'; boards(2).SubDeviceID = 'C100'; boards(2).DeviceName = '1710'; boards(2).VendorName = 'advantech'; boards(2).DeviceType = 'advantech 1710'; boards(3).VendorID = '13FE'; boards(3).DeviceID = '1780'; boards(3).SubVendorID = '13FE'; 18

XPC环境下PCI板卡驱动编写方法

boards(3).SubDeviceID = 'A200'; boards(3).DeviceName = '1780'; boards(3).VendorName = 'advantech'; boards(3).DeviceType = 'advantech 1780'; 前面四个可以从xpc信息中看到,后面三个是自己填写,可以添加任意个板卡信息,从

boards(1)开始;

19

XPC环境下PCI板卡驱动编写方法

4 软件相关信息

4.1 程序文件列表

DI1727.c DI1727.mdl DI1727.mexw32 advantech.mdl

advantech_supported.m advantech_xpcblocks.m

4.2 运行平台

硬件平台:研华板卡1727

研华工控机

软件平台:MATLAB 7.9 Windows XP

VC 6.0

4.3 编程语言

C语言 M语言

20

XPC环境下PCI板卡驱动编写方法

附录

#define S_FUNCTION_LEVEL 2 #undef S_FUNCTION_NAME

#define S_FUNCTION_NAME di1727

#include #include

#include \"simstruc.h\"

#ifdef MATLAB_MEX_FILE #include \"mex.h\" #else

#include #include \"io_xpcimport.h\" #endif

/* Input Arguments */

#define NUM_PARAMS (2)

#define CHANNEL_ARG (ssGetSFcnParam(S,0)) #define SAMPLE_TIME_PARAM (ssGetSFcnParam(S,1))

/* Convert S Function Parameters to Varibles */

#define BASE ((uint_T) mxGetPr(BASE_ADDRESS_ARG)[0]) #define SAMPLE_TIME ((real_T) mxGetPr(SAMPLE_TIME_PARAM)[0])

#define NO_I_WORKS (2) #define DIN_LOW_I_IND (0) #define DIN_HIGH_I_IND (1)

static char_T msg[256];

/*====================* * S-function methods * *====================*/

static void mdlCheckParameters(SimStruct *S) {

21

XPC环境下PCI板卡驱动编写方法 }

static void mdlInitializeSizes(SimStruct *S) {

uint_T i;

#ifndef MATLAB_MEX_FILE #include \"io_xpcimport.c\" #endif

ssSetNumSFcnParams(S, NUM_PARAMS);

if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) { mdlCheckParameters(S);

if (ssGetErrorStatus(S) != NULL) { return; } } else {

return; /* Parameter mismatch will be reported by Simulink */ }

ssSetNumContStates(S, 0); ssSetNumDiscStates(S, 0);

if (!ssSetNumInputPorts(S, 0)) return;

if (!ssSetNumOutputPorts(S, mxGetNumberOfElements(CHANNEL_ARG))) return;

for (i=0;issSetNumSampleTimes(S, 1);

ssSetNumIWork(S, NO_I_WORKS);

ssSetNumModes(S, 0);

ssSetNumNonsampledZCs(S, 0);

ssSetSFcnParamNotTunable(S,0); ssSetSFcnParamNotTunable(S,1); ssSetSFcnParamNotTunable(S,2);

22

XPC环境下PCI板卡驱动编写方法

ssSetSFcnParamNotTunable(S,3);

ssSetOptions(S, SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME | SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_PLACE_ASAP); }

static void mdlInitializeSampleTimes(SimStruct *S) {

ssSetSampleTime(S, 0, SAMPLE_TIME); ssSetOffsetTime(S, 0, SAMPLE_OFFSET); }

#define MDL_START

static void mdlStart(SimStruct *S) {

#ifndef MATLAB_MEX_FILE

uint_T din_low; uint_T din_high; PCIDeviceInfo pciinfo; char devName[20]=\"di1727\";

if (rl32eGetPCIInfo((unsigned short)Vendor_ID,(unsigned short)Device_ID,&pciinfo)) {

sprintf(msg,\"%s: board not present\ ssSetErrorStatus(S,msg); return;

BASE = (uint_T)pciinfo.BaseAddress[2];

din_low=BASE+1; din_high=BASE+0;

ssSetIWorkValue(S, DIN_LOW_I_IND, din_low); ssSetIWorkValue(S, DIN_HIGH_I_IND, din_high);

#endif /* MATLAB_MEX_FILE */ }

static void mdlOutputs(SimStruct *S, int_T tid) {

#ifndef MATLAB_MEX_FILE

23

XPC环境下PCI板卡驱动编写方法

uint_T i;

uint_T baseAddr = BASE; real_T *y;

uint_T tempPortData; uint_T din_low; uint_T din_high;

din_low = ssGetIWorkValue(S, DIN_LOW_I_IND); din_high = ssGetIWorkValue(S, DIN_HIGH_I_IND);

/* Read in Digital Input from Hardware */

tempPortData = (rl32eInpB((unsigned

short)din_high)<<8)|(rl32eInpB((unsigned short)din_low)&0xff);

for (i=0;iy[0] = (tempPortData >> (((short)mxGetPr(CHANNEL_ARG)[i])-1))&0x01; }

#endif /* MATLAB_MEX_FILE */ }

static void mdlTerminate(SimStruct *S) {

#ifndef MATLAB_MEX_FILE #endif /* MATLAB_MEX_FILE */ }

/*=============================* * Required S-function trailer * *=============================*/

#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */ #include \"simulink.c\" /* MEX-file interface mechanism */ #else

#include \"cg_sfun.h\" /* Code generation registration function */ #endif

24

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- dfix.cn 版权所有 湘ICP备2024080961号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务