Wince6.0 添加IOCTL

在WinCE5.0中,应用程序和驱动程序可以通过调用KernelIoControl(..)函数来访问WinCE内核,导致调用OEMIoControl函数,这样应用程序和驱动程序就可以访问到OAL中的资源了。但在WinCE6.0中,提供了更好的安全性,应用程序能够访问OEMIoControl中的case受到了限制,只有下面的这些case是可以让应用程序访问的:
IOCTL_HAL_GET_CACHE_INFO
IOCTL_HAL_GET_DEVICE_INFO
IOCTL_HAL_GET_DEVICEID
IOCTL_HAL_GET_UUID
IOCTL_PROCESSOR_INFORMATION
如果用户在应用程序中试图访问其他的case,肯定会返回失败的。在WinCE6.0中,驱动程序还像以前一样,可以访问OEMIoControl中的任何case。也许有人会问,那么我们如何让应用程序也访问到一些case呢?既然微软已经公开了这些代码,我们就可以修改了,哈哈!以下以我添加用户设置UUID为例,详细讲解如何添加IOCTL了:

 

1. D:/WINCE600/PUBLIC/COMMON/OAK/INC/pkfuncs.h 添加要设置的IOCTL:


#define IOCTL_SET_KERNEL_COMM_DEV               CTL_CODE(FILE_DEVICE_HAL, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_HAL_GET_UUID                      CTL_CODE(FILE_DEVICE_HAL, 13, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_HAL_SET_UUID                      CTL_CODE(FILE_DEVICE_HAL, 3000, METHOD_BUFFERED, FILE_ANY_ACCESS) //Hugo

 

 

2.  D:/WINCE600/PUBLIC/COMMON/OAK/OALIOCTL/oalioctl.cpp 添加我们定义的IOCTL:


EXTERN_C

BOOL

IOControl(

    DWORD dwIoControlCode,

    PBYTE pInBuf,

    DWORD nInBufSize,

    PBYTE pOutBuf,

    DWORD nOutBufSize,

    PDWORD pBytesReturned

    )

{

    BOOL fRet = FALSE;

 

    //

    // By default the following ioctls are supported for user mode threads.

    // If a new ioctl is being added to this list, make sure the corresponding

    // data associated with that ioctl is marshalled properly to the OAL

    // ioctl implementation. In normal cases, one doesn't need any

    // marshaling as first level user specified buffers are already validated

    // by kernel that:

    // -- the buffers are within the user process space

    // Check out IsValidUsrPtr() function in vmlayout.h for details on kernel

    // validation of user specified buffers. Kernel doesn't validate that the

    // buffers are accessible; it only checks that the buffer start and end

    // addresses are within the user process space.

    //

    switch (dwIoControlCode) {    

        case IOCTL_HAL_GET_CACHE_INFO:

        case IOCTL_HAL_GET_DEVICE_INFO:

        case IOCTL_HAL_GET_DEVICEID:

        case IOCTL_HAL_GET_UUID:

        case IOCTL_HAL_SET_UUID: //Hugo

        case IOCTL_PROCESSOR_INFORMATION:

            // request is to service the ioctl - forward the call to OAL code

            // OAL code will set the last error if there is a failure

            fRet = (*g_pfnExtOALIoctl)(dwIoControlCode, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned);

        break;

        default:

            SetLastError(ERROR_NOT_SUPPORTED);

        break;

    }

 

    return fRet;

}

 这些IOCTL 都是用户可以调用的;

 

3. 到OAL 层的oalioctl.cpp 里添加我们定义的IOCTL :

EXTERN_C

BOOL

IOControl(

    DWORD dwIoControlCode,

    PBYTE pInBuf,

    DWORD nInBufSize,

    PBYTE pOutBuf,

    DWORD nOutBufSize,

    PDWORD pBytesReturned

)

{

    BOOL fRet = FALSE;

 

    //

    // By default the following ioctls are supported for user mode threads.

    // If a new ioctl is being added to this list, make sure the corresponding

    // data associated with that ioctl is marshalled properly to the OAL

    // ioctl implementation. In normal cases, one doesn't need any

    // marshaling as first level user specified buffers are already validated

    // by kernel that:

    // -- the buffers are within the user process space

    // Check out IsValidUsrPtr() function in vmlayout.h for details on kernel

    // validation of user specified buffers. Kernel doesn't validate that the

    // buffers are accessible; it only checks that the buffer start and end

    // addresses are within the user process space.

    //

    switch (dwIoControlCode)

    {

        case IOCTL_HAL_GET_CACHE_INFO:

 

        case IOCTL_HAL_GET_DEVICE_INFO:

 

        case IOCTL_HAL_GET_DEVICEID:

 

        case IOCTL_HAL_GET_UUID:

           

        case IOCTL_HAL_SET_UUID: //Hugo

                   

        case IOCTL_PROCESSOR_INFORMATION:

 

        case IOCTL_SET_RTC_WAKEUP_TIME:

 

        case IOCTL_HAL_GET_SYS_CLOCK_INFO:

 

        case IOCTL_HAL_GET_BTMACADDR:

 

        case IOCTL_HAL_GET_CUSTOMERNUM:

 

        case IOCTL_HAL_GET_FURTURENUM:

 

        case IOCTL_HAL_GET_OEMVALUE:

                   

    case IOCTL_HAL_GET_RTC:

 

        case IOCTL_HAL_GET_DBG_DATA_BUF: 

                   

           case IOCTL_HAL_GET_REG_CLK_EN:

                                      

        case IOCTL_HAL_REBOOT:

            // request is to service the ioctl - forward the call to OAL code

            // OAL code will set the last error if there is a failure

            fRet = (*g_pfnExtOALIoctl)(dwIoControlCode, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned);

            break;

 

        default:

            SetLastError(ERROR_NOT_SUPPORTED);

            break;

    }

 

    return fRet;

}


这些IOCTL 都是驱动可以调用的;

 

4. D:/WINCE600/PLATFORM/COMMON/SRC/INC/oal_ioctl_tab.h 添加 IOCTL 对应的函数:

{ IOCTL_HAL_GET_CACHE_INFO,                 0,  OALIoCtlHalGetCacheInfo     },

{ IOCTL_HAL_GET_DEVICEID,                   0,  OALIoCtlHalGetDeviceId      },

{ IOCTL_HAL_GET_DEVICE_INFO,                0,  OALIoCtlHalGetDeviceInfo    },

{ IOCTL_HAL_GET_UUID,                       0,  OALIoCtlHalGetUUID          },

{ IOCTL_HAL_SET_UUID,                       0,  OALIoCtlHalSetUUID          }, //Hugo

 


5. D:/WINCE600/PLATFORM/COMMON/SRC/INC/oal_ioctl.h 添加函数声明:

BOOL OALIoCtlHalReboot(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);

BOOL OALIoCtlHalGetUUID (UINT32, VOID *, UINT32, VOID *, UINT32, UINT32 *);

BOOL OALIoCtlHalSetUUID (UINT32, VOID *, UINT32, VOID *, UINT32, UINT32 *); //Hugo

BOOL OALIoCtlHalUpdateMode(UINT32, VOID *, UINT32, VOID *, UINT32, UINT32 *);

 


6.  D:/WINCE600/PLATFORM/COMMON/SRC/COMMON/IOCTL/uuid.c 添加函数定义:

//------------------------------------------------------------------------------

//

//  Function:  OALIoCtlHalSetUUID

//

//  Implements the IOCTL_HAL_SET_UUID handler. This function fills in a

//  GUID structure.

//

BOOL OALIoCtlHalSetUUID (

                            UINT32 code,

                            VOID *pInpBuffer,

                            UINT32 inpSize,

                            VOID *pOutBuffer,

                            UINT32 outSize,

                            UINT32 *pOutSize

                        )

{

    BOOL rc = FALSE;

    static const GUID guidPattern = {0x600cc7d0, 0xde3a, 0x4713, {

        0xa5, 0xb0, 0x56, 0xe, 0x6c, 0x36, 0x4e, 0xde

    }};

    GUID *pUuid;   

    UINT32 length;

   

    RETAILMSG(1, (_T("Hugo warn:Set the UUID! /r/n")));

    if (NULL == pInpBuffer || inpSize < sizeof(GUID))

    {

        NKSetLastError(ERROR_INSUFFICIENT_BUFFER);

        OALMSG(OAL_WARN, (L"WARN: OALIoCtlHalSetUUID: Buffer too small/r/n"));

        goto cleanUp;

    }

   

    //Does the BSP UUID exist?

    pUuid = OALArgsQuery(OAL_ARGS_QUERY_UUID);

    if (NULL == pUuid)

    {

        RETAILMSG(1, (_T("Hugo Error:BSP UUID doesn't exit! /r/n")));

        goto cleanUp;

    }

    else

    {

        RETAILMSG(1, (_T("Hugo BSP UUID exit, now change it! /r/n")));

        length = sizeof(GUID);

        memcpy(pUuid, pInpBuffer, length);

    }

   

    //Done

    rc = TRUE;

   

cleanUp:

    return rc;

}

 


OK, 到了这里,rebuild 一下我们的os image 就可以在应用层调用KernelIoControl(..) 设置UUID了,so easy? ^_^!!!

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
ioctl是Linux系统中的一个系统调用,用于设备驱动程序和用户空间程序之间的通信。在GPIO驱动程序中,ioctl可以用于控制GPIO的输入输出状态。使用gpiolib库和ioctl命令可以实现GPIO的输入输出操作。 下面是一个使用ioctl控制GPIO的例子: ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/gpio.h> #define GPIO_NUM 17 int main(int argc, char *argv[]) { int fd; struct gpiochip_info chip_info; struct gpioline_info line_info; struct gpiohandle_request req; int ret; fd = open("/dev/gpiochip0", O_RDWR); if (fd < 0) { perror("open"); exit(1); } ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &chip_info); if (ret < 0) { perror("ioctl"); exit(1); } line_info.line_offset = GPIO_NUM; ret = ioctl(fd, GPIO_GET_LINEINFO_IOCTL, &line_info); if (ret < 0) { perror("ioctl"); exit(1); } req.lines = 1; req.lineoffsets[0] = GPIO_NUM; req.default_values[0] = 0; req.consumer_label = "gpio_test"; ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req); if (ret < 0) { perror("ioctl"); exit(1); } while (1) { req.values[0] = 1; ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &req); if (ret < 0) { perror("ioctl"); exit(1); } sleep(2); req.values[0] = 0; ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &req); if (ret < 0) { perror("ioctl"); exit(1); } sleep(2); } close(fd); return 0; } ``` 该例子中使用了Linux内核提供的GPIO驱动程序,通过打开/dev/gpiochip0设备文件,使用ioctl命令控制GPIO的输入输出状态。具体来说,该例子中使用了GPIO_GET_CHIPINFO_IOCTL和GPIO_GET_LINEINFO_IOCTL命令获取GPIO芯片和GPIO线路的信息,使用GPIO_GET_LINEHANDLE_IOCTL命令获取GPIO线路的句柄,使用GPIOHANDLE_SET_LINE_VALUES_IOCTL命令设置GPIO线路的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值