<2012 11 3 > linux设备驱动程序开发初探(1) 目次 概念 框架 最小驱动程序

<linux设备驱动程序开发初探> based on WeiDongshan

------------------Content--------------------
一、字符设备驱动程序
1、概念介绍
@1 应用程序与内核、驱动的关系。
@2 框架

二、First驱动程序:点亮LED
@1 源码分析
@2 驱动编译
@3 驱动测试与使用

三、Second驱动程序:查询方式获取按键
@1 源码分析
@2 驱动测试与使用

四、Third驱动程序:中断方式获取按键
@1 linux异常体系架构-->linux中断体系结构
@2 源码分析
@3 驱动测试与使用

五、按键驱动深化:poll或者select操作
@1 源码分析:poll机制分析
@2 测试

六、按键驱动深化:同步、互斥、阻塞
@1 源码分析:机制分析
@2 测试

七、按键驱动深化:异步通信机制
@1 源码分析:机制分析
@2 测试
------------------------------------------
一、概念
Bootloader ==> Kernel ==> FileSysterm ==>APP
APP:读写文件、操控硬件(如点亮LEDs、获取按键值)等

Linux驱动程序:对底层硬件操作的一个抽象封装,并且被纳入内核的统一管理体系。

# 驱动程序框架:

1、实例化一个结构体为Driver_NameA_fops,表示驱动支持的哪些操作,该结构体原型在源码 include\linux\fs.h中定义。
struct file_operations{
... ...
}
2、在内核中注册的函数(内核根据APP打开的文件的 设备类型和主设备号锁定驱动,chrdev表示“char device 字符设备”,是内核管理的一个所有字符型驱动的数组)
register_chrdev(major, "Driver_NameA",&Driver_NameA_fops)
3、驱动的入口函数(被内核引用)
int Driver_NameA_init( )
4、宏module_init将入口函数包装成内核统一的接口
module_init(Driver_NameA_init)

# 最简单的一个驱动程序范例
编辑一个first_drv.c程序:

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/fs.h>

#include <linux/init.h>

#include <linux/delay.h>

#include <asm/uaccess.h>

#include <asm/irq.h>

#include <asm/io.h>

#include <asm/arch/regs-gpio.h>

#include <asm/hardware.h>





static int first_drv_open(struct inode *inode, struct file *file)

{

printk("open_Andrew~\n");

return 0;

}



static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)

{

printk("write_Andrew~\n");

return 0;

}



static struct file_operations first_drv_fops = {

.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

.open = first_drv_open, 

.write    =    first_drv_write,    

};



static int first_drv_init(void)

{

register_chrdev(111, "first_drv", &first_drv_fops); // 注册, 告诉内核

return 0;

}



static void first_drv_exit(void)

{

unregister_chrdev(111, "first_drv"); // 卸载

}



module_init(first_drv_init);

module_exit(first_drv_exit);



 



MODULE_LICENSE("GPL");

编写一个makefile文件来编译这个C程序到.ko模块

KERN_DIR = /home/kernel_project/linux-2.6.12



all:

make -C $(KERN_DIR) M=`pwd` modules



clean:

make -C $(KERN_DIR) M=`pwd` modules clean

rm -rf modules.order



obj-m    += first_drv.o

第一行表示需要加载到的内核(版本最好要一致)的源程序目录,需要注意的是,这个源程序目录中的kernel需要先被编译一下,生成必须的目标文件。

在驱动源文件first_drv.c的目录下执行

make clean

make

便生成了first_drv.ko模块
执行加载模块,并查看已加载的模块

insmod ./first_drv.ko

cat /proc/devices | grep first_drv

可以看到模块以及被加载。
然后需要在 /dev/目录下手动创建一个节点来进行应用程序的操作

mknode /dev/xyz c 111 0

下面可以写一个简单的APP来验证这个驱动模块是否可用
编辑一个firstdrvtest.c源文件

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>





int main(int argc, char **argv)

{

int fd;

int val = 1;

fd = open("/dev/xyz", O_RDWR);

if (fd < 0)

{

printf("can't open!\n");

}

write(fd, &val, 4);

return 0;

}


编译一下,并执行

gcc -o firstdrvtest firstdrvtest.c

./firstdrvtest

便能够看到打印信息:表示模块和节点正常运行。

open_Andrew~

write_Andrew~

---------------------------------------------------------

你可能感兴趣的:(linux)