linux用户程序是怎么和驱动程序联系起来ioctl/write
2014-12-25 14:52
369 查看
进步源于不满足。
1, Talking to Device Files (writes and IOCTLs)
我们在使用ioctl和write函数时,知道向里面读数据,写数据,写入控制命令,write函数合ioctl是怎样实现的的呢,用户程序和驱动程序是怎样联系起来得,?这个其实都在你写的驱动程序里面,
驱动程序里面的定义
struct file_operations Fops = { .read = device_read, .write = device_write, .ioctl = device_ioctl, .open = device_open, .release = device_release, /* a.k.a. close */ };
当我们调用write时其实是调用了自己编写的驱动device_write函数
/* * This function is called when somebody tries to * write into our device file. */ static ssize_t device_write(struct file *file, const char __user * buffer, size_t length, loff_t * offset) { int i; #ifdef DEBUG printk(KERN_INFO "device_write(%p,%s,%d)", file, buffer, length); #endif for (i = 0; i < length && i < BUF_LEN; i++) get_user(Message[i], buffer + i); Message_Ptr = Message; /* * Again, return the number of input characters used */ return i; }
同理,其它函数也是一样,ioctl函数
int device_ioctl(struct inode *inode, /* see include/linux/fs.h */ struct file *file, /* ditto */ unsigned int ioctl_num, /* number and param for ioctl */ unsigned long ioctl_param) { int i; char *temp; char ch; /* * Switch according to the ioctl called */ switch (ioctl_num) { case IOCTL_SET_MSG: /* * Receive a pointer to a message (in user space) and set that * to be the device's message. Get the parameter given to * ioctl by the process. */ temp = (char *)ioctl_param; /* * Find the length of the message */ get_user(ch, temp); for (i = 0; ch && i < BUF_LEN; i++, temp++) get_user(ch, temp); device_write(file, (char *)ioctl_param, i, 0); break; case IOCTL_GET_MSG: /* * Give the current message to the calling process - * the parameter we got is a pointer, fill it. */ i = device_read(file, (char *)ioctl_param, 99, 0); /* * Put a zero at the end of the buffer, so it will be * properly terminated */ put_user('\0', (char *)ioctl_param + i); break; case IOCTL_GET_NTH_BYTE: /* * This ioctl is both input (ioctl_param) and * output (the return value of this function) */ return Message[ioctl_param]; break; } return SUCCESS; }
ioctl函数根据不同的cmd 进行switch{case};的选择处理
下面用户程序为对ioctl函数不同命令的封装和测试
/* * ioctl.c - the process to use ioctl's to control the kernel module * * Until now we could have used cat for input and output. But now * we need to do ioctl's, which require writing our own process. */ /* * device specifics, such as ioctl numbers and the * major device file. */ #include "chardev.h" #include <stdio.h> #include <stdlib.h> #include <fcntl.h> /* open */ #include <unistd.h> /* exit */ #include <sys/ioctl.h> /* ioctl */ /* * Functions for the ioctl calls */ ioctl_set_msg(int file_desc, char *message) { int ret_val; ret_val = ioctl(file_desc, IOCTL_SET_MSG, message); if (ret_val < 0) { printf("ioctl_set_msg failed:%d\n", ret_val); exit(-1); } } ioctl_get_msg(int file_desc) { int ret_val; char message[100]; /* * Warning - this is dangerous because we don't tell * the kernel how far it's allowed to write, so it * might overflow the buffer. In a real production * program, we would have used two ioctls - one to tell * the kernel the buffer length and another to give * it the buffer to fill */ ret_val = ioctl(file_desc, IOCTL_GET_MSG, message); if (ret_val < 0) { printf("ioctl_get_msg failed:%d\n", ret_val); exit(-1); } printf("get_msg message:%s\n", message); } ioctl_get_nth_byte(int file_desc) { int i; char c; printf("get_nth_byte message:"); i = 0; do { c = ioctl(file_desc, IOCTL_GET_NTH_BYTE, i++); if (c < 0) { printf ("ioctl_get_nth_byte failed at the %d'th byte:\n", i); exit(-1); } putchar(c); } while (c != 0); putchar('\n'); } /* * Main - Call the ioctl functions */
/* test the ioctl function */
main() { int file_desc, ret_val; char *msg = "Message passed by ioctl\n"; file_desc = open(DEVICE_FILE_NAME, 0); if (file_desc < 0) { printf("Can't open device file: %s\n", DEVICE_FILE_NAME); exit(-1); } ioctl_get_nth_byte(file_desc); ioctl_get_msg(file_desc); ioctl_set_msg(file_desc, msg); close(file_desc); }
相关文章推荐
- linux命令行下 怎么查看 服务所对应的程序
- 怎么把PID算法的汇编程序与温度控制系统的程序结合起来??
- linux下怎么编译c程序
- 在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序
- 在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序
- 转:linux设备驱动程序设计中的程序样例运行的一点说明(编译Linux内核)
- Android系统内置C可执行程序测试Linux内核驱动程序
- Linux设备驱动程序学习(4) -高级字符驱动程序操作[(1)ioctl and llseek]
- 小白学Linux之编写用户层程序
- 【Linux设备驱动程序(第三版)】----ioctl
- 在Linux中,开机自动运行普通用户的脚本程序
- 驱动程序与用户程序之间的通信(原创)
- linux 驱动程序___高级字符驱动程序___ioctl 方法解读
- Linux超级用户root口令忘记怎么办?
- Linux 2.6.23将使用用户空间驱动程序API
- 在Linux中开机自动运行普通用户脚本程序
- linux命令行下 怎么查看 服务所对应的程序
- linux驱动程序与应用程序函数的联系
- probe()函数是什么时候被调用,设备和驱动是怎么联系起来的