Writing Dll Files

  • Upload
    sun3813

  • View
    234

  • Download
    0

Embed Size (px)

Citation preview

  • 8/7/2019 Writing Dll Files

    1/18

    Writing DLLs and LabView: (1)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    Writing DLLs

    and calling DLLs from

    LabView

    byHeinz RongenForschungszentrum JlichZentrallabor fr Elektronik52425 Jlich, Germany

    email: [email protected]

  • 8/7/2019 Writing Dll Files

    2/18

    Writing DLLs and LabView: (2)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    1. What are DLLs ? _________________________________________________________3

    1. The Anatomy of a DLL ____________________________________________________3

    1.1. Outline of the Source Code of a DLL ________________________________________ 4

    2. Example Writing a DLL with Borland C/C++ (5.02)____________________________5

    2.1. C Language Source File __________________________________________________ 5

    2.2. The Header File ________________________________________________________ 7

    2.3. The Module Definition File ________________________________________________ 7

    2.4. Building the Project _____________________________________________________ 7

    3. Calling the DLL from LabView ______________________________________________8

    3.1. Advanced Topic Array and String Options __________________________________ 93.1.1. Arrays of Numeric Data__________________________________________________________ 9

    3.1.2. String Data ___________________________________________________________________ 9

    3.2. Array and String Tips __________________________________________________ 10

    3.3. Troubleshooting the Call Library Function and Your DLL ______________________ 11

    3.4. Important Reminders and Quick Reference __________________________________ 12

    3.5. Datatypes ____________________________________________________________ 13

    4. Hardware access: ________________________________________________________14

    4.1. Hardware access on different Windows Platforms: ____________________________ 14

  • 8/7/2019 Writing Dll Files

    3/18

    Writing DLLs and LabView: (3)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    1. What are DLLs ?

    A Dynamic Link Library (DLL) is a file of code,containing functions,

    that can be called from other executable code.(either an application or another DLL)

    Programmers use DLLs to provide code that they can reuse and toparcel out distinct jobs.Unlike an executable (EXE) file, a DLL cannot be directly run.DLLs must be called from other code that is already executing.

    In more understandable words, a DLL is a file which does a particular job, and allowsother programs to use its efforts in assisting the program's job. Some programs use aDLL so that they won't need to spend time figuring out how to do that job. Forexample, Microsoft has a DLL comctl32.dll which does all the user interface jobs(toolbars, text boxes, scroll bars, etc). So, other programs use that DLL so they won'thave to create their own edit boxes, etc.

    When a program requires a DLL to run, and can't find it, it won't be able to runbecause its suddenly missing the DLL to perform some of its critical work. We've all

    used DLLs before and we're using them now. They're required to run all Windowsprograms, including Windows but you never actually see them at work. There aredifferent versions of the same file name. Just because the file appears to be thesame doesn't mean it is. To check what version the file is, open Windows Explorer,locate the file and right click on it. Select Properties and click on the Version tab. Ifthere is no version tab then the file does not have a version number. Generally, if youhave a newer version of a file, don't replace it with an older version. Due to popularrequest, we are slowly adding version numbers to each individual file. This will takequite a while. Please bear with us.

    1. The Anatomy of a DLLDynamic linking is a mechanism that links applications to libraries at run time. Thelibraries remain in their own files and are not copied into the executable files of theapplications. DLLs link to an application when the application is run, rather than whenit is created. DLLs may contain links to other DLLs.

    Note: Many times, DLLs are placed in files with different extensions such as .EXE,.DRV or .DLL.

    Applications and DLLs can link to other DLLs automatically if the DLL linkage isspecified in the IMPORTS section of the module definition file as part of the compile

    or you can explicitly load them using the Windows LoadLibrary function.

  • 8/7/2019 Writing Dll Files

    4/18

    Writing DLLs and LabView: (4)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    1.1. Outline of the Source Code of a DLL

    The following example code illustrates the basic structure of a DLL:

    #include

    BOOL WINAPI DllEntryPoint ( HINSTANCE hInstDLL,

    DWORD fdwReason,

    LPVOID lpvReserved )

    {

    if (!hDLL) hDLL = hInstDLL; // save DLL handle

    switch (fdwReason)

    {case DLL_PROCESS_ATTACH: break;

    case DLL_THREAD_ATTACH: break;

    case DLL_PROCESS_DETACH: break;

    case DLL_THREAD_DETACH: break;

    }

    return (TRUE);

    }

    As shown in the example code, in Win32 the DllEntryPoint function is the

    main DLL entry point.

    Note: the Dll-Entry-Point function name is different for different Compiler systems:in Borland C/C++: DllEntryPoint

    in Microsoft Visual C/C++: DllMain

    TheDllEntryPoint function is called when a DLL is loaded or unloaded. The

    DllEntryPoint function is also called when a new thread is being created in a

    process already attached to the DLL, or when a thread has exited cleanly.

  • 8/7/2019 Writing Dll Files

    5/18

    Writing DLLs and LabView: (5)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    Finally, a DLL also contains functions that perform the activities the DLL expects toaccomplish. These functions are declared using the WINAPI keyword whenprototyping and declaring the functions.

    Additionaly the EXPORTS section in module definition files must be used to exportthese functions.

    DWORD WINAPI Func1 (DWORD a, DWORD b)

    {

    DWORD c;

    c = a + b;

    return (c);

    }

    2. Example Writing a DLL with Borland C/C++ (5.02)

    In some cases, you may want to write your own DLL, for example, to communicatewith your own custom-built hardware. In this section, you will find sample code thatillustrates how to create a simple DLL.

    To create a DLL, you will need the following four files:

    a C Language source file (required) a header file (optional may be part of the source code)

    a module definition file a project file (or set compiler options to generate a DLL

    2.1. C Language Source File

    The code on the following page is the C language source file for the DLL we willcreate in this example. It uses the standard WINAPI calling convention.

    The example DLL defines three simple functions: add_num adds two integers avg_num finds the simple average of an array of numeric data

    numIntegers counts the number of integers in a string

    In this example, we will create a VI that calls only one of these functions. As a furtherexercise on your own, create VIs that use the Call Library Function to use the otherfunctions in the DLL.

    After the listing of the source code for the DLL, you will also find listing for the customheader file, ourdll.h.

  • 8/7/2019 Writing Dll Files

    6/18

    Writing DLLs and LabView: (6)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    /* ourdll.c source code */

    #include

    #include "ourdll.h"

    DWORD WINAPI Func1 (DWORD a, DWORD b)

    {

    DWORD c;

    c = a + b;

    return (c);

    }

    long WINAPI avg_num (float *a, long size, float *avg)

    {

    int i;

    float sum=0;

    if(a != NULL)

    {

    for(i=0;i < size; i++)

    sum = sum + a[i];

    }

    else return (1);

    *avg = sum / size;

    return (0);

    }

    BOOL WINAPI DllEntryPoint ( HINSTANCE hInstDLL,DWORD fdwReason,

    LPVOID lpvReserved )

    {

    if (!hDLL) hDLL = hInstDLL; // save DLL handle

    switch (fdwReason)

    {

    case DLL_PROCESS_ATTACH: break;

    case DLL_THREAD_ATTACH: break;

    case DLL_PROCESS_DETACH: break;

    case DLL_THREAD_DETACH: break;

    }

    return (TRUE);

    }

  • 8/7/2019 Writing Dll Files

    7/18

    Writing DLLs and LabView: (7)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    2.2. The Header File

    The following code lists the header file ourdll.h. All of the functions we have created

    in the source code are available to other applications because they were exportedusing the _declspec (dllexport) keyword.

    DWORD WINAPI Func1 (DWORD a, DWORD b);

    long WINAPI avg_num (float *a, long size, float *avg);

    in Microsoft C++:_declspec (dllexport) DWORD Func1 (DWORD a, DWORD b);

    _declspec (dllexport) long avg_num (float *a, long size, float *avg);

    2.3. The Module Definition File

    A DLL can have a module definition file (.def) associated with it. The .def file containsthe statements for defining a DLL. e.g name of the DLL and the functions it exports.The only mandatory entries in the .def files are the LIBRARY statement and theEXPORT statement. The LIBRARY statement must be the first statement in the file.The name specified in the LIBRARY statement identifies the library in the importlibrary of the DLL. The EXPORTS statement lists the names of the functions exportedby the DLL. If you were using the _stdcall calling convention in your DLL, then youwould have to use the module definition file to export the functions that the DLL

    exposes, as shown below. This has to be done because the compiler mangles thefunction names. Following is the listing of the module definition file.

    LIBRARY ourDLL

    EXPORTS Func1avg_num

    2.4. Building the Project

    First, you will need to create the project. The steps to create a DLL are beingdescribed in the C Compiler manual.

    First create a new project by selecting New->Project from the File menu. Choose thetype as Dynamic Link Library. Name the project ourdll. Then create the header and Csource code files. Name them ourdll.h and ourdll.c. It is best to store all of these filesin the same directory. After adding these files to the project, compile the code into aDLL.

  • 8/7/2019 Writing Dll Files

    8/18

    Writing DLLs and LabView: (8)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    3. Calling the DLL from LabViewThis simple DLL can now be called by using the LabVIEW Call Library Function. Wewill create a VI called ARRAYAVG.VI that calls the avg_numfunction in ourdll.dll.

    Place a Call Library Functionicon on the block diagram and configure it to call theavg_numfunction.

    As specified in the previous diagram, first specify the location of the DLL by typing inthe path name. Also specify the name of the function you want to call in the DLL. Inthis case it is avg_num. The calling convention for this function in the DLL is C.The return type is Signed 32-bit Integer. The parameters to the function are an Array

    Data Pointer to 4-byte Single precision floating point numbers, a 32-bit SignedInteger which contains the size of the array, and a pointer to a 4-byte Single precisionfloating point value, which will return the average of the elements in the array. Createthe front panel shown in the Figure.Then, connect the appropriate controls and indicators to the Call Library Function

    icon.

  • 8/7/2019 Writing Dll Files

    9/18

    Writing DLLs and LabView: (9)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    After making the appropriate connections, run the VI.Congratulations! Youve written, compiled, and linked to your own DLL and called afunction within it from LabVIEW. If your DLL returns incorrect results or crashes,

    verify the datatypes and wiring to see if you miswired the wrong type of information.

    3.1. Advanced Topic Array and String Options

    This section of the document reviews some important concepts you should befamiliar with when using the Call Library Function to work with array and string

    data. Operations on arrays and strings of data make use of pointers, so thisinformation will be useful in helping you implement the Call Library Function.

    3.1.1. Arrays of Numeric DataArrays of numeric data can be of any integer type, or single (4-byte) or double (8-

    byte) precision floating point numbers. When you pass an array of data to a DLLfunction, you will see that you have the option to pass the data as an Array DataPointer or a LabVIEW Array Handle. When you pass an Array Data Pointer, you canalso set the number of dimensions in the array, but you do notinclude informationabout the size of the array dimension(s). DLL functions either assume the data is of aspecific size or expect the size to be passed as a separate input. Also, because thearray pointer refers to LabVIEW data, neverresize the array within the DLL. Doingthis may cause your computer to crash. If you must return an array of data, allocatean array of sufficient size in LabVIEW, pass it to your function, and have it act as thebuffer. If the data takes less space, you can return the correct size as a separateparameter and then on the calling diagram use array subset to extract the valid data.Alternatively, if you pass the array data as a LabVIEW Array Handle then you canuse the LabVIEW CIN functions to resize the array within the DLL. In order to callLabVIEW CIN functions from your DLL while using the C compiler you will have toinclude the library, labview.libfound in LabVIEW/cintools/Win32directory.

    3.1.2. String DataLabVIEW stores strings in a format similar to the Pascal string. The Call LibraryFunction works with LabVIEW String Handles or with either C or Pascal-style stringpointers. The difference between these formats is explained in the followingparagraphs. You can think of a string as an array of characters; assembling the

    characters in order forms a string. LabVIEW stores a string in a special format inwhich the first four bytes of the array of characters form a signed 32-bit integer thatstores how many characters appear in the string. Thus, a string with ncharacters willrequire n+ 4 bytes to store in memory. For example, the string text contains fourcharacters. When LabVIEW stores the string, the first four bytes contain the value 4as a signed 32-bit number, and each of the following four bytes contains a characterof the string. The advantage of this type of string storage is that NULL characters areallowed in the string. Strings are virtually unlimited in length (up to 2^31 characters).

    The Pascal string format is nearly identical to the LabVIEW string format, but insteadof storing the length of the string as a signed 32-bit integer, it is stored as an

    unsigned 8-bit integer. This limits the length of a Pascal style string to 255

  • 8/7/2019 Writing Dll Files

    10/18

    Writing DLLs and LabView: (10)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    characters. A Pascal string that is ncharacters long will require n+ 1 bytes ofmemory to store.The Pascal String Format C strings are probably the type of strings you will deal with

    most commonly. The similarities between the C-style string and normal numericarrays in C becomes much more clear when one observes that C strings aredeclared as char *, where char is typically an unsigned byte. C strings do not containany information that directly gives the length of the string, as do the LabVIEW andPascal strings. Instead, C strings use a special character, called the NULL character,to indicate the end of the string. NULL is defined to have a value of zero in the ASCIIcharacter set. Note that this is the number zero and not the character 0. Thus, in C,a string containing ncharacters requires n+ 1 bytes of memory to store: nbytes forthe characters in the string, and one additional byte for the NULL terminationcharacter. The advantage of C-style strings is that they are limited in size only byavailable memory. However, if you are acquiring data from an instrument that returns

    numeric data as a binary string, as is common with serial or GPIB instruments,values of zero in the string are possible. For binary data where NULLs may bepresent, you should probably use an array of unsigned 8-bit integers. If you treat thestring as a C-style string, your program will incorrectly assume that the end of thestring has been reached, when in fact your instrument is returning a numeric value ofzero.When you pass string data to a DLL, you must follow the same guidelines as forarrays. Specifically, neverresize a string, concatenate a string, or perform operationsthat may increase the length of string data passed from LabVIEW if you are using theC or Pascal string pointers. If you must return data as a string, you should firstallocate a string of the appropriate length in LabVIEW, and pass this string into theDLL to act as a buffer.

    Note: To use the LabVIEW CIN function calls you must add labview.lib to yourproject if you are using the Visual C++ compiler, or add labview.sym.lib to yourproject if you are using the Symantec compiler.

    3.2. Array and String Tips

    If your DLL function must create an array, change its size, or resize a string of datawithout using LabVIEW handles, then break the function into two steps. In the first

    step, determine the number of elements needed in the array, or the length of thestring to be returned. Have this function return the desired size to LabVIEW. InLabVIEW, initialize an array or string with default values, and pass this array to asecond function in your DLL, which actually places the data into the array. If you areworking with string-based instrument control, it may be easier to pass an array of 8-bit integers than C strings because of the possibility of NULL values in the string.

  • 8/7/2019 Writing Dll Files

    11/18

    Writing DLLs and LabView: (11)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    3.3. Troubleshooting the Call Library Function and Your DLL

    If, after configuring the Call Library Function dialog, you still have a broken Run

    arrow in LabVIEW, check to make sure that the path to the DLL file is correct. IfLabVIEW gives you the error message function not found in library, double-check thespelling of the name of the function you wish to call. Remember that function namesare case sensitive. Also, recall that you need to declare the function with the_declspec (dllexport) keyword in the header file and the source code or define it inthe exports section of the module definition file.Even if you have used the _declspec (dllexport) keyword and are using the _stdcallcalling convention, then you have to declare the DLL function name in the EXPORTSsection of the module definition file. If this is not done, the function will be exportedwith the mangled name, and the actual function name will be unavailable toapplications that call the DLL.

    If the function has not been properly exported, you will need to recompile the DLL.Before recompiling, make sure to close all applications and VIs that may make use ofthe DLL. If the DLL is still in memory, the recompile will fail. Most compilers will warnyou if the DLL is in use by an application.If youve already double-checked the name of the function, and have properlyexported the function, find out whether you have used the C or C++ compiler on thecode. If you have used the C++ compiler, the names of the functions in the DLL havebeen altered by a process called name mangling. The easiest way to correct this isto enclose the declarations of the functions you wish to export in your header file withthe extern C statement:

    extern C{

    /* your function prototypes here */}

    After properly configuring the Call Library Function, run the VI. If it does not run

    successfully, you might get errors or a General Protection Fault. If you get a GeneralProtection Fault, there are several possible causes. First, make sure that you arepassing exactlythe parameters that the function in the DLL expects. For example,make sure that you are passing an int16 and not an int32 when the function expects

    int16. Also confirm that you are using the correct calling convention _stdcall or C.

    Calling the DLL from another C program is also an excellent way to debug your DLL.By doing this, you have a means of testing your DLL independent of LabVIEW, thushelping you identify possible problems sooner.

  • 8/7/2019 Writing Dll Files

    12/18

    Writing DLLs and LabView: (12)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    3.4. Important Reminders and Quick Reference

    Make sure you use the proper calling convention (C or stdcall). Know the correct order of the arguments passed to the function.NEVERresize arrays or concatenate strings using the arguments passed directly

    to a function. Remember, the parameters you pass are LabVIEW data. Changingarray or string sizes may result in a crash by overwriting other data stored inLabVIEW memory. You MAY resize arrays or concatenate strings if you pass a

    LabVIEW Array Handle or LabVIEW String Handle and are using the Visual C++compiler or Symantec compiler to compile your DLL.

    When passing strings to a function, remember to select the correct type of stringto pass C or Pascal or LabVIEW string Handle.

    Remember, Pascal strings are limited to 255 characters in length.

    Remember, C strings are NULL terminated. If your DLL function returns numericdata in a binary string format (for example, via GPIB or the serial port), it mayreturn NULL values as part of the data string. In such cases, passing arrays ofshort (8-bit) integers is most reliable.

    If you are working with arrays or strings of data, ALWAYSpass a buffer or arraythat is large enough to hold any results placed in the buffer by the function unlessyou are passing them as LabVIEW handles, in which case you can resize themusing CIN functions under Visual C++ or Symantec compiler.

    Remember to list DLL functions in the EXPORTS section of the module definitionfile if you are using _stdcall.

    Remember to list DLL functions that other applications call in the moduledefinition file EXPORTS section or to include the _declspec (dllexport) keyword inthe function declaration.

    If you use a C++ compiler, remember to export functions with the extern C{}statement in your header file in order to prevent name mangling.

    If you are writing your own DLL, you should not recompile a DLL while the DLL isloaded into memory by another application (for example, your VI). Beforerecompiling a DLL, make sure that allapplications making use of the DLL areunloaded from memory. This ensures that the DLL itself is not loaded intomemory. You may fail to rebuild correctly if you forget this and your compiler doesnot warn you.

    Test your DLLs with another program to ensure that the function (and the DLL)behave correctly. Testing it with the debugger of your compiler or a simple Cprogram in which you can call a function in a DLL will help you identify whetherpossible difficulties are inherent to the DLL or LabVIEW related.

  • 8/7/2019 Writing Dll Files

    13/18

    Writing DLLs and LabView: (13)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    3.5. Datatypes

    LabView Description Bytes C Typechar character 1 charU8 unsigned 8 bit Integer 1 unsigned charU16 unsigned 16 bit Integer 2 unsigned shortU32 unsigned 32 bit Integer 4 unsigned longI8 signed 8 bit Integer 1 signed charI16 signed 16 bit Integer 2 signed shortI32 signed 32 bit Integer 4 signed longSGL single precision float 4 floatDBL double precision float 8 double

  • 8/7/2019 Writing Dll Files

    14/18

    Writing DLLs and LabView: (14)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    4. Hardware access:

    PC add on boards are either I/O or Memory mapped into the System address space.

    The PC uses 32 bit addresses for memory and 16 bit addresses for I/O. For I/O thismeans we have maximum 65536 I/O addresses (0..FFFF). The ISA Bus onlydecodes the lower 10 address lines, resulting in a I/O address range from 0..3FF(1024 I/O addresses) . PCI devices can use the full I/O address range up to FFFF.

    Access to the hardware is done with a normal memory access instructionsformemory mapped add on board, or with port I/O instructionsfor I/O mapped devices.

    Example: Write/Read from Memory/Port address 0x1234:

    memory mapped I/O mappeshort *ptr

    ptr = 0x1234;*ptr = 0x55; outw (0x1234, 0x55)

    x = *ptr; x = inpw (0x1234)

    4.1. Hardware access on different Windows Platforms

    We have to decide between 16 bit and 32 bit Windows Operating Systems:

    Win 3.11 Win 95 Win 98 Win-NT 4 Win 2000

    16 bit OS

    32 bit OS

    With 16 bit Windows-OS you have full access to all I/O and memory mapped devices

    from the Application layer. (DLL running at application level)In 32 bit Windows-OS hardware access is only possible with a Kernel Mode DeviceDriver.

  • 8/7/2019 Writing Dll Files

    15/18

    Writing DLLs and LabView: (15)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    Assembler Routines for Port I/O:

    void outp (WORD adr, BYTE data)

    {

    _DX = adr;

    _AL = data;

    __emit__ (0xEE);

    }

    BYTE inp (WORD adr)

    {

    _DX = adr;

    __emit__ (0xEC);

    return (_AL);

    }

    void outpw (WORD adr, WORD data)

    {

    _DX = adr;

    _EAX = data;

    __emit__ (0x66, 0xEF);

    }

    WORD inpw (WORD adr)

    {

    _DX = adr;

    __emit__ (0x66, 0xED);

    return (_AX);

    }

  • 8/7/2019 Writing Dll Files

    16/18

    Writing DLLs and LabView: (16)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    PCI Devices in an ISA World

    Abstract

    ISA add-in cards use IO address aliasing to get around the limited IO space availablein standard PC-compatibles. This aliasing (and the dependence upon it) means thatPCI devices must never require more than 256 bytes of contiguous IO space.

    Introduction

    This paper describes what ISA aliasing is and how it came into existence. Once ISAaliasing is understood, the obvious requirements on PCI devices are discussed.This paper is motivated by encounters with PCI devices that have required more than256 bytes of IO space. These devices will cause problems in systems also having anISA bus. How the problem shows up depends on the particular system, butsymptoms include: the BIOS is unable to initialize the PCI device

    (because the BIOS will not allocate an IO space larger than 256 bytes) ISA devices (that use IO aliasing) quit working,

    or won't work when the PCI device is in the system.

    ISA Aliasing

    Many years ago, when IBM first introduced its' "PC", the architecture for that systemwas such that motherboard devices only decoded the lower ten address lines for IOspace addresses This effectively limited the IO space of these early PCs to 1K bytes

    (210). The system design further mandated that of these 1K bytes of IO ports, the

    first 256 (addresses 0 thru 255) were reserved for motherboard devices, and the rest(addresses 256 thru 1023) were available for add-in devices.

    The Figure below shows how 16-bit IO addresses were decoded in these earlysystems.

    015 78910

    xxxxxx

    00 = motherboard device01,10,11 = add-in device

    selects particular IO port(motherboard or add-in)

    don't cares (not decoded)

    Some years later, the motherboard standard changed such that the upper six bits ofthe IO address were no longer don't-cares. Motherboard devices then did a full 16-bit decode and still tended to exist in the first 256 bytes of the IO space. This shouldhave allowed the full IO space (64K) to be used. However, by this time there weremany add-in cards that only did a 10-bit decode, so while motherboards were doinga full 16-bit decode, add-in cards still only looked at the bottom ten bits. This

    effectively fragmented the IO address space such that for each 1K (210) chunk of IO

    space the bottom 256 bytes are available for full 16-bit decode while the upper 768bytes are unusable because ISA cards are doing only a 10-bit decode.

  • 8/7/2019 Writing Dll Files

    17/18

    Writing DLLs and LabView: (17)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, GermanyTel: +49-(0)2461-614512 Fax: +49-(0)2461-613990 Email: [email protected]

    The Figure shows the fragmented IO address space.

    0x0000

    0x1000

    0x2000

    0xD000

    0xE000

    0xF000

    0xX000

    0xX400

    0xX500

    0xX800

    0xX900

    0xXC00

    0xXD00

    0xX100

    10-bit decode

    16-bit decode

    16-bit decode

    16-bit decode

    16-bit decode

    10-bit decode

    10-bit decode

    10-bit decode

    Full IO Space

    Sample 4K Chunk

    This fragmentation essentially left ISA add-in cards a total of 768 IO locations toperform whatever functions they wanted to perform. The sheer numbers of add-incards led to compatibility problems because two ISA cards would end up claiming the

    same IO addresses leading to one (or both) cards not working. Some defactostandards arose where certain classes of devices got certain IO locations, but thesehave not been sufficient for some functions.Many ISA add-in cards have gotten around this limitation by claiming a small numberof locations in the 10-bit range, and then using 16-bit aliases of those location to mapother device registers. For instance, if an ISA device uses the 10-bit address 0x300,it can also use the 16-bit aliases of that address (0x1300, 0x2300, ..., 0x0700,0x1700, 0x2700, ..., 0x0B00, 0x1B00, 0x2B00, ..., 0x0F00, 0x1F00, 0x2F00, ...). Forevery IO location in the 10-bit decode area, there are 63 16-bit aliases of thatlocation.

  • 8/7/2019 Writing Dll Files

    18/18

    Writing DLLs and LabView: (18)

    Heinz Rongen Forschungszentrum Jlich, ZEL 52425 Jlich, Germany

    PCI Device RequirementsHow does this ISA aliasing effect PCI devices? Let's take as an example a fictionalPCI device that for some reason is built so that it requires 4K of IO space. This IO

    space is requested and allocated using one of the Base Address registers in thedevice's configuration space. Let's assume that the BIOS assigns the PCI device 4KIO locations beginning at 0x4000. Any IO accesses that the processor makes withan address of 0x4XXX will be claimed by the PCI device. But an ISA card may alsobe expecting to use IO locations in this range. Typically this will mean that the ISAcard will not function in a system with this PCI device.This leads to the a basic rule for PCI devices if they want to reliably operate insystems containing an ISA bus. PCI devices must not require more than 256-bytes of contiguous IO space. This requirement implies that Base Registersrequesting IO space must implement writable bits in bit locations 31::8. If a smaller(than 256) amount of IO space is required then more writable bits should be

    implemented (eg. bits 31::4 for a 16 byte area).