應用呼叫驅動的ioctl函式

迷霧綠洲發表於2014-10-27

在驅動中增加ioctl的方法在前一篇中介紹了。作為除錯驅動的一個很有用的方式,ioctl提供了應用程式和底層驅動的橋樑。在應用程式中呼叫底層函式ioctl可以作為驅動的開發除錯,後期效能測試的手段。這裡的應用程式其實是定義在rootfs中的,我們將程式編譯成一個程式片段,賦予它執行許可權,之後呼叫它執行我們在驅動中的函式。

這裡函式從新貼出來前面的ioctl的函式

static long at32_wdt_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
int ret = -ENOTTY;
int time;
void __user *argp = (void __user *)arg;
int __user *p = argp;


switch (cmd) {
case WDIOC_GETSUPPORT:
ret = copy_to_user(argp, &at32_wdt_info,
sizeof(at32_wdt_info)) ? -EFAULT : 0;
break;
case WDIOC_GETSTATUS:
ret = put_user(0, p);
break;
case WDIOC_GETBOOTSTATUS:
ret = put_user(wdt->boot_status, p);
break;
case WDIOC_SETOPTIONS:
ret = get_user(time, p);
if (ret)
break;
if (time & WDIOS_DISABLECARD)
at32_wdt_stop();
if (time & WDIOS_ENABLECARD)
at32_wdt_start();
ret = 0;
break;
case WDIOC_KEEPALIVE:
at32_wdt_pat();
ret = 0;
break;
case WDIOC_SETTIMEOUT:
ret = get_user(time, p);
if (ret)
break;
ret = at32_wdt_settimeout(time);
if (ret)
break;
/* Enable new time value */
at32_wdt_start();
/* fall through */
case WDIOC_GETTIMEOUT:
ret = put_user(wdt->timeout, p);
break;
}


return ret;
}

上面定義了幾個命令   

下面就是重頭戲,組織我們的應用程式了

先要建立一個.c檔案 就先建立一個test.c吧

編輯裡面的內容

先解決裡面的依賴檔案的問題

#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include<watchdog.h>

一個關鍵的函式就是main 了

int main(int argc, char const *argv[])
{
int fd;
int c;
char *devname;
int ret = 0;
char *ioctl_cmd;
char *ioctl_arg;
int cmd;
int value;
int i;


if (argc == 1) {
usage(argv[0]);
ret = -1;
goto exit;
}


while ((c = getopt(argc, argv, "d:i:a:")) != -1) {
switch (c) {
case 'd':
devname = strdup(optarg);
break;
case 'i':
ioctl_cmd = strdup(optarg);
break;
case 'a':
ioctl_arg = strdup(optarg);
break;
default:
usage(argv[0]);
ret = -2;
goto exit;
}
}


fd = open(devname, O_RDWR);
if (fd < 0) {
perror("open");
ret = -3;
goto exit;
}


cmd = lookup_cmd(ioctl_cmd);
if (cmd == 0) {
fprintf(stderr, "invalid ioctl cmd\n");
ret = -4;
goto exit;
}
switch (cmd) {
case WDIOC_SUPPORT:
value = strtol(ioctl_arg, NULL, 0);
if ((ret = ioctl(fd, WDIOC_SUPPORT, &value)) < 0) {
fprintf(stderr, "ioctl for WDIOC_SUPPORT failed with value: %d\n", value);
goto exit;
}
break;
case WDIOC_GETSTATUS:
if ((ret = ioctl(fd, WDIOC_GETSTATUS, &value)) < 0) {
fprintf(stderr, "ioctl for I2C_RDWR failed with value: %d\n", value);
goto exit;
}
break;
default:
fprintf(stderr, "invalid ioctl cmd !\n");
ret = -5;
break;
}


exit:
if (fd)
close(fd);
return ret;
}

上面就是呼叫的關鍵步驟 ,可以看出來裡面其實關鍵就是getopt(argc, argv, "d:i:a:")獲取終端輸入的引數

ioctl(fd, WDIOC_GETSTATUS, &value)將引數應用 去呼叫驅動底層的函式


這個ioctl是一個C 庫的介面函式,getopt是全域性的函式  會用就行了

這樣就可以呼叫了

相關文章