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

免费网站建设视频哪个网站可以做水果销售代理

免费网站建设视频,哪个网站可以做水果销售代理,东莞公司展厅设计公司,wordpress 博客页面至多显示文章目录一、字符设备驱动高级1.1 注册字符设备驱动新接口1.1.1 新接口与旧接口1.1.2 cdev介绍1.1.3 设备号1.1.4 编程实践1.1.5 alloc_chrdev_region自动分配设备号1.1.6 中途出错的倒影式错误处理方法二、字符设备驱动注册代码分析2.1 旧接口register_chrdev2.2 新接口regist… 文章目录一、字符设备驱动高级1.1 注册字符设备驱动新接口1.1.1 新接口与旧接口1.1.2 cdev介绍1.1.3 设备号1.1.4 编程实践1.1.5 alloc_chrdev_region自动分配设备号1.1.6 中途出错的倒影式错误处理方法二、字符设备驱动注册代码分析2.1 旧接口register_chrdev2.2 新接口register_chrdev_region alloc_chrdev_region2.3 注销三、自动创建字符设备驱动的设备文件3.1 解决方案udev嵌入式中用的是mdev3.2 内核驱动设备类相关函数四、设备类相关代码分析4.1 sysfs文件系统五、静态映射表建立过程分析5.1 建立映射表的三个关键部分六、动态映射结构体方式操作寄存器七、内核提供的读写寄存器接口一、字符设备驱动高级 1.1 注册字符设备驱动新接口 1.1.1 新接口与旧接口 旧接口register_chrdev新接口register_chrdev_region(注册设备号)/alloc_chrdev_region(分配设备号) cdev 1.1.2 cdev介绍 (1) 结构体 struct cdev {struct kobject kobj; // 内嵌的内核对象每个 cdev 都是一个 kobjectstruct module *owner; // 指向实现驱动的模块const struct file_operations *ops; // 操纵这个字符设备文件的方法struct list_head list; // 与 cdev 对应的字符设备文件的 inode-i_devices 的链表头用来将已经向内核注册的所有字符设备形成链表dev_t dev; // 字符设备的设备号由主设备号和次设备号构成unsigned int count; // 隶属于同一主设备号的次设备号的个数. };(2) 模块加载函数通过 register_chrdev_region( ) 或 alloc_chrdev_region( )来静态或者动态获取设备号; (3) 通过 cdev_init( ) 建立cdev与 file_operations之间的连接通过 cdev_add( ) 向系统添加一个cdev以完成注册; (4) 模块卸载函数通过cdev_del( )来注销cdev通过 unregister_chrdev_region( )来释放设备号; 1.1.3 设备号 (1) 设备号 主设备号 次设备号 (2) dev_t类型 (3) MKDEV(MAJOR, MINOR); 说明 获取设备在设备表中的位置。 MAJOR 主设备号 MINOR 次设备号 1.1.4 编程实践 (1) 使用register_chrdev_region cdev_init cdev_add进行字符设备驱动注册 全局变量#define MYMAJOR 200#define MYCNT 1#define MYNAME testcharstatic dev_t mydev;static struct cdev test_cdev;注册驱动// 新的接口注册字符设备驱动需要2步// 第1步静态注册/分配主次设备号int retval;mydev MKDEV(MYMAJOR, 0);retval register_chrdev_region(mydev, MYCNT, MYNAME);if (retval){printk(KERN_ERR Unable to register minors for %s\n, MYNAME);return -EINVAL;}printk(KERN_INFO register_chrdev_region success\n);// 第2步注册字符设备驱动cdev_init(test_cdev, test_fops);retval cdev_add(test_cdev, mydev, MYCNT);if (retval) {printk(KERN_ERR Unable to cdev_add\n);return -EINVAL;}printk(KERN_INFO cdev_add success\n);注销驱动 // 使用新的接口来注销字符设备驱动// 注销分2步// 第一步真正注销字符设备驱动用cdev_delcdev_del(test_cdev);// 第二步去注销申请的主次设备号unregister_chrdev_region(mydev, MYCNT);1.1.5 alloc_chrdev_region自动分配设备号 (1) register_chrdev_region是在事先知道要使用的主、次设备号时使用的要先查看cat /proc/devices去查看没有使用的。 (2) 更简便、更智能的方法是让内核给我们自动分配一个主设备号使用alloc_chrdev_region就可以自动分配了。 (3) 自动分配的设备号必须去知道它的主次设备号否则后面没法去mknod创建他对应的设备文件。 (4) 使用MAJOR宏和MINOR宏从dev_t得到major和minor (5) 反过来使用MKDEV宏从major和minor得到dev_t。 (6) 使用这些宏的代码具有可移植性 #define MYCNT 1#define MYNAME testcharstatic dev_t mydev;static struct cdev test_cdev;//自动分配主次设备号retval alloc_chrdev_region(mydev, 12, MYCNT, MYNAME);if (retval 0) {printk(KERN_ERR Unable to alloc minors for %s\n, MYNAME);goto flag1;}printk(KERN_INFO alloc_chrdev_region success\n);printk(KERN_INFO major %d, minor %d.\n, MAJOR(mydev), MINOR(mydev)); //获取我们的主次设备号用于创建设备文件1.1.6 中途出错的倒影式错误处理方法 (1) 内核中很多函数中包含了很多个操作这些操作每一步都有可能出错而且出错后,后面的步骤就没有进行下去的必要性了。所以就有了倒影式处理错误的方法。 // 第1步分配主次设备号retval alloc_chrdev_region(mydev, 12, MYCNT, MYNAME);if (retval 0) {printk(KERN_ERR Unable to alloc minors for %s\n, MYNAME);goto flag1;}// 第2步注册字符设备驱动cdev_init(test_cdev, test_fops);retval cdev_add(test_cdev, mydev, MYCNT);if (retval) {printk(KERN_ERR Unable to cdev_add\n);goto flag2;}// 第3步使用动态映射的方式来操作寄存器if (!request_mem_region(GPJ0CON_PA, 4, GPJ0CON))goto flag3;// 如果第3步才出错跳转到这里来 flag3:release_mem_region(GPJ0CON_PA, 4);// 如果第2步才出错跳转到这里来 flag2:cdev_del(test_cdev);// 如果第1步才出错跳转到这里来 flag1:// 在这里把第1步做成功的东西给注销掉unregister_chrdev_region(mydev, MYCNT);注使用cdev_alloccdev_init的替代(重点) 二、字符设备驱动注册代码分析 2.1 旧接口register_chrdev register_chrdev注册函数 》 __register_chrdev -- 内核级函数》 __register_chrdev_region -- 内核级函数》cdev_alloc -- 让内核为这个结构体分配内存的。》cdev_add -- 向内核里面添加一个驱动注册驱动。函数 __register_chrdev_region() 主要执行以下步骤 分配一个新的 char_device_struct 结构并用 0 填充。如果申请的设备编号范围的主设备号为 0那么表示设备驱动程序请求动态分配一个主设备号。动态分配主设备号的原则是从散列表的最后一个桶向前寻找那个桶是空的主设备号就是相应散列桶的序号。所以动态分配的主设备号总是小于 256如果每个桶都有字符设备编号了那动态分配就会失败。根据参数设置 char_device_struct 结构中的初始设备号范围大小及设备驱动名称。计算出主设备号所对应的散列桶为新的 char_device_struct 结构寻找正确的位置。同时如果设备编号范围有重复的话则出错返回。将新的 char_device_struct 结构插入散列表中并返回 char_device_struct 结构的地址。 2.2 新接口register_chrdev_region alloc_chrdev_region register_chrdev_region 动态分配主次设备号 》__register_chrdev_regionregister_chrdev_region() 函数用于分配指定的设备编号范围。如果申请的设备编号范围跨越了主设备号它会把分配范围内的编号按主设备号分割成较小的子范围并在每个子范围上调用 __register_chrdev_region() 。如果其中有一次分配失败的话那会把之前成功分配的都全部退回。 alloc_chrdev_region让内核自动给我们分配设备号 》__register_chrdev_regionalloc_chrdev_region() 函数用于动态申请设备编号范围通过指针参数返回实际获得的起始设备编号。 2.3 注销 注销和注册分配字符设备编号范围类似内核提供了两个注销字符设备编号范围的函数分别是 unregister_chrdev_region() 和 unregister_chrdev() 。它们都调用__unregister_chrdev_region函数这个就不分析了。 三、自动创建字符设备驱动的设备文件 (1) 整体流程回顾 (2) 使用mknod创建设备文件的缺点 (3) 能否自动生成和删除设备文件 3.1 解决方案udev嵌入式中用的是mdev (1) 什么是udev应用层的一个应用程序 (2) 内核驱动和应用层udev之间有一套信息传输机制netlink协议 (3) 应用层启用udev内核驱动中使用相应接口 (4) 驱动注册和注销时信息会被传给udev由udev在应用层进行设备文件的创建和删除 3.2 内核驱动设备类相关函数 class_create/class_destroydevice_create/device_destroy #include linux/device.h //相关的函数包含在这个头文件里面static dev_t mydev; static struct class *test_class;// 注册字符设备驱动完成后添加设备类的操作以让内核帮我们发信息// 给udev让udev自动创建和删除设备文件test_class class_create(THIS_MODULE, aston_class);if (IS_ERR(test_class))return -EINVAL;// 最后1个参数字符串就是我们将来要在/dev目录下创建的设备文件的名字// 所以我们这里要的文件名是/dev/test111device_create(test_class, NULL, mydev, NULL, test111);//在注销设备驱动之前device_destroy(test_class, mydev);class_destroy(test_class);四、设备类相关代码分析 4.1 sysfs文件系统 因为udev需要sysfs文件系统的支持sysfs文件系统只在linux-2.6内核以上才有所以它存在于Linux-2.6版本之后的内核。udev借助于netlink协议在内核驱动和应用层之间传递信息。当内核中的驱动完成注册和注销时信息会被传送给应用层的udevudev便会自动地完成设备文件的创建和删除。 内核中定义了struct class结构体顾名思义一个struct class结构体类型变量对应一个类 内核同时提供了class_create(…)函数可以用它来创建一个类这个类存放于sysfs下面一旦创建好了这个类再调用 device_create(…)函数来在/dev目录下创建相应的设备节点。这样加载模块的时候用户空间中的udev会自动响应 device_create(…)函数去/sysfs下寻找对应的类从而创建设备节点。 2、class_creat device_createt (1) class_creat 树形调用的主要的函数 class_create(); __class_create(); __class_register(); kset_register(); kobject_uevent(); (2) device_createt 树形调用的主要的函数 struct device *device_create(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...) ------------------- 参数”...”就是可变参数 更多的时候表示了次设备号。 { ......... }例如此图中 tty 就表示主设备号 后面的14… 15等表示次设备号 device_createt();device_create_vargs();kobject_set_name_vargs();device_register();device_add();kobject_add(); //真正的把设备添加进去了device_create_file();//下面这些函数都是操作 sysfs 的函数device_create_sys_dev_entry();devtmpfs_create_node();device_add_class_symlinks();device_add_attrs();device_pm_add();kobject_uevent();device_create_file() 函数创建的就是 dev 目录(sysfs函数实现的) int device_create_file(struct device *dev,const struct device_attribute *attr) {int error 0;if (dev) {....error sysfs_create_file(dev-kobj, attr-attr);}return error; } EXPORT_SYMBOL_GPL(device_create_file);参数 uevent_attr static struct device_attribute uevent_attr __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent); -------- 给出的属性, 参数中 show_uevent, store_uevent 表示读和存储。所以在执行cat dev 读取 dev 这个文件时 内核调用的就是 show_uevent 函数。 五、静态映射表建立过程分析 5.1 建立映射表的三个关键部分 (1) 主映射表映射表具体物理地址和虚拟地址的值相关的宏定义 (2) 映射表建立函数。该函数负责由(1)中的映射表来建立linux内核的页表映射关系。 在kernel/arch/arm/mach-s5pv210/mach-smdkc110.c中的smdkc110_map_io函数 smdkc110_map_io();s5p_init_io();iotable_init(); // 引出io 描述符的概念经过分析真正的内核移植时给定的静态映射表在arch/arm/plat-s5p/cpu.c中的s5p_iodesc本质是一个结构体数组数组中每一个元素就是一个映射这个映射描述了一段物理地址到虚拟地址之间的映射。这个结构体数组所记录的几个映射关系被iotable_init所使用该函数负责将这个结构体数组格式的表建立成MMU所能识别的页表映射关系这样在开机后可以直接使用相对应的虚拟地址来访问对应的物理地址。 注该部分重点记录分析方法。 // 由上图可以看出内存管理最小的表是4K。 (3) 开机时调用映射表建立函数 问题开机时kernel启动时smdkc110_map_io怎么被调用的 函数调用层级 start_kernel();setup_arch();paging_init();devicemaps_init();if (mdesc-map_io)mdesc-map_io();六、动态映射结构体方式操作寄存器 知识回顾之前的动态映射每个寄存器地址是单独映射的要进行多次。 (1) 仿效真实驱动中用结构体封装的方式来进行单次多寄存器的地址映射。 实验代码 typedef struct GPJ0REG {volatile unsigned int gpj0con;volatile unsigned int gpj0dat; } gpj0_reg_t;#define GPJ0_REGBASE 0xe0200240 //物理地址 gpj0_reg_t *pGPJ0REG;// 使用动态映射的方式来操作寄存器if (!request_mem_region(GPJ0_REGBASE, sizeof(gpj0_reg_t), GPJ0REG))return -EINVAL;pGPJ0REG ioremap(GPJ0_REGBASE, sizeof(gpj0_reg_t));// 映射之后用指向结构体的指针来进行操作// 指针使用-结构体内元素的方式来操作各个寄存器pGPJ0REG-gpj0con 0x11111111;pGPJ0REG-gpj0dat ((03) | (04) | (05)); // 亮// 解除映射iounmap(pGPJ0REG);release_mem_region(GPJ0_REGBASE, sizeof(gpj0_reg_t));七、内核提供的读写寄存器接口 内核提供的寄存器读写接口在不同的架构下可移植性高 (1) writel和readl,在3.字符设备驱动上篇已经提过了。 (2) iowrite32和ioread32代码实践 #define GPJ0CON S5PV210_GPJ0CON #define GPJ0DAT S5PV210_GPJ0DAT#define rGPJ0CON *((volatile unsigned int *)GPJ0CON) #define rGPJ0DAT *((volatile unsigned int *)GPJ0DAT)#define GPJ0CON_PA 0xe0200240 #define GPJ0DAT_PA 0xe0200244#define S5P_GPJ0REG(x) (x) #define S5P_GPJ0CON S5P_GPJ0REG(0) #define S5P_GPJ0DAT S5P_GPJ0REG(4)unsigned int *pGPJ0CON; unsigned int *pGPJ0DAT;static void __iomem *baseaddr; // 寄存器的虚拟地址的基地址// 使用动态映射的方式来操作寄存器if (!request_mem_region(GPJ0CON_PA, 4, GPJ0CON))return -EINVAL;if (!request_mem_region(GPJ0DAT_PA, 4, GPJ0CON))return -EINVAL;pGPJ0CON ioremap(GPJ0CON_PA, 4);pGPJ0DAT ioremap(GPJ0DAT_PA, 4);/************/ 原始的用解引用指针的方法 /***********/*pGPJ0CON 0x11111111; *pGPJ0DAT ((03) | (04) | (05)); // 亮/***********/ 使用内部读写接口的方法 /***********/测试1用2次ioremap得到的动态映射虚拟地址来操作测试成功 writel(0x11111111, pGPJ0CON); writel(((03) | (04) | (05)), pGPJ0DAT);测试2用静态映射的虚拟地址来操作测试成功 writel(0x11111111, GPJ0CON); writel(((03) | (04) | (05)), GPJ0DAT);测试3用1次ioremap映射多个寄存器得到虚拟地址测试成功 if (!request_mem_region(GPJ0CON_PA, 8, GPJ0BASE))return -EINVAL; baseaddr ioremap(GPJ0CON_PA, 8);writel(0x11111111, baseaddr S5P_GPJ0CON); writel(((03) | (04) | (05)), baseaddr S5P_GPJ0DAT);操作寄存器的大致流程 注 本文参考朱有鹏老师网上学员的学习记录博客根据自己的理解进行学习汇总如有侵权联系本人及时删除。
http://www.tj-hxxt.cn/news/134664.html

相关文章:

  • 台州做网站软件网站建设平台对比
  • 网站界面设计案例wordpress页面注册忘记密码
  • 网上商城网站开发公司拼多多网络营销方式
  • 企业网站优化定制ui设计师需要学的软件
  • 国外公共空间设计网站windows 安装 wordpress
  • 游戏网站建设论文网站设计素养
  • 做网站的群海外网站建设
  • 邢台网站建设公司做cpc不做网站可以吗
  • 简诉网站建设的基本流程图北京网站建设怎么样天
  • 商标 做网站 是几类龙岩正规全网品牌营销招商
  • 网站架构方案windows优化大师和鲁大师
  • 会计网站建设意义网站制作价格范围
  • 做demo的网站app开发公司大概多少钱
  • 58同城的网站怎么做的什么网站都能打开的浏览器
  • 学做网站论坛vip共享免费十八种禁用网站游戏
  • 上海网站关键词排名建站公司要不要承担网站被黑
  • 西部数码网站打不开苏州品牌网站设计
  • 利用google地图标注做网站镇江住房和城乡建设局网站
  • 县城做二手车网站成都建设网站哪些公司好
  • 建立网站批复简付后wordpress
  • 南通企业网站排名东台网站网站建设
  • 个人建站平台wordpress文章前台看不到
  • 网站免费申请建站网站建设 物流
  • 组织部信息化建设官方网站dedecms网站关键词
  • 上海技术做网站永久免费可联网的进销存软件
  • 网站建设html代码wordpress的搭建教程 pdf
  • 网站建设价格情况wordpress熊掌号自动推送
  • 孟村县做网站涿州市建设局网站
  • 高端大气网站模板wordpress自定义结构空白页
  • 深圳自适应网站的公司网站开发如何记账