什么是电子商务网站建设与管理Wordpress如何设置页面格式

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

什么是电子商务网站建设与管理,Wordpress如何设置页面格式,短视频营销的正确步骤,网页美工设计课程前言 #xff08;1#xff09;学习韦东山老师的Linux#xff0c;因为他讲的很精简#xff0c;以至于很多人听不懂。接下来我讲介绍韦东山老师的驱动实验班的第二个Hello程序。 #xff08;2#xff09;注意#xff0c;请先学习完视频再来看这个教程#xff01;本文仅供… 前言 1学习韦东山老师的Linux因为他讲的很精简以至于很多人听不懂。接下来我讲介绍韦东山老师的驱动实验班的第二个Hello程序。 2注意请先学习完视频再来看这个教程本文仅供入门学习如需深入请搜索其他博客 3因为上一个教程已经讲的很详细了所以很多内容不会重复讲解只会说明区别的地方。所以阅读本教程之前建议先阅读韦东山Linux驱动入门实验班1hello驱动 4gitee仓库GitHub仓库 本教程与上一个教程区别 这一篇中的应用层代码和上一篇是一模一样的。所以本文的所有代码都是针对驱动层的如果应用层代码不理解可以看上一篇博客 区别1—驱动层与应用层数据交互 区别讲解 1 1我们在阅读编写上一个程序的时候有没有发现一个问题。就是说我们无论给驱动程序写入什么最终读取出来的都是一个奇怪的符号。这个是为什么呢 2因为应用层和驱动层是完全隔绝开来的应用层无法直接访问驱动层中的各种变量。因为这个操作系统的是要给很多开发者使用的而这些开发者可能有些人水平不够或者是想恶意破坏。那么就会存在一个问题如果这些人给驱动程序写入了一些错误数据就容易让整个系统崩溃。所以驱动层和应用层是隔绝的应用层无法直接访问驱动层同理驱动层也无法直接访问应用层。 3驱动层和应用层是怎么隔离的呢首先应用层发出请求想访问驱动层。这个时候这条指令将会传递给CPUCPU读取指令之后将信息发给MMU内存管理单元。这个时候MMU将会发现应用层发起请求想访问驱动层于是MMU将会把这个请求杀死。 4应用层和驱动层是隔离的。那么如果我硬要驱动层跟应用层进行交互怎么办呢于是就可以使用两个函数copy_from_user驱动层得到应用层数据copy_to_user驱动层发数据给应用层 3应用层和驱动层有交互函数。那么驱动层怎么跟硬件交互呢在我们编写单片机程序的时候可以直接使用寄存器编写程序也可以使用官方提供的库函数。而Linux中我们也是两种办法第一种是使用寄存器直接控制第二种就是使用子系统函数。每个寄存器都有一个地址我们将这个称之为物理地址。但是我们的驱动程序不能直接使用物理地址他必须是使用ioremap函数返回一个虚拟地址用指针存放。之后我们就可以通过这个指针操作寄存器了。 代码实操 1咱们这里有两个函数都有改动分成两部分讲。 2hello_read 1unsigned long len size 100 ? 100 : size; 这一部分用于判断传入驱动层给应用层发送的字符是否大于100个如果大于100个字符那么就只发送100个字符。如果驱动层给应用层发送的字符小于100个那么就发送实际数量的字符数。 2copy_to_user(buf, hello_buf, len); 1我们copy_to_user函数咱们上面介绍了是驱动层用于给应用层发送数据的函数。第一个参数是最终发送到应用层的数据因为我们hello_read函数的第二个参数是buf所以copy_to_user第一个参数传入buf。 2copy_to_user的第二个参数是驱动层需要发送给应用层的数据这个是需要我们自己在驱动层创建无符号字符数组hello_buf[]。hello_buf[]这个数组负责存放驱动层和应用层的交互信息。 3copy_to_user的第三个参数是需要传输的字符数量。如果传输的字符大于100那么就只传输100个字符。如果传输的字符小于100个那么就按照需要传输的字符数量传输。 3 return len; 最终返回传输的字符数量。与原来的 return size;不同在于 return size;是没有加上最多传输100个字符的限制。 3hello_write 1与hello_read的一样变化。 2copy_from_user(hello_buf, buf, len); 1copy_from_user函数和copy_to_user函数使用方法类似的。只不过copy_from_user函数是用于应用层给驱动层发送信号。 2copy_from_user的第一个参数是目的地址所以需要传入hello_buf。第二个参数是起始地址所以需要传入buf。第三个参数与copy_to_user一样。 3最终返回值的改变与hello_read的一样变化。 4最后强调一下这个代码会有两个警告。ignoring return value of ‘copy_from_user’, declared with attribute warn_unused_result和 ignoring return value of ‘copy_to_user’, declared with attribute warn_unused_result。这两个警告翻译过来就是忽略使用warn_unused_result属性声明的 copy_from_user 的返回值 和 忽略使用warn_unused_result属性声明的 copy_to_user 的返回值。 这两个警告是什么意思呢有什么影响很简单copy_from_user和copy_to_user是存在返回值的。而我们没有接收这两个函数的返回值所以会存在警告无需理会。 static unsigned char hello_buf[100]; //存放驱动层和应用层交互的信息/传入参数 *filp 要读的文件*buf 读的数据放在哪里*size 读多大数据*offset 偏移值一般不用*返回参数 读到的数据长度 */ static ssize_t hello_read (struct file *filp, char user *buf, size_t size, loff_t offset) {//判断size是否大于100如果大于100len100否则lensizeunsigned long len size 100 ? 100 : size;/FILE__ 表示文件FUNCTION 当前函数名LINE 在文件的哪一行/printk(%s %s %d\n, FILE, FUNCTION, LINE);/ 作用 驱动层发数据给应用层* buf 应用层数据* hello_buf : 驱动层数据* len 数据长度*/copy_to_user(buf, hello_buf, len);return len; } /传入参数 *filp 要写的文件*buf 写入的数据来自于buf*size 写多大数据*offset 偏移值一般不用*返回参数 写的数据长度 */ static ssize_t hello_write(struct file *filp, const char user *buf, size_t size, loff_t offset) {//判断size是否大于100如果大于100len100否则lensizeunsigned long len size 100 ? 100 : size;/FILE__ 表示文件FUNCTION 当前函数名LINE 在文件的哪一行/printk(%s %s %d\n, FILE, FUNCTION, LINE);/ 作用 驱动层得到应用层数据* buf 应用层数据* hello_buf : 驱动层数据* len 数据长度*/copy_from_user(hello_buf, buf, len);return len; } 结果演示 1与上一个博客一样流程 1Ubuntu下make编译 2打开开发板输入mount -t nfs -o nolock,vers3  192.168.5.11:/home/book/nfs_rootfs  /mnt共享文件 3内核打印可以选中打开或者不打开 关闭内核打印echo 0 4 0 7 /proc/sys/kernel/printk 打开内核打印echo 7 4 1 7 /proc/sys/kernel/printk 4insmod hello_drv.ko装载驱动 5cat /proc/devices:查看当前已经被使用掉的设备号注意这里的设备号之后的创建设备节点需要用到 6 mknod  /dev/xyz c 240 0 xyz可以为任意名字设备号与上面的有关0表示次设备号随便填 7在应用层调用设备节点如./hello_test /dev/xyz  123 8卸载驱动程序 rmmod 驱动程序 9删除设备节点rm  /dev/xyz 2 关闭内核打印演示结果 3打开内核打印演示结果 区别二—自动创建设备节点 讲解 1咱们有没有发现一个问题驱动装载流程太长了。我们能不能自动创建一个设备节点然后自己删除呢答案是可以的不然我也不会提及。 2如何在让系统实现自动创建设备节点呢这个时候我们就要讲到两个函数。class_create和device_create。 1class_create函数用于动态创建设备的逻辑类此函数的执行效果就是在目录/sys/class下创建一个新的文件夹此文件夹的名字为此函数的第二个输入参数但此文件夹是空的。同时在/sys/devices目录下也会创建新的空文件夹。 2device_create函数就是用于创建设备节点的第一个参数为class_create的返回值。class_create函数不是在/sys/class中创建一个空的文件夹麻device_create函数就是在这个空的文件夹中创建一个链接文件。同时在/sys/devices/virtual目录下创建新的逻辑设备目录。这个链接文件也就是咱们输入mknod命令创建的设备节点。 3自动创建了设备节点之后我们还需要销毁设备节点。那么这个时候又需要使用两个函数了。device_destroy和class_destroy。 1因为我们创建设备节点的时候是先注册驱动再创建逻辑类最后创建设备节点的。所以销毁的时候需要反过来。先销毁设备节点再销毁逻辑类最后卸载驱动。 2class_destroy执行的效果是删除函数__class_create()或宏class_create()在目录/sys/class下创建的逻辑类对应的文件夹。device_destroy用于销毁设备节点。 代码  //在命令行输入insmod命令就是注册驱动程序。之后就会进入这个入口函数 //3,入口函数 static int hello_init(void) {/*将hello_drv这个驱动放在内核的第n项中间传入的名字不重要第三个是要告诉内核的驱动*因为我们不知道第n项是否已经存放了其他驱动就可以放在第0项然后让系统自动往后遍历存放到空的地方major为最终存放的第n项,等下卸载程序需要使用。如果不卸载程序可以不管这个/major register_chrdev(0, 100ask_hello, hello_drv);//如果成功注册驱动打印printk(insmod success!\n);/***这里相当于命令行输入 mknod /dev/hello c 240 0 创建设备节点**///创建类为THIS_MODULE模块创建一个类这个类叫做hello_classhello_class class_create(THIS_MODULE, hello_class);if (IS_ERR(hello_class)) //如果返回错误{//打印类创建失败printk(failed to allocate class\n);//返回错误return PTR_ERR(hello_class);}/*在hello_class类下面创建设备*无父设备的指针*MKDEV传入主设备号major和此设备号0*没有私有数据输入参数是逻辑设备的设备名即在目录/dev目录下创建的设备名/device_create(hello_class, NULL, MKDEV(major, 0), NULL, hello); /* /dev/hello */return 0; }//在命令行输入rmmod命令就是注册驱动程序。之后就会进入这个出口函数 //4,出口函数 static void hello_exit(void) {//销毁hello_class类下面的设备节点device_destroy(hello_class, MKDEV(major, 0));//销毁hello_class类class_destroy(hello_class);//卸载驱动程序//第一个参数是主设备号第二个是名字unregister_chrdev(major, 100ask_hello);//如果成功卸载驱动打印printk(rmmod success!\n); } 效果演示 1演示自动产生设备节点 2现在使用驱动需要的步骤 1Ubuntu下make编译 2打开开发板输入mount -t nfs -o nolock,vers3  192.168.5.11:/home/book/nfs_rootfs  /mnt共享文件 3内核打印可以选中打开或者不打开 关闭内核打印echo 0 4 0 7 /proc/sys/kernel/printk 打开内核打印echo 7 4 1 7 /proc/sys/kernel/printk 4insmod hello_drv.ko装载驱动 5在应用层调用设备节点如./hello_test /dev/xyz  123 6卸载驱动程序 rmmod 驱动程序