个人作品网站策划书网站建设语言环境

当前位置: 首页 > news >正文

个人作品网站策划书,网站建设语言环境,温州seo关键词优化,中小企业网站优化目录 一、驱动程序编写流程 二、代码编写 2.1 驱动程序hello_drv.c 2.2 测试程序 2.3 编写驱动程序的Makefile 三、上机实验 3.1 NFS 挂载 3.2 测试示例 一、驱动程序编写流程 构造file_operations结构体 在里面填充open/read/write/ioctl成员 注册file_operations结… 目录 一、驱动程序编写流程 二、代码编写 2.1 驱动程序hello_drv.c 2.2 测试程序 2.3 编写驱动程序的Makefile 三、上机实验 3.1 NFS 挂载 3.2 测试示例 一、驱动程序编写流程 构造file_operations结构体 在里面填充open/read/write/ioctl成员 注册file_operations结构体 int major register_chrdev(0, name, fops); 入口函数调用regiister_chrdev 出口函数调用unregiister_chrdev 辅助信息 class_create/class_destroy   device_create/device_destroy
总结应用程序调用open/read/write/ioctl驱动程序就给你提供对应的open/read/write/ioctl只不过驱动程序的这些函数为了便于管理故把函数放在file_operations结构体里面通过 register_chrdev函数把结构体告诉内核并注册字符设备驱动程序。驱动程序里面有个入口函数相当于main函数是装载驱动程序时调用的函数在入口函数中注册把结构体放到chrdevs数组里面来出口函数中反注册就是把结构体拿掉在卸载驱动程序时调用的函数。   二、代码编写 2.1 驱动程序hello_drv.c 参考 driver/char 中的程序包含头文件写框架传输数据 驱动中实现 open, read, write, release APP 调用这些函数时都打印内核信息APP 调用 write 函数时传入的数据保存在驱动中   APP 调用 read 函数时把驱动中保存的数据返回给 APP   需要注意的是驱动程序和应用程序之间数据传递要使用copy_from_user(hello_buf, buf, len)和copy_to_user(buf, hello_buf, len) class_create和device_create这两个函数为我们创建了设备节点、主次设备号等辅助信息就不用手动创建设备节点了 mknod /dev/xyz c 245 0 class_create(THIS_MODULE, hello_class)创建类为这个模块创建类类名叫hello_class device_create(hello_class, NULL, MKDEV(major, 0), NULL, hello)在类下面创建设备信息在hello_class下创建设备没有父亲NULL主次设备号无私有数据NULL格式hello根据这些信息系统会为我们创建设备节点设备节点名字是/dev/hello和上面的类名无关 device_destroy(hello_class, MKDEV(major, 0))销毁hello_class类下面的这个设备由主次设备号确定 class_destroy(hello_class)销毁hello_class类
#include asm/cacheflush.h #include linux/mm.h #include linux/module.h #include linux/miscdevice.h #include linux/slab.h #include linux/vmalloc.h #include linux/mman.h #include linux/random.h #include linux/init.h #include linux/raw.h #include linux/tty.h #include linux/capability.h #include linux/ptrace.h #include linux/device.h #include linux/highmem.h #include linux/backing-dev.h #include linux/shmem_fs.h #include linux/splice.h #include linux/pfn.h #include linux/export.h #include linux/io.h #include linux/uio.h #include linux/uaccess.hstatic struct class *hello_class; static int major; static unsigned char hello_buf[100];static int hello_open (struct inode *node, struct file *filp) {printk(%s %s %d\n, FILE, FUNCTION, LINE);return 0; }static ssize_t hello_read (struct file *filp, char __user *buf, size_t size, loff_t *offset) {unsigned long len size 100 ? 100 : size;printk(%s %s %d\n, FILE, FUNCTION, LINE);copy_to_user(buf, hello_buf, len);return len; }static ssize_t hello_write(struct file *filp, const char __user *buf, size_t size, loff_t *offset) {unsigned long len size 100 ? 100 : size;printk(%s %s %d\n, FILE, FUNCTION, LINE);copy_from_user(hello_buf, buf, len);return len; }static int hello_release (struct inode *node, struct file filp) {printk(%s %s %d\n, FILE, FUNCTION, LINE);return 0; }/ 1. create file_operations / static const struct file_operations hello_drv {.owner THIS_MODULE,.read hello_read,.write hello_write,.open hello_open,.release hello_release, };/ 2. register_chrdev // 3. entry function / static int hello_init(void) {major register_chrdev(0, 100ask_hello, hello_drv);hello_class class_create(THIS_MODULE, hello_class);if (IS_ERR(hello_class)) {printk(failed to allocate class\n);return PTR_ERR(hello_class);}device_create(hello_class, NULL, MKDEV(major, 0), NULL, hello); / /dev/hello /return 0; }/ 4. exit function / static void hello_exit(void) { device_destroy(hello_class, MKDEV(major, 0));class_destroy(hello_class);unregister_chrdev(major, 100ask_hello); }module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE(GPL);2.2 测试程序 测试程序要实现读、写功能 ./hello_test /dev/xxx abcdef // 把字符串“abcdeft”发给驱动程序 ./hello_test /dev/xxx // 把驱动中保存的字符串读回来 hello_drv_test.c源码如下 #include sys/types.h #include sys/stat.h #include fcntl.h #include unistd.h #include stdio.h #include string.h/ 写: ./hello_test /dev/xxx 100ask* 读: ./hello_test /dev/xxx*/ int main(int argc, char **argv) {int fd;int len;char buf[100];if (argc 2){printf(Usage: \n);printf(%s dev [string]\n, argv[0]);return -1;}// openfd open(argv[1], O_RDWR);if (fd 0){printf(can not open file %s\n, argv[1]);return -1;}if (argc 3){// writelen write(fd, argv[2], strlen(argv[2])1);printf(write ret %d\n, len);}else{// readlen read(fd, buf, 100);buf[99] \0;printf(read str : %s\n, buf);}// closeclose(fd);return 0; }2.3 编写驱动程序的Makefile 驱动程序中包含了很多头文件这些头文件来自内核不同的 ARM 板它的某些头文件可能不同。所以编译驱动程序时需要指定板子所用的内核的源码路径。要编译哪个文件这也需要指定设置 obj-m 变量即可怎么把.c 文件编译为驱动程序.ko这要借助内核的顶层 Makefile。 本驱动程序的 Makefile 内容如下 KERN_DIR /home/me/Linux-4.9.88 指定内核目录 先设置好交叉编译工具链编译好你的板子所用的内核然后修改 Makefile指定内核源码路径最后即可执行make命令编译驱动程序和测试程序。  三、上机实验 3.1 NFS 挂载 我们是在 Ubuntu 中编译程序但是需要在 ARM 板子上测试。所以需要把程序放到 ARM 板子上。启动单板后可以通过 NFS 挂载 Ubuntu 的某个目录访问该目录中的程序。 ifconfig eth0 192.168.5.9 //静态配置开发板ip地址 mount -t nfs -o nolock,vers3 192.168.5.11:/home/book/nfs_rootfs /mnt //挂载到开发板上的mnt目录下 echo 7 4 1 7 /proc/sys/kernel/printk //打开内核打印信息 3.2 测试示例 首先在开发板的mnt目录下查看文件是否挂载成功当前目录下以及有了Ubuntu编译好的驱动程序和测试文件 insmod hello_drv.ko // 安装驱动程序 ls /dev/hello -l // 驱动程序会生成设备节点 ./hello_drv_test // 查看测试程序的用法 显示已载入系统的模块 查看测试程序用法并写入字符串abcdef后读出测试结果如下