xPC Target™ 4 Device Drivers
How to Contact MathWorks Web Newsgroup www.mathworks.com/contact_TS.html Technical Support www.mathworks.com comp.soft-sys.matlab suggest@mathworks.com bugs@mathworks.com doc@mathworks.com service@mathworks.com info@mathworks.com Product enhancement suggestions Bug reports Documentation error reports Order status, license renewals, passcodes Sales, pricing, and general information 508-647-7000 (Phone) 508-647-7001 (Fax) The MathWorks, Inc.
Revision History March 2007 September 2007 March 2008 October 2008 March 2009 September 2009 March 2010 September 2010 Online Online Online Online Online Online Online Online only only only only only only only only New for Version 3.2 (Release 2007a) Updated for Version 3.3 (Release 2007b) Updated for Version 3.4 (Release 2008a) Updated for Version 4.0 (Release 2008b) Updated for Version 4.1 (Release 2009a) Updated for Version 4.2 (Release 2009b) Updated for Version 4.
Contents Customizing xPC Target Drivers 1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xPC Target Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . When to Write Your Own Drivers . . . . . . . . . . . . . . . . . . . . Restrictions on Customizing xPC Target Drivers . . . . . . . . Expected Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Resources for Customizing xPC Target Drivers . . . . . . . . .
ISA and PC/104 Drivers 3 ISA and PC/104 Bus Considerations . . . . . . . . . . . . . . . . . Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I/O Mapped . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Memory Mapped . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-2 3-2 3-2 3-3 Masking Drivers 4 .................. 4-2 Driver Mask Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Hook Function Prototypes — Alphabetical List . . . . . . . 5-15 Custom xPC Target Driver Notes 6 S-Function Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2 mdlStart and mdlTerminate Considerations . . . . . . . . . 6-4 DMA Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-5 Passing Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-6 Accessing Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
I/O Structures — By Category 8 I/O Structures — Alphabetical List 9 I/O Functions — By Category 10 Port I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-2 PCI Configuration Information . . . . . . . . . . . . . . . . . . . . . 10-2 Physical Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-2 Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-2 Miscellaneous . . . . . . . . . .
1 Customizing xPC Target Drivers • “Introduction” on page 1-2 • “Before You Start” on page 1-8 • “Creating a Custom Driver” on page 1-11 • “Debugging Notes” on page 1-16
1 Customizing xPC Target™ Drivers Introduction In this section... “xPC Target Drivers” on page 1-2 “When to Write Your Own Drivers” on page 1-3 “Restrictions on Customizing xPC Target Drivers” on page 1-3 “Expected Background” on page 1-3 “Resources for Customizing xPC Target Drivers” on page 1-4 “What Makes Up an xPC Target Driver?” on page 1-6 xPC Target Drivers The xPC Target™ software provides device drivers for a variety of third-party boards.
Introduction When to Write Your Own Drivers Consider writing your own device drivers for the xPC Target block library if: • No xPC Target driver exists for your I/O needs. • You are unable to use a board that the xPC Target software supports. • You need to extend the functionality of an existing xPC Target driver. • The MathWorks xPC Target team will not write a device driver for your board.
1 Customizing xPC Target™ Drivers • Good C programming skills • Knowledge of how Simulink simulation works, for example, the type and order of calls • Knowledge of writing S-functions and compiling those functions as C-MEX functions. This includes a comprehensive knowledge of Simulink callback methods and the Simulink SimStruct functions. • Basic knowledge of Real-Time Workshop • Understanding of I/O hardware.
Introduction See... For... Developing S-Functions How to write MATLAB C-MEX S-functions (noninlined S-functions). Note the following references in this guide: • “S-Function Callback Methods — Alphabetical List” the Simulink software invokes these methods when simulating a model with S-functions. Real-Time Workshop uses the same methods in generated real-time applications.
1 Customizing xPC Target™ Drivers xPC Target Exported Functions The xPC Target software provides kernel functions that you can use when writing your device drivers. These functions enable you to input and output data, configure PCI devices, and specify time-out intervals. Use only the functions documented in this guide. The guidelines in this document are not applicable if you are using an xPC Target software version prior to xPC Target software version 3.2 (R2007a).
Introduction Underlying driver code (C-file) Block mask Mask initialization (M-file) Mask editor Anatomy of an xPC Target™ Driver 1-7
1 Customizing xPC Target™ Drivers Before You Start In this section...
Before You Start • Select polling versus interrupt. • Specify the blocks for the drivers. Identify - Input and output ports Mask parameters Work variables to be shared between driver start, output, and terminate routines • Determine your timing considerations. • Decide whether you use Inlined functions. If yes, see the Target Language Compiler documentation of the Real-Time Workshop.
1 Customizing xPC Target™ Drivers Bus Access ISA Board switches or jumpers usually select I/O port address and any memory-mapped region. PCI The BIOS determines the I/O port address during PCI PNP (Plug and Play) configurations. The memory space for I/O boards is different for ISA and PCI boards.
Creating a Custom Driver Creating a Custom Driver The following is a generic procedure for how to create a custom device driver. For additional notes on writing custom xPC Target drivers, see Chapter 6, “Custom xPC Target Driver Notes”. For a description of a tool that helps you create simple custom drivers, see Chapter 7, “Creating Custom Drivers Using the xPC Target Driver Authoring Tool”. A simple custom device driver is one which performs no DMA or interrupt handling.
1 Customizing xPC Target™ Drivers 4 Open the Simulink Library Browser and create a new library, for example, your_company_namelib.mdl (see “Creating Block Libraries” in the “Working with Block Libraries” in the chapter of Simulink User’s Guide). Use a unique library name to prevent conflicts with other libraries. 5 In the new library, create an S-function block. From the Simulink Library Browser, drag an S-Function block to the new library. 6 Configure the S-Function block.
Creating a Custom Driver 7 Double-click the S-Function block and create a block mask (see Chapter 4, “Masking Drivers”). 8 Save and close the S-Function block. 9 At the bottom of the S-Function block, enter a block name. For example, MM-32. 10 Save and close the library. 11 To make your new library visible in the Simulink Library Browser, move it to matlabroot\toolbox\rtw\targets\xpc\target\build\xpcblocks\thirdpartydrivers 12 Copy and paste sample_xpcblocks.
1 Customizing xPC Target™ Drivers Rename this file your_company_namelib_xpcblocks.m and edit this file as follows: • Set out.Library to your new library. out.Library = 'your_company_namelib'; • Set out.Name to a string, such as the library name. out.Name = 'your_company_namelib Blockset'; This string will appear in the Simulink Library Browser. • Ensure that out.IsFlat is set to 0. out.IsFlat = 0; Note Ensure that you create a function that calls the out structure.
Creating a Custom Driver boards(1).VendorName = 'Commtech'; boards(1).DeviceType = 'Serial Ports'; e Save and close the file. f To confirm your entries, type getxpcpci('all') in the MATLAB Command Window. 14 Ensure that all your driver files, including include files, are in the directory: matlabroot\toolbox\rtw\targets\xpc\target\build\xpcblocks\thirdpartydrivers Ensure that these files have unique names to prevent conflicts.
1 Customizing xPC Target™ Drivers Debugging Notes While developing your custom driver, you can use printf statements in your code. This displays output on the left-hand side of the target PC monitor. If your printf statements scroll off the monitor, consider disabling the target PC scope area to provide more display area for these statements: 1 At the MATLAB Command Window, type xpcexplr to start xPC Target Explorer. 2 In xPC Target Explorer, navigate to target_PC_node > Configuration > Appearance.
2 PCI Drivers • “PCI Bus Considerations” on page 2-2 • “Sample PCI Device Driver” on page 2-8
2 PCI Drivers PCI Bus Considerations In this section... “Introduction” on page 2-2 “PCI Configuration Space API” on page 2-3 “Memory-Mapped Accesses” on page 2-6 “I/O Port Accesses” on page 2-6 Introduction When writing xPC Target drivers for PCI devices, consider the memory access method. A PCI device can be either I/O port mapped or memory mapped. • I/O port mapped — The BIOS assigns a port range. • Memory mapped — The BIOS assigns a memory region, if your device is memory mapped.
PCI Bus Considerations You can have the drivers locate PCI devices in one of the following ways: • If the system has one board of any one type, you can use the driver slot option to search for the first board that matches a vendor and device ID. To initiate this search, set this option to -1. • If the system contains multiple boards of the same type, setting the slot option to -1 does not find the additional boards. In that case, specify the bus and slot numbers with the vendor and device IDs.
2 PCI Drivers PCI Device Information Use the xpcGetPCIDeviceInfo function to get information for a PCI device in your system. The syntax for this function is: int xpcGetPCIDeviceInfo (uint16_T vendorId, uint16_T deviceId, uint16_T subVendorId, uint16_T subDeviceId, uint16_T bus, uint16_T slot, xpcPCIDevice *pciInfo); This function returns the xpcPCIDevice structure filled according to the following: If You Supply... This Function....
PCI Bus Considerations Set... To... Set slot = -1 Assume bus = 0 and call the xpcGetPCIDeviceInfo function to find the first instance of the board. Set slot = S Assume bus = 0 and call the xpcGetPCIDeviceInfo function to find the specified board. If the board matches the IDs, return the PCI information to the driver. Otherwise, return an error. Set slot = [B, S] Check bus B and slot S for the specified board. If the board matches the IDs, return the PCI information to the driver.
2 PCI Drivers vendorId = (uint16_T)0x1234; deviceId = (uint16_T)0x9876; subvendor = (uint16_T)0x5678; subdevice = (uint16_T)0x8765; /* Set subvendor and subdevice to XPC_NO_SUB, XPC_NO_SUB if they are not necessary */ /* xpcGetPCIDeviceInfo() populates the pciInfo struct */ if ( xpcGetPCIDeviceInfo(vendorId, deviceId, subvendor, subdevice, bus, slot, &pciInfo) ) { sprintf(msg, "Board 0x%x not found at bus %d slot %d", deviceId, bus, slot); ssSetErrorStatus(S, msg); return; } For detailed information on
PCI Bus Considerations • xpcInpB, xpcInpW, xpcInpDW — I/O port input functions for byte, word, and double word accesses • xpcOutpB, xpcOutpW, xpcOutpDW — I/O port output functions for byte, word, and double word accesses 2-7
2 PCI Drivers Sample PCI Device Driver For example PCI device driver code, see matlabroot\toolbox\rtw\targets\xpc\target\build\xpcblocks\dikpc i1800.c This driver illustrates digital input driver code for the Keithley 1800 series PCI devices. Note Remember to enter the C-file name (without the extension) as the S-function name for the S-Function block.
3 ISA and PC/104 Drivers
3 ISA and PC/104 Drivers ISA and PC/104 Bus Considerations In this section... “Introduction” on page 3-2 “I/O Mapped” on page 3-2 “Memory Mapped” on page 3-3 Introduction When writingxPC Target drivers for ISA and PC/104 devices, consider the memory access method. A PCI device can be either port mapped or memory mapped. Most ISA and PC/104 boards are port mapped. Those that are memory mapped typically need large register banks or are interfaced via dual-port memory.
ISA and PC/104 Bus Considerations Memory Mapped The I/O and memory on the board is set via jumpers or switches. Drivers cannot discover these addresses on their own; you must specify these addresses to the driver. Reserved Space on the Target PC The xPC Target kernel reserves space in the region (C0000 to DC000) for memory-mapped I/O cards. You must set up ISA and PC/104 cards to use addresses in this range.
3 3-4 ISA and PC/104 Drivers
4 Masking Drivers • “Creating Driver Subsystem Masks” on page 4-2 • “Driver Mask Guidelines” on page 4-3 • “Cross-Block Checking” on page 4-5 • “When You Are Done” on page 4-6 • “Sample Driver Mask” on page 4-7
4 Masking Drivers Creating Driver Subsystem Masks This chapter describes guidelines for creating a Simulink block user interface (mask) for the S-Function block associated your driver. A mask defines the menu items that will be passed to the S-function. The mask can call a MATLAB file to do parameter or range value checking. You can also modify the labels of a block to show port numbers or other information. After you create the C code for an xPC Target device driver: 1 Create an optional MATLAB file.
Driver Mask Guidelines Driver Mask Guidelines This topic lists guidelines you should follow when creating a mask for your xPC Target driver. You should already know how to create masked blocks. See the “Working with Block Masks” chapter in Simulink User’s Guide for further information. Users access the masked block to interact with the driver, which in turn interacts with the device. • Create an S-Function block for the driver. • Decide on the set of parameters the user will need to provide to the driver.
4 4-4 Masking Drivers - Range checking for all parameters. For example, if you expect input values from 1 to 10, do not allow users to enter negative values, or values greater than 10. - Cross-block checking (see “Cross-Block Checking” on page 4-5).
Cross-Block Checking Cross-Block Checking Cross-block checking determines if multiple blocks are trying to access the same hardware. You should include cross-block checking in your driver to prevent such conflicts. You can perform cross-block checking by calling find_system from the block mask in a number of ways. Use the following guidelines when performing cross-block checking: • The recommended way is to call the find_system function from the block InitFcn callback function.
4 Masking Drivers When You Are Done After you write the driver S-function and create the S-Function block, optional block mask, and MATLAB file for it, be sure to: • Check the text of each error message for spelling and appropriateness. • (Optional) Use a coding standard indentation such as four or eight spaces with no tabs. • Copy your new blocks into a custom directory with a unique name.
Sample Driver Mask Sample Driver Mask The following is the block mask for the Diamond MM-32 Analog Input block. If you were to create this mask as a new mask, you would: 1 Open the Mask Editor for the block. 2 Select the Parameters tab and click the Add button on the left three times. Three blank lines appear in the Dialog parameters section.
4 Masking Drivers Number of channels: Range Sample time: Base address (for example 0x300): • In the Variable column, enter the parameter names. Be sure that these names match the S-function parameters field of the S-Function block. configuration firstChan numChans range sampleTime base • In the Type column, select: popup edit edit popup edit edit • In the Evaluate and Tunable columns, ensure that the first five check boxes of Evaluate and all the check boxes for Tunable are selected.
Sample Driver Mask 3 Select the Initialization tab. The tab displays the dialog variables you entered in the Parameters tab. 4 In the Initialization code section, type phase = 2; [baseDec, maskDisplay, maskDescription] = maddiamondmm32(phase, configuration, firstChan, numChans, range, base); set_param(gcb, 'MaskDescription', maskDescription); set_param(gcb, 'MaskDisplay', maskDisplay); where maddiamondmm32 references the maddiamondmm32.m file for the driver.
4 Masking Drivers This example returns a string to display on the block with the variable port_label commands with which to label the input and output ports. The number and content of the port_label commands depend on the channel vector that the user enters in the mask. 5 Select the Documentation tab. This tab contains three fields, Mask type, Mask description, and Mask help. In the Mask type field, enter the type of driver.
Sample Driver Mask At InitFcn time, no variables in the mask exist yet. You cannot pass them into the InitFcn. However, in the function, you can get the string values using the get_param function. For example: function [baseDec, maskDisplay, maskDescription] = ...
4 4-12 Masking Drivers
5 Interrupt Support • “xPC Target Interrupts” on page 5-2 • “Adding Interrupt Support” on page 5-7 • “Hook Function Prototypes — Alphabetical List” on page 5-15
5 Interrupt Support xPC Target Interrupts In this section... “Introduction” on page 5-2 “Interrupt Processing in the xPC Target Environment” on page 5-2 Introduction If your device supports interrupts, you can use the procedures in this chapter to add your custom interrupt functions to the xPC Target framework.
xPC Target™ Interrupts The following illustrates the flow of processing once a hardware interrupt occurs. This is background information to help you understand the context in which the interrupt functions run.
5 Interrupt Support Interrupt occurs Call PreHookFunction (if one exists) No Did PreHookFunction return a value of XPC_RUN_ISR? Yes For each device on this IRQ Function call on interrupt? No Send wakeup to model thread Yes Async IRQ source block only (Call interrupt service function call subsystem; interrupt preemption disallowed) Yes Call PostHookFunction (if one exists) Another device? No Return from interrupt 5-4 Model thread executes after return from interrupt; new interrupts might preempt
xPC Target™ Interrupts When a hardware interrupt occurs, the generated code uses the following steps for each device on this IRQ to determine which device generated the interrupt: 1 Call the PreHook function, if one exists. The return value determines the action. 2 The generated code determines whether this device generated the interrupt. • If the PreHook function returns XPC_RUN_ISR, execution continues to step 3. • If the PreHook function returns XPC_DROP_ISR, the generated code goes to step 5.
5 Interrupt Support Note The Allow preemption of function call subsystem check box has no effect. Interrupts are never enabled when the function-call subsystem is executed.
Adding Interrupt Support Adding Interrupt Support In this section... “Introduction” on page 5-7 “Guidelines for Creating Interrupt Functions” on page 5-9 “Filling in the Driver board Structure” on page 5-10 Introduction To add interrupt handling for a custom driver, you must create • A descriptor file to connect a board type to the functions needed to start, handle, and stop interrupts • A C file to implement these functions Include the following functions.
5 Interrupt Support Function Description Start Runs as the last item when starting a model, just before the model runs. It is typically used to turn on interrupt generation. Program this function to enable interrupts on the board and start any action. Stop Runs at the beginning of a stop request, before any mdlTerminate entries for any block in the model runs. It is typically used to turn off interrupt generation. Program this function to disable interrupts from the board and stop any action.
Adding Interrupt Support 4 Copy the file sample_int.m to a unique file name in the following directory: matlabroot\toolbox\rtw\targets\xpc\target\build\ xpcblocks\thirdpartydrivers For example: your_company_name_int.m The xPC Target software searches in this directory for file names that end with _int.m and looks for board interrupt descriptions. 5 Open and edit the following file: matlabroot\toolbox\rtw\targets\xpc\target\build\ xpcblocks\thirdpartydrivers\your_company_name_int.
5 Interrupt Support matlabroot\toolbox\rtw\targets\xpc\target\build\ xpcblocks\thirdpartydrivers\ When modifying an existing hook file: • Change the names of all of the functions to match those you have selected for your board. • Do not change the function signatures. • Do not remove the __cdecl string. • The PreHook and PostHook functions run with interrupts disabled. Do not change the interrupt status in these functions.
Adding Interrupt Support • Depending on the bus type of your board, select a board structure of an existing board that has the same bus type. The information passed to the functions is slightly different for an ISA board or a PCI board. You will use this structure as a template for your own board entry. The following is a structure for an ISA or PC/104 device: board.name = 'RTD_DM6804'; board.VendorId = -1; board.DeviceId = 1; board.SubVendorId = -1; board.SubDeviceId = -1; board.
5 Interrupt Support that board with either two or four ID values, depending on the specific hardware. When calling the hook functions, the xPC Target kernel obtains the PCI information for the board and passes it to the hook functions. Use these parameters to help identify the interrupting board. - For VendorId and DeviceId, enter the IDs you get from the board manufacturer. - Many boards do not have SubVendorId and SubDeviceId values.
Adding Interrupt Support - PreHookFunction Prototype: int __cdecl - your_company_name_boardPreHook(xpcPCIDevice *pciInfo); PostHookFunction Prototype: void __cdecl your_company_name_boardPostHook(xpcPCIDevice *pciInfo); - StartFunction Prototype: void __cdecl your_company_name_boardStart(xpcPCIDevice *pciInfo); - StopFunction Prototype: void __cdecl your_company_name_boardStop(xpcPCIDevice *pciInfo); If any of these four functions does not need to exist, set the corresponding board structure e
5 Interrupt Support • HookIncludeFile — Interrupt handling file that contains the PreHookFunction, PostHookFunction, StartFunction, and StopFunction functions for this board. Specify this name without the .c extension. • Specify this structure for each board for which interrupt functions have been written. For example: board(1).name = 'name1'; . . . board(2).
Hook Function Prototypes — Alphabetical List Hook Function Prototypes — Alphabetical List • your_company_name_boardPostHook • your_company_name_boardPreHook • your_company_name_boardStart • your_company_name_boardStop 5-15
your_company_name_boardPostHook Purpose Run after return from interrupt service routine function-call subsystem or after sending wakeup call to model thread Syntax void __cdecl your_company_name_boardPostHook(xpcPCIDevice *pciInfo); Argument Description pciInfo Pointer to the PciDevice structure. your_company_name_boardPostHook is not typically required.
your_company_name_boardPreHook Purpose Run just before the interrupt service routine Syntax int __cdecl *pciInfo); Argument your_company_name_boardPreHook(xpcPCIDevice pciInfo Pointer to the PciDevice structure. Description your_company_name_boardPreHook runs just before the model-level Return This function must check the status register on the board to determine if the board caused the interrupt.
your_company_name_boardStart Purpose Run as the last item in mdlStart Syntax void __cdecl your_company_name_boardStart(xpcPCIDevice *pciInfo); Argument 5-18 pciInfo Pointer to the PciDevice structure. Description your_company_name_boardStart runs as the last item after all mdlStart functions. It is typically used to turn on interrupt generation.
your_company_name_boardStop Purpose Run at the beginning of mdlTerminate Syntax void __cdecl your_company_name_boardStop(xpcPCIDevice *pciInfo); Argument pciInfo Pointer to the PciDevice structure. Description your_company_name_boardStop runs before the mdlTerminate function of the blocks in the model. It is typically used to turn off interrupt generation.
your_company_name_boardStop 5-20
6 Custom xPC Target Driver Notes • “S-Function Guidelines” on page 6-2 • “mdlStart and mdlTerminate Considerations” on page 6-4 • “DMA Considerations” on page 6-5 • “Passing Parameters” on page 6-6 • “Accessing Registers” on page 6-7
6 Custom xPC Target™ Driver Notes S-Function Guidelines You implement xPC Target device driver blocks using Simulink S-functions. An S-function is a set of subroutines that implements a function. On the host, you can write an S-function in MATLAB code, C, or Fortran. For xPC Target device drivers, you must write an S-function in C. Simulink S-functions have a number of callback methods.
S-Function Guidelines is also compiled with your application to run on the target PC. Because of the following reasons, you must conditionally compile code for the host PC and the target PC. - The host PC runs Windows and the target PC runs the xPC Target kernel. - The host PC does not have the same I/O hardware as the target PC. The preprocessor symbol MATLAB_MEX_FILE is defined when you compile for simulation (via mex). Undefine this symbol when compiling for the xPC Target environment.
6 Custom xPC Target™ Driver Notes mdlStart and mdlTerminate Considerations When you load a target application onto a target PC, the driver executes the mdlStart callback method. If the execution is successful, the driver then executes mdlTerminate. If mdlStart does not successfully complete, the application does not execute mdlTerminate. (Typically, mdlStart might not successfully complete if the application cannot find a referenced I/O board or if the board does not successfully initialize.
DMA Considerations DMA Considerations If your board directly accesses system RAM, such as a DMA controller, you must allocate that memory using the xpcAllocPhysicalMemory function. This function allocates the buffer such that the buffer virtual address is the same as its physical address.
6 Custom xPC Target™ Driver Notes Passing Parameters See “Passing Parameters to S-Functions” in Developing S-Functions.
Accessing Registers Accessing Registers In this section...
6 Custom xPC Target™ Driver Notes • Structure struct bdregs { volatile int reg1; volatile int reg2; etc. }; struct bdregs *regs = pciInfo.VirtualAddress[1]; regs->reg1 = 0x1234; // Sets reg1 to that value regs->reg2 = 0x56789abc; etc. If your hardware uses registers with different lengths, it might be easier to use the structure method. • Array #define REG1 #define REG2 etc. 0 1 volatile int *aregs = pciInfo.
7 Creating Custom Drivers Using the xPC Target Driver Authoring Tool • “xPC Target Driver Authoring Tool” on page 7-2 • “Generating Custom Driver Templates” on page 7-4
7 Creating Custom Drivers Using the xPC Target™ Driver Authoring Tool xPC Target Driver Authoring Tool xPC Target Driver Authoring Tool helps you create templates for simple custom device drivers. A simple custom device driver is one that does not perform DMA or interrupt processing. The xPC Target Driver Authoring Tool is not useful for these more complicated applications. Based on the inputs you provide to xPC Target Driver Authoring Tool, it can create a number of files, including the following.
xPC Target™ Driver Authoring Tool Note The xPC Target Driver Authoring Tool creates custom driver templates using the Legacy Code Tool (LCT). You do not need any prior knowledge of the Legacy Code Tool to use the xPC Target Driver Authoring Tool. If you want to read about the Legacy Code Tool, see “Integrating Existing C Functions into Simulink Models with the Legacy Code Tool” in Developing S-Functions.
7 Creating Custom Drivers Using the xPC Target™ Driver Authoring Tool Generating Custom Driver Templates In this section...
Generating Custom Driver Templates The xPC Target Driver Authoring Tool is displayed. 3 In the Main tab, enter: • Driver name — The name for your driver. The tool will create supporting files using this string as the prefix. For example, type testdriver. • Sample time — Select one of the following: – Mask parameter — If you want the block sample time to be settable as a block dialog box parameter (Sample Time). – Inherited — If you want the block to inherit its sample time from a connected block.
7 Creating Custom Drivers Using the xPC Target™ Driver Authoring Tool • Size — Enter the maximum size number of storage locations to be allocated for the parameter. If you want this number to be a variable one, enter a value of 0. This setting means that you can pass an additional function argument that contains the size into the start, output, and/or terminate functions along with the port/parameter variable. • Type — From the list, select the data type for the input port.
Generating Custom Driver Templates function argument that contains the size into the start, output and/or terminate functions along with the port/parameter variable. • Start — Select the check box if you want the parameter value to be passed into the S-function mdlStart callback method. • Output — Select the check box if you want the parameter value to be passed into the S-function mdlOutputs callback method.
7 Creating Custom Drivers Using the xPC Target™ Driver Authoring Tool You can iteratively change the configuration and resave the MAT-file as often as you like. Reloading the Configuration The xPC Target Driver Authoring Tool allows you to reload your configuration session as a MAT-file. 1 In the xPC Target Driver Authoring Tool, click the Main tab. 2 Click Load settings. The tool loads the testdriver.mat file into the tool.
Generating Custom Driver Templates Note Use the xPC Target Driver Authoring Tool to build the C Mex file if you have not edited the C source code file (testdriver.c). If you have edited this file and want to keep those changes, do not use the xPC Target Driver Authoring Tool to build the driver. Doing so overwrites your changes to the C source code. Instead, use the mex function (see “Creating a C MEX File Using the mex Function” on page 7-9).
7 7-10 Creating Custom Drivers Using the xPC Target™ Driver Authoring Tool
8 I/O Structures — By Category xpcPCIDevice Type definition for PCI configuration space structure xpcTime Type definition of time structure
8 8-2 I/O Structures — By Category
9 I/O Structures — Alphabetical List
xpcPCIDevice Purpose Type definition for PCI configuration space structure Prototype typedef struct xpcPCIDeviceStruct{ uint32_T BaseAddress[6]; uint32_T VirtAddress[6]; uint32_T Length[6]; uint16_T AddressSpaceIndicator[6]; uint16_T MemoryType[6]; uint16_T Prefetchable[6]; uint16_T InterruptLine; uint16_T VendorId; uint16_T DeviceId; uint16_T SubDeviceId; uint16_T SubVendorId; } xpcPCIDevice; Header File xpctarget.
xpcPCIDevice AddressSpaceIndicator Indicates whether the board is I/O port mapped or memory-mapped. Values are one of the following. Verify this value in the hardware manufacturer manual for accuracy. MemoryType Description 0 Memory-mapped 1 I/O port mapped Type of memory. This field is relevant only if AddressSpaceIndicator has a value of 0.
xpcPCIDevice of these addresses. Base addresses are filled in during the BIOS plug and play initialization, before the xPC Target kernel starts to execute. The hardware designer of the board decides how many address spaces are defined and what they are used for. Many boards use one address space to contain all of the registers for the board, other boards separate functions into different address spaces. See the board hardware manufacturer manual for this information.
xpcTime Purpose Type definition of time structure Prototype typedef struct xpcTime64Struct{ uint32_T NanoSecondsLo; uint32_T NanoSecondsHi; } xpcTime64; typedef union xpcTimeStruct{ xpcTime64 U64; //uint64_T NanoSeconds; } xpcTime; Header File Members xpctarget.h U64.NanoSecondsLo Bottom 32 bits of 64-bit value. U64.NanoSecondsHi Top 32 bits of 64-bit value. Description The xPCTime structure holds the time value in nanoseconds, as a 64-bit integer.
xpcTime 9-6
10 I/O Functions — By Category Port I/O (p. 10-2) I/O port input and output functions for byte, word and double word accesses PCI Configuration Information (p. 10-2) Work with PCI devices through the PCI configuration space Physical Memory (p. 10-2) PCI memory management functions Time (p. 10-2) xPC Target timing functions Miscellaneous (p.
10 I/O Functions — By Category Port I/O xpcInpB, xpcInpW, xpcInpDW I/O port input functions for byte, word, and double word accesses xpcOutpB, xpcOutpW, xpcOutpDW I/O port output functions for byte, word, and double word accesses PCI Configuration Information xpcGetPCIDeviceInfo Return information for PCI device xpcShowPCIDeviceInfo Display contents of PCIDevice structure Physical Memory xpcAllocPhysicalMemory Allocate physical memory xpcFreePhysicalMemory Free physical memory xpcReserveMemory
Miscellaneous Miscellaneous xpcBusyWait Wait for specified length of time in seconds xpcIsModelInit Return target application load state 10-3
10 10-4 I/O Functions — By Category
11 I/O Functions — Alphabetical List
xpcAllocPhysicalMemory Purpose Allocate physical memory Prototype void *xpcAllocPhysicalMemory(uint32_T numBytes) Header File xpctarget.h Arguments Description numBytes Allocate specified number of bytes of memory. The xpcAllocPhysicalMemory function allocates the requested bytes of physical memory. Functions such as malloc only return virtual memory. xPCAllocPhysicalMemory allocates physical memory, where physical memory is the same as the virtual address.
xpcBusyWait Purpose Wait for specified length of time in seconds Prototype void xpcBusyWait(real_T seconds) Header File xpctarget.h Arguments Description seconds Length of time to wait, in seconds. The xpcBusyWait function waits for the specified number of seconds. This function blocks this specified amount of time.
xpcFreePhysicalMemory Purpose Free physical memory Prototype void xpcFreePhysicalMemory(const void *physical) Header File xpctarget.h Arguments 11-4 physical Free specified memory. Description The xpcFreePhysicalMemory function frees the specified section of physical memory.
xpcGetElapsedTime Purpose Return time since system boot Prototype real_T xpcGetElapsedTime(xpcTime *upTime) Arguments upTime Pointer to an xpcTime structure. Description The xpcGetElapsedTime function returns the time since the system was last booted, in seconds. You can get this time in nanoseconds by passing a pointer to a previously allocated xpcTime structure. You can pass a NULL pointer for the upTime argument if you do not want the time in nanoseconds.
xpcGetPCIDeviceInfo Purpose Return information for PCI device Prototype int32_T xpcGetPCIDeviceInfo (uint16_T vendorId, uint16_T deviceId, uint16_T subVendorId, uint16_T subDeviceId, uint16_T bus, uint16_T slot, xpcPCIDevice *pciInfo); Arguments vendorId Enter the vendor ID. deviceId Enter the device ID. subVendorId Enter the subvendor ID. subDeviceId Enter the subdevice ID. bus Enter the device bus. slot Enter the slot that contains the device. pciInfo Pointer to the PciDevice structure.
xpcGetPCIDeviceInfo using only vendor ID and device ID, use XPC_NO_SUB for subDeviceId and XPC_NO_SUB for subVendorId. This function returns 0 upon success. Otherwise, it returns a nonzero value.
xpcInpB, xpcInpW, xpcInpDW Purpose I/O port input functions for byte, word, and double word accesses Prototype uint8_T xpcInpB(uint16_T port) uint16_T xpcInpW(uint16_T port) uint32_T xpcInpDW(uint16_T port) Arguments 11-8 port Enter the port value Header File xpctarget.h Description These functions input data from the I/O port space. Use xpcInpB for byte access (8-bit), xpcInpW for word accesses (16-bit), and xpcInpDW for double word accesses (32-bit).
xpcIsModelInit Purpose Return target application load state Prototype boolean_T xpcIsModelInit(void) Header File xpctarget.h Arguments Description none The xpcIsModelInit function returns a Boolean value to indicate the target application load state: • true — While target application is loading • false — Start of target application execution You can call this function from the mdlStart and mdlTerminate callbacks.
xpcOutpB, xpcOutpW, xpcOutpDW Purpose I/O port output functions for byte, word, and double word accesses Prototype void xpcOutpB(uint16_T port, uint8_T value) void xpcOutpW(uint16_T port, uint16_T value) void xpcOutpDW(uint16_T port, uint32_T value) Arguments port Enter the port value value Contains the output value Header File xpctarget.h Description These functions output data to the I/O port space.
xpcReserveMemoryRegion Purpose Return virtual address that corresponds to physical address and mark region as readable/writable Prototype void * xpcReserveMemoryRegion(const void *physical, uint32_T numBytes, uint32_T access) Arguments physical Starting address of the memory region to be reserved. This is typically obtained from one of the PCI base address registers. numBytes Size of region to be located, in bytes. access Type of access, limited to XPC_RT_PG_USERREADWRITE (read/write).
xpcShowPCIDeviceInfo Purpose Display contents of PCIDevice structure Prototype void xpcShowPCIDeviceInfo(xpcPCIDevice *pciInfo) Arguments Description pciInfo Pointer to the xpcPCIDevice structure. This debugging function displays the contents of the PCIDevice structure pointed to by pciInfo. You can use this function with the xpcGetPCIDeviceInfo function to display the contents of the xpcPCIDevice structure. Note Remove this function from the driver before deploying.
xpcSubtractTime Purpose Return difference between two times Prototype real_T xpcSubtractTime(xpcTime *time, const xpcTime *time2, const xpcTime *time1) Arguments Description time Pointer to an xpcTime structure. time2 Enter the time to subtract. time1 Enter the time to subtract from. xpcSubtractTime returns the difference between time1 and time2 (time2 - time1), in seconds. You can get this time in nanoseconds by passing a pointer to a previously allocated xpcTime structure.