linux驱动
来源:互联网 发布:林姗姗淘宝店 编辑:程序博客网 时间:2024/04/29 22:49
1.使用字符设备驱动程序
1) 编译/安装驱动
2)创建设备文件
3)访问设备
1) 在linux系统中,驱动程序通常采用内核模块的程序结构进行编码。
应用程序: mem_write.c
arm-linux-readelf -d mem_write.c 检查动态链接库
一般采用静态编译
arm-linux-gcc -static mem_write.c -o mem_write
应用程序: mem_read.c
2.字符设备文件
应用程序{文件名} ---> 字符设备文件 --->(主设备号) ----> 设备驱动程序
通过字符设备文件,应用程序可以使用相应的字符设备驱动程序来控制字符设备。创建字符设备
文件的方法一般有两种:
1.使用mknod命令
mknod /dev/文件名 c 主设备号 次设备号
cat /proc/devices
第一列 第二列
数字(主设备号) 设备名字
2.使用函数在驱动程序中创建
1) 编译/安装驱动
2)创建设备文件
3)访问设备
1) 在linux系统中,驱动程序通常采用内核模块的程序结构进行编码。
因此,编译/安装一个驱动程序,其实质就是编译/安装一个内核模块。
驱动名 memdev.c #include <linux/module.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/cdev.h>#include <asm/uaccess.h>int dev1_registers[5];int dev2_registers[5];struct cdev cdev; dev_t devno;/*文件打开函数*/int mem_open(struct inode *inode, struct file *filp){ /*获取次设备号*/ int num = MINOR(inode->i_rdev); if (num==0) filp->private_data = dev1_registers; else if(num == 1) filp->private_data = dev2_registers; else return -ENODEV; //无效的次设备号 return 0; }/*文件释放函数*/int mem_release(struct inode *inode, struct file *filp){ return 0;}/*读函数*/static ssize_t mem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos){ unsigned long p = *ppos; unsigned int count = size; int ret = 0; int *register_addr = filp->private_data; /*获取设备的寄存器基地址*/ /*判断读位置是否有效*/ if (p >= 5*sizeof(int)) return 0; if (count > 5*sizeof(int) - p) count = 5*sizeof(int) - p; /*读数据到用户空间*/ if (copy_to_user(buf, register_addr+p, count)) { ret = -EFAULT; } else { *ppos += count; ret = count; } return ret;}/*写函数*/static ssize_t mem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos){ unsigned long p = *ppos; unsigned int count = size; int ret = 0; int *register_addr = filp->private_data; /*获取设备的寄存器地址*/ /*分析和获取有效的写长度*/ if (p >= 5*sizeof(int)) return 0; if (count > 5*sizeof(int) - p) count = 5*sizeof(int) - p; /*从用户空间写入数据*/ if (copy_from_user(register_addr + p, buf, count)) ret = -EFAULT; else { *ppos += count; ret = count; } return ret;}/* seek文件定位函数 */static loff_t mem_llseek(struct file *filp, loff_t offset, int whence){ loff_t newpos; switch(whence) { case SEEK_SET: newpos = offset; break; case SEEK_CUR: newpos = filp->f_pos + offset; break; case SEEK_END: newpos = 5*sizeof(int)-1 + offset; break; default: return -EINVAL; } if ((newpos<0) || (newpos>5*sizeof(int))) return -EINVAL; filp->f_pos = newpos; return newpos;}/*文件操作结构体*/static const struct file_operations mem_fops ={ .llseek = mem_llseek, .read = mem_read, .write = mem_write, .open = mem_open, .release = mem_release,};/*设备驱动模块加载函数*/static int memdev_init(void){ /*初始化cdev结构*/ cdev_init(&cdev, &mem_fops); /* 注册字符设备 */ alloc_chrdev_region(&devno, 0, 2, "memdev"); cdev_add(&cdev, devno, 2);}/*模块卸载函数*/static void memdev_exit(void){ cdev_del(&cdev); /*注销设备*/ unregister_chrdev_region(devno, 2); /*释放设备号*/}MODULE_LICENSE("GPL");module_init(memdev_init);module_exit(memdev_exit);
Makefile文件:KDIR := /home/S5-driver/lesson7/linux-tiny6410/all:make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=armclean:rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order
应用程序: mem_write.c
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int main(){int fd = 0;int src = 2013;/*打开设备文件*/fd = open("/dev/memdev0",O_RDWR);/*写入数据*/write(fd, &src, sizeof(int));/*关闭设备*/close(fd);return 0;}
arm-linux-readelf -d mem_write.c 检查动态链接库
一般采用静态编译
arm-linux-gcc -static mem_write.c -o mem_write
应用程序: mem_read.c
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int main(){int fd = 0;int dst = 0;/*打开设备文件*/fd = open("/dev/memdev0",O_RDWR);/*写入数据*/read(fd, &dst, sizeof(int));printf("dst is %d\n",dst);/*关闭设备*/close(fd);return 0;}
2.字符设备文件
应用程序{文件名} ---> 字符设备文件 --->(主设备号) ----> 设备驱动程序
通过字符设备文件,应用程序可以使用相应的字符设备驱动程序来控制字符设备。创建字符设备
文件的方法一般有两种:
1.使用mknod命令
mknod /dev/文件名 c 主设备号 次设备号
cat /proc/devices
第一列 第二列
数字(主设备号) 设备名字
2.使用函数在驱动程序中创建
0 0
- Linux 驱动--ADC驱动
- Linux 驱动--ADC驱动 .
- Linux驱动---按键驱动
- Linux 驱动--ADC驱动
- 《Linux驱动》驱动注册
- linux驱动--LED驱动
- Linux驱动-LCD驱动
- linux驱动---字符驱动
- linux 驱动
- linux 驱动
- Linux驱动
- linux驱动
- linux驱动
- Linux 驱动
- linux驱动
- LINUX驱动
- linux驱动
- linux驱动
- C/C++拷贝文件的方法
- LeetCode 122 Best Time to Buy and Sell Stock II
- Module Thinking之多样性与创新
- Android中shape中的属性大全
- 20160411
- linux驱动
- 作为一个新人,怎样学习嵌入式Linux?(韦东山)
- 一些有用的网站
- 编译原理-0-编译过程概述
- C++实验3-1-个人所得税计算器
- 作业:C++作业3
- RecyclerView添加Header和Footer的基本原理
- 冒泡排序(Bubble Sort)
- 初学java