/***********************************************************************************
*
* Makefile,open,read,write,lseek,poll,ioctl,fasync
*
* 声明:
* 1. 本系列文档是在vim下编辑,请尽量是用vim来阅读,在其它编辑器下可能会
* 不对齐,从而影响阅读.
*
**********************************************************************************/
\\\\\\\--*目录*--//////////////
| 一. Makefile大致写法:
| 二. 获取进程task_struct的方法:
| 三. open 大致写法:
| 四. read 大致写法:
| 五. write 大致写法:
| 六. lseek 大致写法:
| 七. poll 大致写法:
| 八. ioctl 大致写法:
| 九. close 大致写法:
| 十. fasync 大致写法:
| 十一. 等待队列API:
| 十二. 驱动wait_queue poll fasync:
| 十三. 应用wait_queue poll fasync:
\\\\\\\\\///////////////////
一. Makefile大致写法:
...
# 定义一个CC变量,赋值为arm-linux-
CC = arm-linux-
# .c文件依赖的.h文件存放的目录,这里是:当前目录下include文件夹
INCLUDE_DIRS = include
# 如果变量objs在此之前未声明定义,那么就声明定义,并赋值objs为hello.o
# 如果变量objs在此之前已声明定义,那么把hello.o放在objs字符串后面
objs += hello.o
# 1. hello : 下面命令要生成的目标,当然也有可能是伪指令;
# 2. $(objs) : 依赖文件,只有依赖文件都存在的情况下才会执行下面的指令;
# 3. $(CC)gcc $< -o $@ : 编译依赖文件产生目标文件;
# 1. $(CC) : 取CC变量里的值;
# 2. $< : 依赖文件($(objs))
# 3. $@ : 目标文件(hello)
hello : $(objs)
$(CC)gcc $< -o $@
# 1. 生成的目标文件简写,将当前文件下所有的.c编译成对应的.o文件;
# 2. -I$(INCLUDE_DIRS) : .c编译时需要的头文件所在的目录
%.o : %.c
$(CC)gcc -c $< -o $@ -I$(INCLUDE_DIRS)
# 伪命令声明,这样即使存在clean文件,也会把clean当命令使用
.PHONY:clean
clean:
rm *.o hello
...
二. 获取进程task_struct的方法:
...
int ret;
struct thread_info *info;
struct task_struct *task;
/**
* 获取当前进程的进程描述符(PCB)算法,主要是因为thread_info里有task_struct指针,
* 而thread_info放在了内核线程栈的起始地方,而内核线程栈是8k对齐,
* 所以thread_finfo的首地址是: ((unsigned int)&ret & ~(0x2000 - 1))
*/
info = (void *)((unsigned int)&ret & ~(0x2000 - 1));
task = info->task;
printk('pid = %d, [%s]n', task->pid, task->comm); /* task->comm 运行的程序名 */
// current 当前进程的PCB指针,系统自带提供的全局变量
printk('pid = %d, [%s]n', current->pid, current->comm);
...
三. open 大致写法:
1. int (*open) (struct inode *, struct file *);
2. 代码模型:
static int test_open(struct inode *inode, struct file *file)
{
/**
* 一般open函数里面都要把私有数据绑定到file->private_data上
*/
test_t *p;
p = container_of(file->f_op, test_t, fops);
file->private_data = p;
//声明当前设备不支持llseek方法调整读写位置
//nonseekable_open(inode, file);
return 0;
}
四. read 大致写法:
1. ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
2. 代码模型:
static ssize_t test_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
{
int ret;
test_t *p = file->private_data;
/**
* 检查可读数据是否足够
*/
if(count > BUF_SIZE - *pos)
count = BUF_SIZE - *pos;
ret = copy_to_user(buf, p->buf + *pos, count);
if(ret)
return -EFAULT;
*pos += count;
return count; //返回读到的数据个数
}
五. write 大致写法:
1. ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
2. 代码模型:
static ssize_t test_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
{
test_t *p = file->private_data;
if(p->is_empty)
{
/* 进入深度睡眠其中方法中的一种 */
current->state = TASK_UNINTERRUPTIBLE;
schedule();
}
return count;
}
六. lseek 大致写法:
1. loff_t (*llseek) (struct file *, loff_t, int);
2. 2.6版本内核不实现该方法的话,使用内核默认的llseek函数,当前版本必须实现该方法;
3. 代码模型:
static loff_t test_llseek(struct file *file, loff_t offset, int whence)
{
loff_t pos = file->f_pos;
switch(whence)
{
case SEEK_SET:
pos = offset;
break;
case SEEK_CUR:
pos += offset;
break;
case SEEK_END:
pos = BUF_SIZE + offset;
break;
default:
return -EINVAL; //参数非法
}
file->f_pos = pos;
//返回lseek之后的文件读写位置(相对文件开始处)
return pos;
}
七. poll 大致写法:
1. poll,epoll,select系统调用的后端,都用作查询对一个或多个文件描述符的读写是否阻塞
2. unsigned int (*poll) (struct file *, struct poll_table_struct *);
3. 代码模型:
static unsigned int test_poll(struct file *file, struct poll_table_struct *table)
{
unsigned int poll = 0;
test_t *p = file->private_data;
/*printk('In test_poll.n');*/
上一篇:Samsung_tiny4412(驱动笔记06)----list_head,proc file system,GPIO,ioremap
下一篇:Samsung_tiny4412(驱动笔记04)----volatile,container_of,file_operations,file,inode
推荐阅读最新更新时间:2026-03-22 11:00
- RDR-142 - 35W电源
- i.MX RT1060 Evaluation Kit
- 使用 Embedded Planet 的 5CEFA9U27 的参考设计
- DC1369A-D、LTC2258-14 演示板、14 位 65 Msps ADC、LVDS 输出、5-170MHz
- LT3990EMSE-5 12V 降压转换器的典型应用
- 使用 Analog Devices 的 LTC1148 的参考设计
- LT1377IS8 具有直接反馈的正负转换器的典型应用
- 使用 NXP Semiconductors 的 TL431AI 的参考设计
- LT8304IS8E 18V 至 80Vin、5Vout 隔离反激式转换器的典型应用电路
- LT3512EMS 演示板,单片式高压隔离反激式转换器 36V VIN 75V,VOUT = 5V @ 500mA



Linux内核驱动笔记
三星2410开发板ALLEGRO BRD原文件
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号