Search

Technical Discussion Group Forum

This forum is provided for user discussion. While Beacon EmbeddedWorks support staff and engineers participate, Beacon EmbeddedWorks does not guarantee the accuracy of all information within in the Technical Discussion Group (TDG).

The "Articles" forums provide brief Articles written by Beacon EmbeddedWorks engineers that address the most frequently asked technical questions.

To receive email notifications when updates are posted for a Beacon EmbeddedWorks product download, please subscribe to the TDG Forum of interest.

TDG Forum

PrevPrev Go to previous topic
NextNext Go to next topic
Last Post 20 Dec 2004 01:39 PM by  scobb
installable ISR
 23 Replies
Sort:
You are not authorized to post a reply.
Page 1 of 212 > >>
Author Messages
mpinton
New Member
New Member
Posts:


--
08 Jun 2004 07:16 AM
    Hi,
    I plan on creating a couple IISRs. The BSP supports this correct?
    Thanks,
    /michel
    mikee@logicpd.com
    New Member
    New Member
    Posts:


    --
    15 Jun 2004 02:30 PM
    Michel,

    Yes, the BSP does support installable ISR's. Give her a go and let us know if you need any more help.

    --mikee
    mpinton
    New Member
    New Member
    Posts:


    --
    15 Jun 2004 02:55 PM
    Awesome.
    I plan on using IISRs for uP_IRQA/B/C/D. There should be no issue with these interrupts?
    /michel
    mpinton
    New Member
    New Member
    Posts:


    --
    18 Jun 2004 02:06 PM
    Hi,
    Is IOCTL_CODES.h (\WINCE420\PLATFORM\LoCE_A400_rel_100\inc) the right place to put my IOCTLs I am going to create to support my own IISR and device drivers? You've got 6 IOCTLs defined in there now.
    I am alittle confused by the comment in that file about which numbers I can use:
    /*
    * Note: the kernel uses IOCTL codes starting with 0x01010000 through
    * 0x01012458 (16,842,752 - 16,852,056). Do NOT conflict with them!
    * Put all platform IOCTL's in this file.
    */

    vs what's in winiotl.h (WINCE420\PUBLIC\COMMON\SDK\INC) which talks about :
    //
    // Macro definition for defining IOCTL and FSCTL function control codes. Note
    // that function codes 0-2047 are reserved for Microsoft Corporation, and
    // 2048-4095 are reserved for customers.
    //

    and:
    //
    // Define the various device type values. Note that values used by Microsoft
    // Corporation are in the range 0-32767, and 32768-65535 are reserved for use
    // by customers.
    //

    TIA,
    /michel
    mikee@logicpd.com
    New Member
    New Member
    Posts:


    --
    18 Jun 2004 02:23 PM
    michel,

    In looking at the file IOCTL_CODES.h, I can see where you would be confused. In fact, that is pretty old code right there. The reason it works is probably more than you are interested in right now. However, a more correct way to declare an IOCTL for yourself would be:

    #define MY_IOCTL CTL_CODE(FILE_DEVICE_HAL, (some unique number), METHOD_BUFFERED, FILE_ANY_ACCESS)

    For instance, I have an IOCTL which allows people to query the boot parameter string which is defined as:

    #define IOCTL_LPD_GET_HAL_PARAM_VALUE \
    CTL_CODE(FILE_DEVICE_HAL,('l'+'p'+'d'+0),METHOD_BUFFERED,FILE_ANY_ACCESS)

    I use the addition of the characters 'l', 'p', and 'd' plus a numeric constant to generate what (I feel fairly confident) will be some unique salt for the CTL_CODE macro.

    If you look in WINCE420\PUBLIC\COMMON\SDK\INC\winioctl.h and D:\WINCE420\PUBLIC\COMMON\OAK\INC\pkfuncs.h, you should be able to figure out what is going on.

    Where you declare these IOCTLs is up to you and IOCTL_CODES.h certainly is a central location. I actually prefer to try and keep definitions as local as possible. So if this is an IOCTL for your driver, for instance one used to communicate between a driver dll and its ISR dll, then I would keep the declaration with the driver. But again, it is completely up to you.

    Hope that helps, write back if it didn't.

    --mikee
    mpinton
    New Member
    New Member
    Posts:


    --
    02 Sep 2004 09:27 AM
    Hi,
    For uP_nIRQA/B/C, which GPIO do these match up with in port F? Do I need to do any interrupt setup for these (like ITENS and Port F GPIO registers)? Or are they all ready to go and use (setup in your OAL code)?

    Thanks,
    /michel
    mpinton
    New Member
    New Member
    Posts:


    --
    15 Sep 2004 07:11 AM
    Hi,
    In my IISR can I address the 7A400 registers directly? Or do I have to map them? The IISR DLL is actually loaded by NK, not Device, right?

    Thanks,
    /michel
    mikee@logicpd.com
    New Member
    New Member
    Posts:


    --
    15 Sep 2004 12:01 PM
    m,

    You can address the registers within your ISR, but you need to be somewhat tricky about it. You are on the right track when you say nk loads the ISR instead of device, but your not quite right. I'll try and explain.

    The installable ISR (call it isr.dll) is going to be loaded by device.exe when it loads the rest of the device driver. However, device.exe is going to insert isr.dll into the kernel's address space. This is important for the following reason.

    Typically, when your code runs, it uses virtual addresses. When you want to access a physical address, such as a hardware register, you need to map that physical address into the virtual address space of the running process. This is easily done by a call to the API function; MmMapIoSpace(). That function maps a physical address into the virtual address space of the calling thread.

    However, isr.dll isn't going to be running within the virtual address space of device.exe like the rest of your driver. It is going to be running within the kernel's address space. So, instead of using MmMapIoSpace() you need to use a different function. The magical API call is TransBusAddrToStatic(). This will map a physical address into the kernel's space. You then pass these memory mapped addresses to isr.dll using the I/O control call, KernelLibIoControl(..., IOCTL_GIISR_INFO, ...).

    Within Platform Builder's help file, check the following topics :

      TransBusAddrToStatic
      Installable ISRs with Drivers
      GIISR_INFO
      KernelLibIoControl


    Also, check out Microsoft's example installable ISR code in:

    x:\WINCE420\PUBLIC\COMMON\OAK\DRIVERS\GIISR

    This is the basic code for an installable ISR. Yours won't need to be quite so general as you probably know what size registers you are accessing, etc.

    Also, a couple of MS's drivers within x:\WINCE420\PUBLIC\Common\Oak\Drivers use an installable ISR as well. I forget which ones right now, but if you do a search for a GIISR_INFO structure, you should be able to find it.

    Hope this helps,
    --mikee
    mpinton
    New Member
    New Member
    Posts:


    --
    13 Oct 2004 07:09 AM
    Hi,
    Well I've got my driver installed and working but my IISRs are failing. As device.exe is going through the list of builtins in the registry as it begins the DLLMain call into the first of my IISRs I am getting an exception (a bad address) - this is in the _preamble_ code prior to my DllMain function.
    Is there anything special to build an IISR (compiler and/or linker options, anything in .bib, anything about any .libs in can or can/not reference, can it use DEBUGMSG macros, etc)?
    TIA,
    /michel
    mikee@logicpd.com
    New Member
    New Member
    Posts:


    --
    13 Oct 2004 09:24 AM
    Nothing that wouldn't be expected.

    Make sure that the sources file that builds the IISR sets:

      WINCEOEM=1
      NOLIBC=1
      NOMIPS16CODE=1


    You can read up what those do in the help file. I will tell you that "NOMIPS16CODE" is the worst naming ever for a variable! It actually has nothing to do with a MIPS processor. Instead, it enables the /QRimplicit-import- compiler flag. This prevents the compiler from importing helper functions. You need this because your IISR will be running in kernel space and you won't be able to "thunk" through to the standard libraries.

    Let me know if that helps,
    --mikee
    mpinton
    New Member
    New Member
    Posts:


    --
    13 Oct 2004 12:13 PM
    OK, I didn't have the NOLIBC and NOMIPS16CODE macros, so I'll add those. You are right, I assumed the NOMIPS16CODE macro had something to do with a MIPS processor so never even thought to investigate what it really was. I'll let you know how it goes.

    Thanks,
    /michel
    mpinton
    New Member
    New Member
    Posts:


    --
    14 Oct 2004 01:07 PM
    Does it matter whether the source code for the IISR DLL is in a ".c" or ".cpp" file - e.g. is there anything out of the normal that I would need to account for if my source is in ".cpp" file and thus using the c++ compiler?

    /michel
    mikee@logicpd.com
    New Member
    New Member
    Posts:


    --
    14 Oct 2004 02:00 PM
    Hmmm,

    Good question. It is quite possible that it needs to be a *.c file. I know that sounds kind of crazy, but I've seen the PB compilers do very strange things before.

    Is there any reason that it needs to be a *.cpp file? If not, I would change it and give it a whirl.

    --mikee
    mpinton
    New Member
    New Member
    Posts:


    --
    14 Oct 2004 02:24 PM
    I can try renaming to ".c" and see what happens.

    In regards to the WINCEOEM, NOLIBC, and NOMIPS16CODE macros, how do I set them in the PB IDE so that they affect (and only affect) the IISR DLLs? I have other driver DLLs that are non-IISR that I would not want affected. I have a separate project for each of them (3), under my platform, in the Features tab they are listed under "User features", and under a master workspace.

    I tried setting them as environment variables in the Custom Build Feature Build step, but that didn't do it. NExt I tried to set hen as environment variables in the Environment tab of the settings for each .pbp file. Neither worked.

    TIA,
    /michel
    mikee@logicpd.com
    New Member
    New Member
    Posts:


    --
    14 Oct 2004 02:31 PM
    Don't try to set that stuff up in the IDE, you will only cause yourself heartache. Just set it up in the 'sources' file of the IISR directory. That way it will only affect code being built in that particular section.

    If you actually created those drivers using PB's visual tools, you are, unfortunately, on your own When you do something like that, PB uses a different build scheme. That's why I do everything using *.cec, sources, and dirs files. That way, I know exactly how the code is being built.

    --mikee
    mpinton
    New Member
    New Member
    Posts:


    --
    14 Oct 2004 02:32 PM
    argh! now you tell me! I have been doing everything in the PB IDE.
    mikee@logicpd.com
    New Member
    New Member
    Posts:


    --
    14 Oct 2004 02:50 PM
    Sorry man,

    The build system was one of, if not the, major item Microsoft was trying to fix with CE 5.0. They have always had serious problems with it.

    The fact is, building something using a *.cec file and a sources file is substantially different than building something using a workspace file. It was explained to me once. Something to do with the fact that originally, CE was always built from the command line using dirs and sources files and the nmake program. Then, when they really started to concentrate on the IDE, they based it on Visual C++ which used some other build mechanism. Thus, the two build systems trying to exist side by side.

    It is all suppossed to be fixed in 5.0 now, but I haven't really checked it out yet, so I'll refrain from any rants or raves.

    Typically, I/we build everything from the command line because the IDE is slow and painful to build with. Most of the other WinCE gurus that I know, including MS's own WinCE development team do so as well.

    Theoretically, both should work. However, as I never use PB's project creator, I can't speak for it. I have learned to not expect too much from PB as a tool, thus I don't push it into anything I don't know that it can handle.

    --mikee
    mpinton
    New Member
    New Member
    Posts:


    --
    27 Oct 2004 02:27 PM
    Hi,
    Well, I am not having much luck with my IISRs. I am failing the call to InterruptIntialize (actually it's something in OEMInterruptEnbable() via the DoInterruptEnable() that's in the SC_InterruptInitialize call) and have no clue why.

    Essentially, I have a device driver DLL that Device.exe is loading, calling it's initialization function. In that init function I configure and setup the IISRs for 3 interrupts (IRQA/B/C).

    Essentially for each, I do a LoadIntChainHandler passing in the IRQ #(I use INTC_GPIO1INTR_BIT, INTC_GPIO2INTR_BIT, INTC_GPIO0FIQ_BIT). This works (at least for the first IRQ). After which I call InterruptInitialize passing in the sysintr #(SYSINTR_IRQB, SYSINTR_IRQC, SYSINTR_IRQA).


    // chain our ISR to the IRQ
    *lphISR = ::LoadIntChainHandler(szNameDLL, szNameHndlr, ucIrq);
    if (!(*lphISR))
    {
    DEBUGMSG(ZONE_ERROR,
    (_T("LNG_Init: LoadIntChainHandler('%s', '%s', '%d') failed %u\r\n"),
    szNameDLL, szNameHndlr, ucIrq));
    return(FALSE);
    }

    // initialze the interrupt (CE's standpoint)
    if (!::InterruptInitialize(dwSysIntr, *lphThreadEvent, 0, 0))
    {
    DEBUGMSG(ZONE_ERROR,
    (_T("LNG_Init: InterruptInitialize('%x') failed\r\n"), dwSysIntr));
    return(FALSE);
    }



    I then create the thread for the IISRT and set it's priority (I never get this far). Any ideas??

    TIA,
    /michel
    mikee@logicpd.com
    New Member
    New Member
    Posts:


    --
    27 Oct 2004 02:44 PM
    Are you obtaining the SysIntr value from the OAL via a call to KernelIoControl() with IOCTL_HAL_REQUEST_SYSINTR?

    Something like so:


    DWORD sys_intr, irq;
    BOOL ret_val;

    irq = /*Whatever hardware IRQ you are hooking. */

    ret_val =
    KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,
    (VOID *)(&irq),
    sizeof(irq),
    (VOID *)(&sys_intr),
    sizeof(sys_intr),
    NULL);

    if ( !ret_val )
    {
    DEBUGMSG("ERROR, COULDN'T GET SYSINTR!");
    goto fail;
    }

    /* Now, install the ISR, passing it the value of the SysIntr
    that it is suppossed to return to the OAL if it detects a
    valid interrupt. */

    /* Now, call InterruptInitialize with the value of SysIntr. */
    InterruptInitialize(sys_intr, ....);


    I ask because a call to InterruptInitialize() would definiately fail if given a bad SysIntr value, or one that that OAL didn't know about yet.

    Also, it appears that you are using C++. Is this true? If it is, I don't think you should. I know it sounds kind of crazy and reactionary, but I wouldn't trust MS's compilers to do the right thing in the case of a driver.

    Maybe you should just have our app's team knock this out for you. I'm sure it would be quick and you could learn from them what they did to get it to work.

    --mikee
    mpinton
    New Member
    New Member
    Posts:


    --
    28 Oct 2004 01:12 PM
    Mike,
    Thanks for the info on having to use the IOCTL_HAL_REQUEST_SYSTINR to get a sysintr assigned for the irq. I have that part working now. And using c++ doesn't seem to hurt.

    I also eventually picked out the correct compiler and linker settings to get the IISR DLLs to build properly in the PB IDE though it was a tedious process.

    I still have some issues though. When I looked at oalintr.h I see the SYSINTR_IRQA/B/C macros assigned. When I call KernelIOControl with the IOCTL_HAL_REQUEST_SYSINTR for the 3 sysintr's I need I get value that are quite different, in my case 0x14 (SYSINTR_ETHER), 0x15 (SYSINTR_AUDIO), and 0x16 (SYSINTR_PCMCIA_STATE). This is for a debug version running KITL. What gives? Or does it not matter, and I just need to make sure that whichever values I received from the IOCTL_HAL_REQUEST_SYSINTR are the ones that the IISRs return when they have a valid interrupt?

    Thanks,
    /michel
    You are not authorized to post a reply.
    Page 1 of 212 > >>