一、Linux驱动程序
1.Makefile
1 TARGET = app 2 3 OBJS = main.o fun.o 4 5 %.o : %.c 6 gcc -c -o$@ $^ 7 8 $(TARGET) : $(OBJS) 9 gcc -o$@ $^ 10 11 clean: 12 rm $(OBJS) $(TARGET) 13
2.为何如此麻烦的编译?
编译步骤
1. vi drivers/char/Kconfig
2.make menuconfig
3.vi drivers/char/Makefile
4.编译
make modules
生成一个 first_driver.ko
5.copy drivers/char/first driver.ko ~/nfs/rootfs//在内核中找到这个.ko文件
6.在minicom中
insmod first_driver.ko//执行
nmmod first_driver //删除
Makefile好管理
简单方法
mkdir my_driver
2.代码
所有调用register_chrdev之前必须申明内联函数(inline)
内联/函数放在头文件里
构造和析构两个过程的顺序是逆序的
按一个字节 两个 四个字节读
3.字符设备驱动
int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops); |
字符设备驱动程序注册函数 |
unsigned int major:主设备号 const char *name:为你的驱动程序起一个名字 struct file_operations *fops:这是一个指向file_operations结构 体变量的指针 open 函数用于打开设备文件 release 函数用于释放(关闭)设备文件,与应用程序中的 close 函数对应 read 函数用于读取设备文件 write 函数用于向设备文件写入(发送)数据 poll 是个轮询函数,用于查询设备是否可以进行非阻塞的读写 owner 拥有该结构体的模块的指针,一般设置为 THIS_MODULE |
返回值: |
4.混杂设备驱动
int misc_register(struct miscdevice * misc); 注册一个混杂设备 该函数需要一个struct miscdevice结构体变量的地址
minor:子设备号,由于主设备号都是10,子设备号必须指定而且不 能冲突, linux/miscdevice.h中定义了几个子设备号,如果需要动态 获取,就用MISC_DYNAMIC_MINOR
name:将来在/dev下的设备名 3
fops:指向文件操作结构体变量的指针
返回值:
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev); 注册中断使用的函数 1. irq:中断号。结合mini2440开发板, 按键1所对应的就是IRQ_EINT8。
2. handler:中断处理函数指针,
内核中的定义如下:typedef irqreturn_t (*irq_handler_t)(int, void *); irq_handler_t是一个函数指针,这个函数 指针必须指向返回值是irqreturn_t,函数参数必须是int和void *的那 种函数。
3. flags:该参数用于表明中断产生的条件以及系统在处理时的行为,我们使用 IRQF_TRIGGER_FALLING和IRQF_DISABLED,表示电平的下降沿方 式和在处理中断时不响应其他中断;
4. name:为你的中断起个名字,设置以后可以在/proc/interrupts 文件 中看到对应的中断名字;
5. 给中断服务函数传参,就是key_irq_handle的pData
此外使用linux中断还有两个函数:
1. void disable_irq(unsigned int irq);禁止某个中断发生,如果这个中断正在执行,那么就等待中断执行结束后再禁止它
2. void free_irq(unsigned int irq, void *dev_id);和request_irq相反,注销已经注册过的中断