none
Use CriticalSection and KernelIoControl to share resource between OAL and driver RRS feed

  • Question

  • Hi,

    Is it possible to share a resource between the OAL and a driver using a CritcalSection in the OAL and a KerneIOControl which is called from the driver which does Enter/Leave CS in CE6 ?

    Thanks

    Sbstn_rf

    Thursday, June 20, 2013 9:10 PM

All replies

  • you mean you want the KernelIOControl to act as a CS. I am not sure no this. But there are other tricky way to make a sharable resource between OAL and driver.

    1) you can use critical section inside the OAL. SInce it is the part of the kernel, you can see the NKGLOBAL structure and the \WINCE600\PRIVATE\WINCEOS\COREOS\NK\NKSTUB.c which is included as a library while building the OAL.exe in your BSP.

    I can take the sharable resource as I2C bus

    Using the resource in OAL

    2) Create a library to access the I2C bus in OAL. This library should be capable of doing Init ,Read, write etc..

    3) use the critcal section in the necessary function in the library (required for read, write functions)

    4) To access the device in OAL, you can directly link the I2C library

    Using the resource in Driver

    1) Create a KernelIOControl in OAL. Create a Function pointer table for all the function in the I2C library as shown below

    //------------------------------------------------------------------------------
    //
    //  Define:  IOCTL_DDK_GET_OAL_I2C_IFC
    //
    //  This IOCTL code is used to obtain the function pointers to the OAL
    //  i2c functions.
    //
    #define IOCTL_DDK_GET_OAL_I2C_IFC \
        CTL_CODE(FILE_DEVICE_I2C, 0x0100, METHOD_BUFFERED, FILE_ANY_ACCESS)
    
    typedef struct {
        void      (*fnI2CLock)(UINT idI2C);
        void      (*fnI2CUnlock)(UINT idI2C);    
        HANDLE    (*fnI2COpen)(UINT devId, void *pData);
        void      (*fnI2CClose)(void *pData);
        UINT      (*fnI2CWrite)(void *hCtx, UINT32 subAddr, VOID *pBuffer, UINT32 size);
        UINT      (*fnI2CRead)(void *hCtx, UINT32 subAddr, VOID *pBuffer, UINT32 size);
    } OAL_IFC_I2C;
    //-----------------------------------------------------------------------------
    //
    //  Function:  OALIoCtlHalI2CCopyFnTable
    //
    //  returns OAL i2c routines to be called directly from drivers
    //
    BOOL 
    OALIoCtlHalI2CCopyFnTable(
        UINT32 code, 
        VOID *pInBuffer,
        UINT32 inSize, 
        VOID *pOutBuffer, 
        UINT32 outSize, 
        UINT32 *pOutSize
        )
    {
        BOOL rc = FALSE;
        OAL_IFC_I2C *pIn;
    
        OALMSG(OAL_IOCTL&&OAL_FUNC, (L"+OALIoCtlHalI2CCopyFnTable\r\n"));
        
        if (pInBuffer == NULL || inSize != sizeof(OAL_IFC_I2C))
            {
            goto cleanUp;
            }
    
        // update info and call appropriate routine
        //
        if (pOutSize != NULL) *pOutSize = sizeof(OAL_IFC_I2C);
        pIn = (OAL_IFC_I2C*)pInBuffer;
    
        pIn->fnI2CLock = OALI2CLock;
        pIn->fnI2CUnlock = OALI2CUnlock;
        pIn->fnI2COpen = OALI2COpen;
        pIn->fnI2CClose = OALI2CClose;
        pIn->fnI2CWrite = OALI2CWrite;
        pIn->fnI2CRead = OALI2CRead;
        rc = TRUE;
        
    cleanUp:
        OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIoCtlHalI2CCopyFnTable(rc = %d)\r\n", rc));
        return rc;
    }
    

    2) You can call this IOCTL from your driver to get the function of the I2C as shown below

    //-----------------------------------------------------------------------------
    static OAL_IFC_I2C      _i2cFnTable;
    static BOOL             _bI2CFnTableInit = FALSE;
    
    
    //-----------------------------------------------------------------------------
    static
    BOOL
    I2CInitialize()
    {
        if (_bI2CFnTableInit == FALSE)
            {
            // get I2C function table from kernel
            if (KernelIoControl(IOCTL_HAL_I2CCOPYFNTABLE, (void*)&_i2cFnTable,
                    sizeof(OAL_IFC_I2C), NULL, 0, NULL))
                {
                _bI2CFnTableInit = TRUE;
                }
            }
        return _bI2CFnTableInit;
    }
    
    

    3) Now you can access the I2C function from your driver.


    Vinoth.R

    www.e-consystems.com

    http://vinoth-vinothblog.blogspot.com

    Friday, June 21, 2013 5:14 AM