1、Functional SpecificationInterface for direct calls to external drivers from RealtimePLC-RuntimeforWindows NT1. Which modules are linked ?IO-Drivers are linked by entries in the registry-key HKEY_LOCAL_MACHINESoftware3S Smart Software SolutionsCodesys SPRTPLCIO Drivers. Here a value DriverXX“ must ex
2、ist for each driver that should be linked. XX is a continuously incremented number, starting with 0. All function, that may work on hardware, are redirected to the drivers that are linked, from now on.This document describes the interface necessary to manage the linking of external IO-Drivers (by fi
3、lling some function-pointer-tables) to the realtime extension of WindowsNT, created by Smart Software Solutions GmbH.1.1. The basic procedure to retrieve the functionpointers.Each driver running under WindowsNT must fill some entries in the list of his dispatch-functions, for example:pDriverObject-M
4、ajorFunctionIRP_MJ_DEVICE_CONTROL= ntDeviceControl;pDriverObject-MajorFunctionIRP_MJ_CREATE = ntCreateFile;Now we add one entry, which tells the operating system the address of a function, dedicated for driver-driver-comunication.pDriverObject-MajorFunctionIRP_MJ_INTERNAL_DEVICE_CONTROL= yyyyyy;wher
5、e yyyyyy is the address of a function, defined as follows:typedef struct _tagCallbackInfo/the security-members are made to check, whether the caller is a legal caller to the driver.unsigned long ulSecurityId1; / this member must be set to 0x436F4465 means CoDeunsigned long ulSecurityId2; / this memb
6、er must be set to 0x53797320 means Sysunsigned long ulCommand;unsigned long ulSubCommand;unsigned long ulCmdParam;void* pAdditionalCmdData; /may point to a caller-supplied, command-specific structure.CallbackInfo;unsigned long yyyyyy(CallbackInfo* pcbi, void* pPar);This function is called by the rea
7、ltimePLC, with the security Ids as parameters, see above. The driver now can determine, whether the call really comes from realtimePLC and so the first parameter is a pointer to a CallbackInfo-structure.Additionally the driver checks ulCommand-member for DRV_CMD_GET_FUNCTION_POINTER_LIST“(#define DR
8、V_CMD_GET_FUNCTION_POINTER_LIST 1)When filling the list of functionpointers, the driver uses the following indexesDRV_FCT_INIT 1DRV_FCT _EXIT 2DRV_FCT _GET_ID 3DRV_FCT _GET_FLAGS 4DRV_FCT _GET_IORANGE 5DRV_FCT _CONFIGURE_IONET 6DRV_FCT _CONFIGURE_MODULE 7DRV_FCT _CONFIGURE_DEVICE 8DRV_FCT _START_WRI
9、TE_OUTPUTS 9DRV_FCT _WRITE_OUTPUTS 10DRV_FCT _DONE_WRITE_OUTPUTS 11DRV_FCT _START_READ_INPUTS 12DRV_FCT _READ_INPUTS 13DRV_FCT _DONE_READ_INPUTS 14DRV_FCT_PLC_STATUS_CHANGES 15DRV_FCT_START_CONFIGURE_IONET,DRV_FCT_DONE_CONFIGURE_IONET,DRV_FCT_ENTER_NMI_ROUTINE,DRV_FCT_LEAVE_NMI_ROUTINE,DRV_FCT_START
10、_INTERRUPT,DRV_FCT_STOP_INTERRUPT,DRV_FCT_RETAIN_SAVE,DRV_FCT_RETAIN_RESTORE,DRV_FCT_CYCLIC_CALL,DRV_GET_EXTREFTABLE DRV_FCT_BUSDIAG_GETBUSSTATE,DRV_FCT_BUSDIAG_GETSTATE,DRV_FCT_BUSDIAG_SETBUSSTATE,DRV_FCT_BUSDIAG_SETSTATE/here extendable by 3S.The list is initialized with NULL, the driver inserts o
11、nly the functions, he wants to be called by the PLC.Example:(void*)pAdditionalCmdData)DRV_FCT_INIT = yyyyyy, where yyyyyy is the name of the function which initializes the driver. The same method is used for every function, the driver wants to register.The whole procedure to register functions and r
12、etrieve functionpointers from the PLC-API, for calling PLC-functions from an IO-diver, is implmented in the RTIOdriver-toolkit. There, the codesections where the code must be modified are marked with TODO:-comments. When the single functions are called by the PLC, and the meaning of each single para
13、meter, is described in Description of IO-driver functions“.1.2. Creating IO-Drivers with the RTIODrv_Toolkit.Hint: The toolkit is developped for creating drivers with the Microsoft Visual C+ 6.0“ compiler, running under Windows NT4.0.To create an IO-driver, which works with the realtimePLC, the foll
14、owing steps must be obtained before implmentation of own functionality begins:- Change the names of some sourcefiles, specially the one of RTIOdrv.c, to keep things clear. (Therefore rename the files, create a new workspace in Visual C+ and insert the renamed projectfile. Then add the renamed source
15、files, evtl. remove those which cannot be found anymore, because they are renamed. (Alternatively you can also edit the workspace and the projectfile, delivered with the toolkit, as a textfile and modify them by search for RTIOdrv and replace by . In that case you can skip the following step).- In p
16、roject/settings-dialogue change the filenames for Executable for Debug Session“ und Linker“/Output file name“ to your own filename of the driver, do the same thing PostBuildStep, where the drivername is referenced in both commands existing there.- Modify the names of the so called Symbolic Links“ (i
17、n the Toolkit) RTIODrv.c (which now should be named RTIOdrvXYZ.c). The links must be named according to the drivername.- Change the includes of the headerfiles, normally you renamed RTIOdrv.h to RTIOdrvXYZ.Now the driver should be compiled without errors and a file .sys in %SystemRoot%System32Driver
18、s-directory should be created. Check for it.The driver now has to be installed, to notify the system.Therefore, edit the file RTIOdrv.reg in the subdirectory Registration“ and then, to keep things clear, save under .reg. In the .reg-file, only the name of the key, that has to be created, must be mod
19、ified:HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesRTIOdrvcahnges toHKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices.Then doubleclick the file and the driver is registered.After the next restart of the computer, the driver appears in the list of drivers the devicemanager maintains. The driver c
20、an be started/stopped there manually.2. Description of IO-driver functions“2.1. DRV_FCT_INITThe function is called everytime the PLC initializes (the system starts)Prototyp:typedef unsigned long (*PF_INIT)(unsigned long ulPar);with ulPar:#define DRV_INIT_FLAG_HWCONFIG_CHANGED 0x1or 0, if the call co
21、mes from initializing the PLC.Returnvalues which are bigger than one are error-codes, zero is an undefined error. Only 1 is o.k.2.2. DRV_FCT_EXITThe function is only called, when the PLC shuts down.Prototyp:typedef unsigned long (*PF_EXIT)(void);Returnvalue is not checked.2.3. DRV_FCT _GET_IDThe fun
22、ction is also called when initializing. The PLC calls the function to retrieve the drivers id and some more data. The function must be implemented.Prototyp:typedef unsigned long (*PF_GET_ID)(void* pDataMemory);The returnvalue is the drivers id, pDataMemory points to a structure of type GetIdData.(Se
23、e definition in IodrvInterface.h or in the appendix.) There the driver must set the iNumDevices-member to minimum 1 device, or some device-specific functions will not be called in future. If the driver (or his devices) use hardwareinterrupts, the driver must specify some informations about these int
24、errupts.When done so, the device will work even if a bluescreen occurs.2.4. DRV_FCT _GET_FLAGSThis function is called everytime the PLC wants to retrieve the capabilties of the devices the driver manages. The following flags are supported in this version:DRV_CAP_FLAG_WANTS_CONFIG 0x1DRV_CAP_FLAG_IS_
25、PBDEVICE 0x2DRV_CAP_FLAG_IS_CANDEVICE 0x4DRV_CAP_FLAG_IS_ASIDEVICE 0x8DRV_CAP_FLAG_IS_TCPIPDEVICE 0x10DRV_CAP_FLAG_IS_ARCNETDEVICE 0x20DRV_CAP_FLAG_IS_IBSDEVICE 0x40DRV_CAP_FLAG_HAS_RETAINDATA_AREA 0x100/extensible by 3SThe flags IS.DEVICE are only interesting in combination with the .WANTS_CONFIG.
26、If the hardwareconfigurator of CoDeSys should be used to configure the devices, the PLC must know what type of configdata must be sent to the device. (e.g. CAN or Profibus).Just return a static value, corresponding to the device-number.The first device that return DRV_CAP_FLAG_HAS_RETAINDATA_AREA, i
27、s called by the PLC to save and restore the retains.Prototy:typedef unsigned long (*PF_GET_FLAGS)(unsigned long ulDeviceNr2.5. DRV_FCT _GET_IORANGEThis function is called after the driver has been initialized, to retrieve the IO-range of the drivers devices.Prototyp:typedef void (*PF_GET_IORANGE)(un
28、signed long* pulOffset, unsigned long* pulSize);The driver writes offsets and sizes to the arrays pulOffset and pulSize point to. Only by writing regular values, the driver will be called for the right IO-offsets whenever the PLC wants to update inputs/outputs.2.6. DRV_FCT_START_CONFIGURE_IONETThis
29、function is called when the PLC starts to send configuration-data to all the devices that set the WANTS_CONFIG-flag. So the driver has the possibility to clear the current configuration on the device, for example.Prototyp:typedef char (*PF_START_CONFIGURE_IONET)(unsigned long ulDeviceNr);2.7. DRV_FC
30、T_DONE_CONFIGURE_IONETThis function is called after all the configuration-data is sent to the device. So the driver can do things like start the bus and so on.Prototyp:typedef char (*PF_DONE_CONFIGURE_IONET)(unsigned long ulDeviceNr);The returnvalue is 0 for general failure, 1 for o.k. and 1 for an
31、errorcode.2.8. DRV_FCT_CONFIGURE_MODULEThe function is called once for every device, that set the WANTS_CONFIG-flag It is called to send the configurationdata for one module. The driver can store the data sent, or configure the device at once.Prototyp:typedef char (*PF_CONFIGURE_MODULE)(int iModule,
32、 void* pModConfData, unsigned long ulDeviceNr);This version supports profibus and CAN configuration. Dependent of the IS_DEVICE-fla, pModConfData points to a CANnode- or a PBSlave-structure. See the appendix or IodrvInterface.h for definitions.2.9. DRV_FCT _CONFIGURE_DEVICEThe function is called to
33、send bus-configurationdata to the device. Prototyp:typedef char (*PF_CONFIGURE_DEVICE)(void* pBusDesc, unsigned long ulDeviceNr);It depends on the IS_DEVICE flag, whether pBusDesc points to DPM_BUS_DP or a CAN_BUS-structure. So the driver can set the bus configuration.2.10. DRV_FCT _START_WRITE_OUTP
34、UTSThe function is called before the outputs of one task are written. The parameters tasknumber and cycle time can be used for optimizations (like store the ios and update only with fastest task or something like this). They can also be ignored.Prototyp:typedef char (*PF_START_WRITE_OUTPUTS)(unsigne
35、d long ulTaskNr, unsigned long ulCycleTime, int iDevice);If the function returns zero here, an IO-update-failure is generated.2.11. DRV_FCT_WRITE_OUTPUTSThe function is called for each output, that belongs to a task. The ulOffset paramter is the offset within the devices IO-range, pucDataSrc points
36、directly to the source, where the driver can read this output.Prototyp:typedef char (*PF_WRITE_OUTPUTS)(unsigned long ulOffset, unsigned long ulSize, unsigned char* pucDataSrc, unsigned long ulTaskNr, unsigned long ulDeviceNr);If the function returns 0, an ERROR_IO_UPDATE exception is generated.2.12
37、. DRV_FCT _DONE_WRITE_OUTPUTSThe function is called after all outputs of one task are written. Now, if not done synchron when getting calls of WRITE_OUTPUT (for example if a DMA-driver wants to transfer the whole IO-data of a device with one transfer), the data can be written to the device.Prototyp:
38、typedef char (*PF_DONE_WRITE_OUTPUTS)(unsigned long ulTaskNr, unsigned long ulCycleTime, int iDevice);If the function returns 0, an ERROR_IO_UPDATE exception is generated.2.13. START_READ_INPUT, READ_INPUT, DONE_READ_INPUTSame as writing outputs, analogue.Prototypen:typedef char (*PF_START_READ_INPU
39、TS)(unsigned long ulTaskNr, unsigned long ulCycleTime, int iDevice);typedef char (*PF_READ_INPUTS)(unsigned long ulOffset, unsigned long ulSize, unsigned char* pucDataDest, unsigned long ulTaskNr, unsigned long ulDeviceNr);typedef char (*PF_DONE_READ_INPUTS)(unsigned long ulTaskNr, unsigned long ulC
40、ycleTime, int iDevice);The ulOffset is the device-relative offset, pucData points directly to the destination of the inputdata, read by the driver.2.14. DRV_FCT_PLC_STATUS_CHANGESThe function is called everytime the PLC-state changes, for example from RUN to STOP.Prototyp:typedef char (*PF_PLC_STATU
41、S_CHANGES)(unsigned char ucNewState);mit NewState eins von/* Controller Status definitions */#define RTS_VOID (unsigned char)-1)#define RTS_RUN 0#define RTS_STOP_SRV 1#define RTS_STOP_BP 2#define RTS_RUN_STEP_IN 3#define RTS_RUN_STEP_OVER 4#define RTS_RUN_WATCHDOG 5The function can prevent the PLC f
42、rom changing from a STOP-state to a RUN-state by returning 0. The driver cannot prevent the CPU from changing to a STOP-state.2.15. DRV_FCT_ENTER_NMI_ROUTINEIf the PLC should work on an NMI as cyclic interrupt, the interrupt-handler will call this function when entering. May be some platform-specifi
43、c things have to be done to reset the interruptsignal (hardware-specific things).Prototyp:typedef unsigned long (*PF_ENTER_NMI_ROUTINE)(unsigned long);The returnvalue of the function can be a combination of the flags#define IODRV_NMIFLAG_SYNCHRONIZE_HIGHPRIOTASK (0x1UL)#define IODRV_NMIFLAG_SCHEDULE
44、_NT_ALWAYS (0x2UL)#define IODRV_NMIFLAG_SCHEUDLE_SCHEDULERTASKS (0x4UL)So the driver is able to influence the behaviour of the scheduler, if scheduling on NMI.Example:With IODRV_NMIFLAG_SYNCHRONIZE_HIGHPRIOTASK the task with the highest priority is scheduled at once, if IODRV_NMIFLAG_SCHEDULE_NT_ALW
45、AYS is not set. To prevent the task from being scheduled after its cycletime, the task must be created with cycletime 0.The IOdriver returns .NT_ALWAYS and ._SYNCHRONIZE_HIGHPRIOTASK alternating.Then NT wil get a fix timeslice, the other timeslice is used to always schedule the task with the highest
46、 priority. The other tasks get the rest of the timeslice of the highest priority task.2.16. DRV_FCT_LEAVE_NMI_ROUTINESame as ENTER_NMI_ROUTINE, called after the scheduler is called from the NMIhandler-routine.Prototyp:typedef void (*PF_LEAVE_NMI_ROUTINE)(void);2.17. DRV_FCT_START_INTERRUPTIf the PLC
47、 wants to schedule on an NMI, it will call this function when initializing, to start the generation of a cyclic interrupt (must be NMI). If this function fails, the system will not work, because the scheduler is never called. So the system will also not be able to terminate himself.Prototyp:typedef
48、int (*PF_START_INTERRUPT)(int iPar);Should return 0, if cyclic interrupt is not generated.The parameter iPar is 2, if the PLC expects, a cyclic (NM-)interrupt is generated from now on (and passed to the CPU). iPar is 42, if the cyclic interrupt can now be passed again to the CPU (without ever having
49、 stopped the generation of the interrupts).With iPar 42 the function is called everytime, the PLC has scheduled. It is possible, that this function is called without a preceding call to DRV_FCT_STOP_INTERRUPT. The function actually has nothing to do then.2.18. DRV_FCT_STOP_INTERRUPTThe generation of cyclic interupts should stop now, the PLC will now deinstall the handler routine. Generating an interrupt may now lead to a systemcrash.Prototyp:typedef int (*PF_STOP_INTERRUPT)(int iPar);iPar is 2, if the gene
Copyright © 2018-2021 Wenke99.com All rights reserved
工信部备案号:浙ICP备20026746号-2
公安局备案号:浙公网安备33038302330469号
本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。