网上开店的基本流程有哪些河池网站seo
news/
2025/9/23 14:00:46/
文章来源:
网上开店的基本流程有哪些,河池网站seo,彩票网站搭建多钱,枣阳市建设局网站目录 前言
驱动入门知识
1.APP 打开的文件在内核中如何表示
2.打开字符设备节点时#xff0c;内核中也有对应的 struct file
编写 Hello 驱动程序步骤
1.流程介绍
2.驱动代码#xff1a;
3.应用层代码#xff1a;
4.本驱动程序的 Makefile 内容#xff1a;
5.上机…目录 前言
驱动入门知识
1.APP 打开的文件在内核中如何表示
2.打开字符设备节点时内核中也有对应的 struct file
编写 Hello 驱动程序步骤
1.流程介绍
2.驱动代码
3.应用层代码
4.本驱动程序的 Makefile 内容
5.上机实验 前言
在编译驱动程序之前要先编译内核原因有三点
驱动程序要用到内核文件编译驱动时用的内核、开发板上运行到内核要一致更换板子上的内核后板子上的其他驱动也要更换
编译内核步骤看我之前写过的文章编译替换内核_设备树_驱动_IMX6ULL-CSDN博客
驱动入门知识
1.首先我们通常都是在Linux的终端上打开一个可执行文件然后可执行文件就会执行程序。那么这个可执行文件做了什么呢
2.可执行文件先是在应用层读取程序其中会有很多库函数库函数是属于内核之中。而内核又会往下调用驱动层程序。最终驱动层控制具体硬件。
其实应用程序到库是比较容易理解的比如我们刚学习C语言的时候使用了printfscanf等等这些函数。而这些函数就在库中。库可以和系统内核相连接具体怎么实现的我也不太清楚。我们写了一个驱动程序就需要告诉内核这个过程叫做注册。我们注册了驱动之后内核里面就会有这个驱动程序的信息然后上层应用就可以调用。
3.所以我们只需要知道咱们需要编写两个程序一个是驱动层的一个是应用层的最后驱动层需要注册进入内核应用层才能够使用。其他的先不要管。
4.我们在应用层调用read函数对应驱动层的read函数。write函数和write函数对应。open函数和open函数对应。close函数和release函数对应这个为什么不一样我也不清楚。
5.我们对Linux 应用程序对驱动程序的调用流程有一个简单了解之后我得知道整个程序编写流程应该怎么做。至于流程为什么是这样的我们记住即可。因为这些都是人规定的如果之后学的深了再进行深究也不迟现在我们主要是入门
1.APP 打开的文件在内核中如何表示
APP 打开文件时可以得到一个整数这个整数被称为文件句柄。对于 APP 的每一个文件句柄在内核里面都有一个“struct file”与之对应。 我们使用 open 打开文件时传入的 flags、mode 等参数会被记录在内核中对应的 struct file 结构体里(f_flags、f_mode)
int open(const char *pathname, int flags, mode_t mode);
去读写文件时文件的当前偏移地址也会保存在 struct file 结构体的 f_pos 成员里。 2.打开字符设备节点时内核中也有对应的 struct file
注意这个结构体中的结构体struct file_operations *f_op这是由驱动程序提供的。 结构体 struct file_operations 的定义如下 编写 Hello 驱动程序步骤
主要为一下七个步骤
确定主设备号也可以让内核分配定义自己的 file_operations 结构体实现对应的 drv_open/drv read/drv write 等函数填入 file operations 结构体把 file_operations 结构体告诉内核: register_chrdev谁来注册驱动程序啊? 得有一个入口函数:安装驱动程序时就会去调用这个入口函数有入口函数就应该有出口函数: 卸载驱动程序时出口函数调用unregister_chrdev其他完善:提供设备信息自动创建设备节点: class_create,device_create
1.流程介绍 1我们首先需要编写一个file_operations类型的结构体这个结构体用于管理驱动程序。之后我们将驱动程序注册进入内核之后我们在应用层调用这个驱动那么就可以直接通过这个结构体来操作驱动中的openwriteread等函数。 2实现对应的 drv_open/drv_read/drv_write 等函数填入 file_operations 结构体。这样我们在应用层调用openwriteread等函数就是调用这个驱动了。 这个时候有人可能会问了有这么多个驱动我怎么知道open对应的是哪一个驱动很简单咱们在写应用层程序的时候是不是第一个参数是需要传入一个设备号。系统根据这个设备号来判断是调用的哪一个驱动。 3把 file_operations 结构体告诉内核 register_chrdev。我们写了一个驱动但是内核是不知道的。那么怎么办呢我们就去注册他内核就明白有了这个驱动然后给他分配一个设备号。之后应用层就可以根据这个设备号来调用驱动层了。 4 这个时候有人就有疑问了谁来注册这个结构体于是我们需要一个入口函数来进行注册安装驱动程序时就会去调用这个入口函数。 5有入口函数就应该有出口函数卸载驱动程序时出口函数调用unregister_chrdev。 6最后需要加入GPL协议。因为Linux是遵顼GPL协议的所以你如果需要使用Linux其他的驱动层函数就必须遵顼GPL协议强制要求开源代码。根据这个协议你可以要求所有使用Linux的厂商提供驱动层源代码同时别人也可以要求你公开你的驱动层代码这个是相互的。不过很多厂商为了规避这个协议驱动源代码很简单复杂的东西放在应用层。至于还有一个作者名字的添加随便写不写。 2.驱动代码
hello_drv.c
#include linux/module.h#include linux/fs.h
#include linux/errno.h
#include linux/miscdevice.h
#include linux/kernel.h
#include linux/major.h
#include linux/mutex.h
#include linux/proc_fs.h
#include linux/seq_file.h
#include linux/stat.h
#include linux/init.h
#include linux/device.h
#include linux/tty.h
#include linux/kmod.h
#include linux/gfp.h/* 1. 确定主设备号 */
static int major 0;
static char kernel_buf[1024];
static struct class *hello_class;#define MIN(a, b) (a b ? a : b)/* 3. 实现对应的open/read/write等函数填入file_operations结构体 */
static ssize_t hello_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{int err;printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);err copy_to_user(buf, kernel_buf, MIN(1024, size));return MIN(1024, size);
}static ssize_t hello_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{int err;printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);err copy_from_user(kernel_buf, buf, MIN(1024, size));return MIN(1024, size);
}static int hello_drv_open (struct inode *node, struct file *file)
{printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);return 0;
}static int hello_drv_close (struct inode *node, struct file *file)
{printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);return 0;
}/* 2. 定义自己的file_operations结构体 */
static struct file_operations hello_drv {.owner THIS_MODULE,.open hello_drv_open,.read hello_drv_read,.write hello_drv_write,.release hello_drv_close,
};/* 4. 把file_operations结构体告诉内核注册驱动程序 */
/* 5. 谁来注册驱动程序啊得有一个入口函数安装驱动程序时就会去调用这个入口函数 */
static int __init hello_init(void)
{int err;printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);major register_chrdev(0, hello, hello_drv); /* /dev/hello */hello_class class_create(THIS_MODULE, hello_class);err PTR_ERR(hello_class);if (IS_ERR(hello_class)) {printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, hello);return -1;}device_create(hello_class, NULL, MKDEV(major, 0), NULL, hello); /* /dev/hello */return 0;
}/* 6. 有入口函数就应该有出口函数卸载驱动程序时就会去调用这个出口函数 */
static void __exit hello_exit(void)
{printk(%s %s line %d\n, __FILE__, __FUNCTION__, __LINE__);device_destroy(hello_class, MKDEV(major, 0));class_destroy(hello_class);unregister_chrdev(major, hello);
}/* 7. 其他完善提供设备信息自动创建设备节点 */module_init(hello_init);
module_exit(hello_exit);MODULE_LICENSE(GPL);
3.应用层代码
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_drv_test -w abc* ./hello_drv_test -r*/
int main(int argc, char **argv)
{int fd;char buf[1024];int len;/* 1. 判断参数 */if (argc 2) {printf(Usage: %s -w string\n, argv[0]);printf( %s -r\n, argv[0]);return -1;}/* 2. 打开文件 */fd open(/dev/hello, O_RDWR);if (fd -1){printf(can not open file /dev/hello\n);return -1;}/* 3. 写文件或读文件 */if ((0 strcmp(argv[1], -w)) (argc 3)){len strlen(argv[2]) 1;len len 1024 ? len : 1024;write(fd, argv[2], len);}else{len read(fd, buf, 1024); buf[1023] \0;printf(APP read : %s\n, buf);}close(fd);return 0;
}
怎么把.c 文件编译为驱动程序.ko
这要借助内核的顶层 Makefile先设置好交叉编译工具链编译好你的板子所用的内核然后修改 Makefile 指定内核源码路径最后即可执行 make 命令编译驱动程序和测试程序。
4.本驱动程序的 Makefile 内容
KERN_DIR /home/book/100ask_imx6ull-sdk/Linux-4.9.88all:make -C $(KERN_DIR) Mpwd modules$(CROSS_COMPILE)gcc -o hello_drv_test hello_drv_test.cclean:make -C $(KERN_DIR) Mpwd modules cleanrm -rf modules.orderrm -f hello_drv_testobj-m hello_drv.o5.上机实验
执行 make 命令编译驱动程序和测试程序
启动单板后可以通过 NFS 挂载 Ubuntu 的某个目录访问该目录中的程序。 打开内核打印echo 7 4 1 7 /proc/sys/kernel/printk
关闭内核打印echo 0 4 0 7 /proc/sys/kernel/printk
insmod 就是install module的缩写载入模块
insmod hello_drv.ko装载驱动
ls /dev/hello -l // 驱动程序会生成设备节点 驱动程序会生成设备节点
lsmod 确认驱动已经安装
我们知道驱动已经安装好了那么我们需要知道这个驱动的设备号
cat /proc/devices查看当前已经被使用掉的设备号
驱动名字与我们在驱动层使用register_chrdev函数的第二个参数有关 ./hello_drv_test // 查看测试程序的用法
./hello_drv_test -w zglnb // 往驱动程序中写入字符串
./hello_drv_test -r // 从驱动程序中读出字符串
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/912765.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!