项目名称:硬件在环
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 XPC环境下PCI板卡驱动编写方法 #include #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 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 在调试过程中如果想观察某个变量的值,可以使用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 \"simstruc.h\" #ifdef MATLAB_MEX_FILE #include \"mex.h\" #else #include /* 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;i 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;i #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
本站由北京市万商天勤律师事务所王兴未律师提供法律服务