locked
USB driver unloading when accessing function from another driver RRS feed

  • Question

  • I am working on i.MX51 platform. For a specific business need, I want to modify USB device driver configuration based on which audio codec chip is detected during startup. The codec hardware is being qualified for correct codec chip in the SGTL5000 codec device driver. For this, I declared a function in the codec driver (which is in cpp) with extern "C" as follows:

    int initSGTL500Success = 0;
    extern "C" int getSGTLInitSuccess(void)
    {
    return initSGTL500Success;
    }

    The variable initSGTL500Success will be updated in the codec driver when the correct codec chip is detected. I want to use this function getSGTLInitSuccess() in the USB driver (which is a c project, not cpp). I modified the codec .def file to include this function, included the correct audio codec .lib path in the linker settings of the USB driver. I make a call to this  function in the USB driver and make some decision based on the return value from the function. With this, I am able to successfully compile and link both the drivers. However, when I try to flash the code with this, the the USB driver hcd_hsotg.dll gets 'unloaded' as seen from the message:

    .

    .

    PB Debugger Loaded symbols for 'C:\WINCE700\OSDESIGNS\LAMPTRUNKPLATFORM\LAMPTRUNKPLATFORM\RELDIR\CONNECTCORE_I_MX51_WI-I_MX51_ARMV7_RELEASE\HCD_HSOTG.DLL'
    PB Debugger Unloaded symbols for 'C:\WINCE700\OSDESIGNS\LAMPTRUNKPLATFORM\LAMPTRUNKPLATFORM\RELDIR\CONNECTCORE_I_MX51_WI-I_MX51_ARMV7_RELEASE\HCD_HSOTG.DLL

    .

    .

    Strangely, if I just comment out the call to his function in the USB driver, everything works fine.

    This is the function where I make a call to it:

    static void ConfigH1(CSP_USB_REGS *pRegs)
    {
        USB_PORTSC_T portsc;
        USB_CTRL_T   ctrl;
        USB_USBCMD_T cmd;
        USB_CTRL_1_T ctrl1;
    HANDLE m_handleI2C;

        DWORD *temp;

    RETAILMSG(1,(TEXT("ConfigH1\r\n")));

        // Stop the controller first
        {
            temp = (DWORD *)&cmd;
            *temp = INREG32(&pRegs->H1.USBCMD);
            cmd.RS = 0;
            OUTREG32(&pRegs->H1.USBCMD, *temp);
            while ((INREG32(&pRegs->H1.USBCMD) & 0x1) == 0x1){
                 Sleep(100);
            }
        }
        // Do a reset first no matter what
        {
            temp = (DWORD *)&cmd;
            *temp = INREG32(&pRegs->H1.USBCMD);
            cmd.RST = 1;
            OUTREG32(&pRegs->H1.USBCMD, *temp);
            while ((INREG32(&pRegs->H1.USBCMD) & 0x1<<1) == (0x1<<1)){
                 Sleep(100);
            }
        }

        temp  = (DWORD *)&ctrl1;
        *temp = INREG32(&pRegs->USB_CTRL_1);
        if(getSGTLInitSuccess())
    ctrl1.uh1_ext_clk_en = 1;
    else
    ctrl1.uh1_ext_clk_en = 0;
        OUTREG32(&pRegs->USB_CTRL_1, *temp);
        RETAILMSG(1,(TEXT("SET uh1_ext_clk_en\r\n")));
        //usb_hs1_ulpi_interface_configure
        temp  = (DWORD *)&portsc;
        *temp = INREG32(&pRegs->H1.PORTSC);
        portsc.PTS = 0x2;

    {
        OUTREG32(&pRegs->H1.PORTSC, *temp);
        RETAILMSG(1,(TEXT("SET portsc.PTS = 0x2\r\n")));

        OUTREG32(&pRegs->H1.FRINDEX, 1);

        OUTREG32(&pRegs->H1.CONFIGFLAG, 1);

        //usb_h1_interrupt_enable
        temp =  (DWORD *)&ctrl;
        *temp = INREG32(&pRegs->USB_CTRL);
        ctrl.H1WIE = 1;
        ctrl.H1UIE = 1;
        ctrl.H1PM = 0;
        OUTREG32(&pRegs->USB_CTRL, *temp);

        {
            DWORD * tempCmd;
            tempCmd=(DWORD *)&cmd;
            *tempCmd=INREG32(&pRegs->H1.USBCMD);
            cmd.ITC=0;
            OUTREG32(&pRegs->H1.USBCMD, *tempCmd);
        }

        {
            temp = (DWORD *)&cmd;
            *temp = INREG32(&pRegs->H1.USBCMD);
            cmd.RST = 1;
            OUTREG32(&pRegs->H1.USBCMD, *temp);
            while ((INREG32(&pRegs->H1.USBCMD) & 0x1<<1) == (0x1<<1)){
                 Sleep(100);
            }
        }
    }
        Sleep(100);

        BSPUsbSetBusConfig((PUCHAR)(&pRegs->H1));

        return;
    }


    I have tried both msdn recommended methods :

    dll export : https://msdn.microsoft.com/en-us/library/aa278950(v=vs.60).aspx

    and

    .def : https://msdn.microsoft.com/en-us/library/aa278947(v=vs.60).aspx

    for interfacing the drivers in cpp and C, but both methods create same issue.

    I feel something is going seriously wrong when I try to call a function from the codec driver in the USB driver. Please suggest a way out of this.

    Thanks in advance,

    Pankaj.

        
    Monday, February 5, 2018 11:58 AM

Answers

  • The best (and only really correct way) is to use IOCTL calls between the drivers. The other way would be to use LoadLibrary and GetProcAddress. You can't statically link 2 drivers since drivers load in series and thus one driver will be loaded and the other isn't. A driver is not a "normal" DLL!

    Good luck,

    Michel Verhagen, eMVP
    Check out my blog: https://guruce.com/blog

    GuruCE
    Microsoft Embedded Partner
    NXP Proven Partner
    https://guruce.com
    Consultancy, training and development services.

    Interested in WEC on i.MX6?
    Get the only 100% stable and best performing i.MX6 BSP for WEC7 and WEC2013 here: https://guruce.com/imx6

    • Marked as answer by Pankaj Rodey Tuesday, February 6, 2018 2:03 PM
    Monday, February 5, 2018 7:52 PM
  • Alternatives

    1. Message queues
    2. Synchronization objects (maybe)
    3. Registry
    4. Shared memory or file

    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys

    • Marked as answer by Pankaj Rodey Tuesday, February 6, 2018 2:03 PM
    Monday, February 5, 2018 9:33 PM

All replies

  • The best (and only really correct way) is to use IOCTL calls between the drivers. The other way would be to use LoadLibrary and GetProcAddress. You can't statically link 2 drivers since drivers load in series and thus one driver will be loaded and the other isn't. A driver is not a "normal" DLL!

    Good luck,

    Michel Verhagen, eMVP
    Check out my blog: https://guruce.com/blog

    GuruCE
    Microsoft Embedded Partner
    NXP Proven Partner
    https://guruce.com
    Consultancy, training and development services.

    Interested in WEC on i.MX6?
    Get the only 100% stable and best performing i.MX6 BSP for WEC7 and WEC2013 here: https://guruce.com/imx6

    • Marked as answer by Pankaj Rodey Tuesday, February 6, 2018 2:03 PM
    Monday, February 5, 2018 7:52 PM
  • Alternatives

    1. Message queues
    2. Synchronization objects (maybe)
    3. Registry
    4. Shared memory or file

    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys

    • Marked as answer by Pankaj Rodey Tuesday, February 6, 2018 2:03 PM
    Monday, February 5, 2018 9:33 PM
  • Thanks for the reply. I opened i2c port in the USB driver to communicate with and re-qualify the codec chip which is ultimately an IOCTL call and that solved the problem.
    Tuesday, February 6, 2018 2:03 PM