ARM驱动开发入门

驱动分类

1   常规分类

1.1       字符设备:以字节为最小访问单位的设备,通常支持open,close,read,write系统调用。如串口、LED、按键

1.2       块设备:以块为最小访问单位的设备(块一般为512字节或512字节的倍数),linux中允许块设备传送任意字节数。如硬盘、flash、SD卡。

1.3       网络接口:负责发送和接收数据报文,可以是硬件设备,如网卡,也可以是纯软件设备,如回环接口(lo)

2   总线分类法

               1.1             USB设备

               1.2             PCI设备

               1.3             平台总线设备

学习方法

1   构建驱动模型

2   添加硬件操作

3   驱动测试

硬件访问

1   地址映射

1.1 静态映射

void *ioremap(physaddr,size)

physaddr:待映射的物理地址

size:映射的区域长度

返回值:映射后的虚拟地址

1.2 动态映射

用户事先指定映射关系,在内核启动时自动将物理地址映射为虚拟地址。

struct map_desc

{

     unsigned long virtual;/映射后的虚拟地址

     unsigned long pfn;/物理地址所在的页帧号

     unsigned long length;/映射长度

     unsigned int type;/映射的设备类型

}

2   寄存器读写

unsigned ioread8(void *addr)

unsigned ioread16(void *addr)

unsigned readb(address)

unsigned readw(address)

unsigned readl(address)

 

void iowrite8(u8 value,void *addr)

void iowrite16(u16 value,void *addr)

void iowrite32(u32 value,void *addr)

void writeb(unsigned value, address)

void writew(unsigned value, address)

void writel(unsigned value, address)

驱动的运用

1   编译安装驱动

1.1 创建Makefile

obj-m := memdev.o

KDIR := /home/…/linux-tq2440

all:

make–C $( KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm

1.2 拷贝驱动(内核模块)到/…/rootfs

1.3 安装驱动程序

insmod  memdev.ko

1.4 查看 lsmod

2   字符设备文件

2.1       查看主设备号

cat /proc/devices

主设备号   设备名

2.2       创建设备文件

mknod /dev/文件名 c 设备号 次设备号(0~255)

3   应用程序

3.1 打开字符设备文件

fd = open(“/dev/memdev0”,O_RDWR);

3.2 操作字符设备文件

write(fd,&buf,sizeof(int));

read(fd,&buf,sizeof(int));

3.3 关闭字符设备文件

close(fd);

3.4 编译(静态编译)

arm-linux-gcc –static 文件名.c –O文件名

字符设备驱动模型

1    设备描述结构cdev

1.1 结构定义

struct cdev

{

struct kobject kobl;

struct module *owner;

const struct file operations *ops ;//设备操作集

struct lis thead list;

dev_t dev;//设备号。

unsigned int count;设备数

}

1.2 设备号类型dev_t

1.2.1 dev_t介绍:实质为32位的unsigned int,高十二位为主设备号,低二十位为次设备号。

1.2.2 操作设备号:

dev_t dev=MKDEV(主设备号,次设备号)

主设备号=MAJOR(dev_t dev)

次设备号=MINOR(dev_t dev)

1.2.3 申请设备号:

静态申请:intregister_chrdev_region(dev_t first, unsigned int count, char *name);

first: 待分配的起始设备编号,通常为0;

count: 连续设备编号的总数

name:设备名(cat /proc/devices

动态申请:intalloc_chrdev_region(dev_t *dev,unsigned int -firstminor,unsigned int -count,char*name)

dev:得到的设备号保存位置

-firstminor: 待分配的起始设备编号,通常为0;

-count: 连续设备编号的总数

name: 设备名(cat /proc/devices

1.2.4 注销设备号:unregister_chardev_region

1.3 操作集struct file operations

1.3.1 structfile operations介绍:函数指针的集合,定义能在设备上进行的操作。对于不支持的操作设置为NULL

1.3.2 例:struct file operations dev_fops =

{

.llseek  = NULL;

.read= dev_read,

.write= dev_write,

.ioctl= dev_inctl,

.open= dev_open,

.release= dev_release,

};

2    驱动初始化

2.1 分配设备描述结构

    静态分配:structcdev mdev;

动态分配:structcdev *pdev = cdev_alloc();

2.2 初始化设备描述结构

cdev_init(struct cdev*cdev,const struct file_operations *fops)

*cdev:待初始化的cdev结构/*fops:设备对应的操作函数集

2.3 注册设备描述结构

    cdev_add(struct cdev *p,dev_t dev,unsignedcount)

p:待添加到内核的字符设备结构

dev:设备号

count:该类设备的设备个数

2.4 硬件初始化

3         设备操作(设备方法)

3.1 int  (*open) (struct inode *,struct file *)  打开设备,响应open系统

3.1.1 structfile:

3.1.1.1   linux系统中,每个打开的文件,都会关联一个structfile,由内核在文件打开时创建,文件关闭后释放

3.1.1.2   重要成员

loff_t f_pos   //文件读写指针

struct file_operation*f_op  //文件对应的操作

3.1.2 structinode

3.1.2.1   每个存在于文件系统的文件都会关联一个inode结构,记录文件物理信息。

3.1.2.2   重要成员:

dev_t i_rdev   //设备号

3.2 int  (*release) (struct inode *,struct file*)  关闭设备,响应close系统

3.3 loff_t  (*llseek) (struct file *,loff_t,int)  重定位读写指针,响应lseek系统调用

3.4 ssize_t(*read) (struct file *,char _user *,size_t,loff_t *)  从设备读取数据,响应read系统调用

3.4.1 参数分析:

filp:与字符设备文件关联的file结构指针,由内核创建

buff:从设备读到的数据需要保存的位置,由read系统调用提供

count:请求传输的数据量,由read系统调用提供

offp:文件读写位置,由内核从file结构中取出传递进来

3.4.2 从设备中读取数据(硬件访问类操作)

3.4.3 将读到的数据返回给应用程序

3.5 ssize_t(*write) (struct file *,const char _user *,size_t,loff_t *)  向设备写入数据,响应write系统调用

3.5.1 参数分析:

filp:与字符设备文件关联的file结构指针,由内核创建

buff:从设备读到的数据需要保存的位置,由read系统调用提供

count:请求传输的数据量,由read系统调用提供

offp:文件读写位置,由内核从file结构中取出传递进来

3.5.2 从应用程序提供的地址中取出数据

3.5.3 将数据写入设备(硬件访问类操作)

4         驱动注销

4.1       用cdev_del函数卸载驱动程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值