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

网站建设介绍会发言稿建设网站需要多少人

网站建设介绍会发言稿,建设网站需要多少人,搬瓦工如何搭建做网站,建立网站根目录下本文有部分借鉴 wowo tech #xff0c;感谢作者的无私分享 目录 1、简介 2、Platform 软件架构 3、Platform 模块向其它模块提供的 APIs 3.1、数据结构 3.1.1、platform_device 3.1.2、platform_driver 3.2、APIs 3.2.1、Platform Device 提供的 APIs 3.2.2、Platfor…本文有部分借鉴 wowo tech 感谢作者的无私分享 目录 1、简介 2、Platform 软件架构 3、Platform 模块向其它模块提供的 APIs 3.1、数据结构 3.1.1、platform_device 3.1.2、platform_driver 3.2、APIs 3.2.1、Platform Device 提供的 APIs 3.2.2、Platform Driver 提供的 APIs 4、Platform 初始化 4.1、Platform 总线初始化 5、Device 和 Driver 匹配执行 probe 5.1、platform_driver_register 情况 5.2、platform_device_register 情况 5.3、小结 1、简介 在Linux设备模型的抽象中存在着一类称作“Platform Device”的设备内核是这样描述它们的Documentation/driver-model/platform.txt Platform devices are devices that typically appear as autonomous entities in the system. This includes legacy port-based devices and host bridges to peripheral buses, and most controllers integrated into system-on-chip platforms.  What they usually have in common is direct addressing from a CPU bus.  Rarely, a platform_device will be connected through a segment of some other kind of bus; but its registers will still be directly addressable. 概括来说Platform设备包括基于端口的设备已不推荐使用保留下来只为兼容旧设备legacy连接物理总线的桥设备集成在SOC平台上面的控制器连接在其它bus上的设备很少见。等等。 这些设备有一个基本的特征可以通过CPU bus直接寻址例如在嵌入式系统常见的“寄存器”。因此由于这个共性内核在设备模型的基础上device和device_driver对这些设备进行了更进一步的封装抽象出paltform bus、platform device和platform driver以便驱动开发人员可以方便的开发这类设备的驱动。 platform总线是虚拟的平台总线是linux设备驱动模型为了保持设备驱动的统一性而虚拟出来的总线。  总线将设备和驱动绑定系统每注册一个设备的时候会寻找与之匹配的驱动相反系统每注册一个驱动的时候会寻找与之匹配的设备而匹配由总线完成。 可以说paltform设备对Linux驱动工程师是非常重要的因为我们编写的大多数设备驱动都是为了驱动plaftom设备。本文我们就来看看Platform设备在内核中的实现。 2、Platform 软件架构 内核中Platform设备有关的实现位于 include/linux/platform_device.h 和 drivers/base/platform.c 两个文件中它的软件架构如下 由图片可知Platform设备在内核中的实现主要包括三个部分 Platform Bus基于底层bus模块抽象出一个虚拟的Platform bus用于挂载Platform设备 Platform Device基于底层device模块抽象出Platform Device用于表示Platform设备 Platform Driver基于底层device_driver模块抽象出Platform Driver用于驱动Platform设备。 3、Platform 模块向其它模块提供的 APIs Platform 提供的接口包括Platform Device 和 Platform Driver 两个数据结构以及它们的操作函数。 3.1、数据结构 3.1.1、platform_device platform_device 代表了一种 device定义在 include/linux/platform_device.h 文件 struct platform_device {const char * name;int id;struct device dev;u32 num_resources;struct resource * resource;const struct platform_device_id *id_entry;/* MFD cell pointer */struct mfd_cell *mfd_cell;/* arch specific additions */struct pdev_archdata archdata; }; 它的字段解释如下 dev真正的设备Platform设备只是一个特殊的设备因此其核心逻辑还是由底层的模块实现。 name设备的名称和 struct device 结构中的 init_name 一样。实际上该名称在设备注册时会拷贝到 dev.init_name中。 id用于表示该设备的 ID。 id_auto指示在注册设备时是否自动赋予ID值不需要人为指定啦可以懒一点啦。 num_resources、resource该设备的资源描述由struct resourceinclude/linux/ioport.h结构抽象。 在Linux中系统资源包括I/O、Memory、Register、IRQ、DMA、Bus等多种类型。这些资源大多具有独占性不允许多个设备同时使用因此Linux内核提供了一些API用于分配、管理这些资源。  当某个设备需要使用某些资源时只需利用struct resource组织这些资源如名称、类型、起始、结束地址等并保存在该设备的resource指针中即可。然后在设备probe时设备需求会调用资源管理接口分配、使用这些资源。而内核的资源管理逻辑可以判断这些资源是否已被使用、是否可被使用等等。 id_entry和内核模块相关的内容暂不说明。 mfd_cell和MFD设备相关的内容暂不说明。 archdata不管它了 可以看出 platform_device 其实是裹了一层 struct device 的一种设备的抽象。 3.1.2、platform_driver platform_driver 是一种特殊的 driver它定义在 include/linux/platform_device.h 文件 struct platform_driver {int (*probe)(struct platform_device *);int (*remove)(struct platform_device *);void (*shutdown)(struct platform_device *);int (*suspend)(struct platform_device *, pm_message_t state);int (*resume)(struct platform_device *);struct device_driver driver;const struct platform_device_id *id_table; }; struct platform_driver结构和struct device_driver非常类似无非就是提供probe、remove、suspend、resume等回调函数这里不再细说。 另外这里有一个 id_table 的指针该指针和 of_match_table、acpi_match_table 的功能类似提供其它方式的设备probe。 内核会在合适的时机检查device和device_driver的名字如果匹配则执行probe。其实除了名称之外还有一些宽泛的匹配方式例如这里提到的各种match table具体原理就先不罗嗦了徒添烦恼就当没看见呵呵。  3.2、APIs 3.2.1、Platform Device 提供的 APIs Platform Device主要提供设备的分配、注册等接口供其它driver使用常用的包括 1、注册/注销一个 Platform 设备 int platform_device_register(struct platform_device *); void platform_device_unregister(struct platform_device *);int platform_add_devices(struct platform_device **, int); // 增加多个 devices2、获取资源 struct resource *platform_get_resource(struct platform_device *,unsigned int, unsigned int);struct resource *platform_get_resource_byname(struct platform_device *,unsigned int,const char *); 3、获取 irq int platform_get_irq(struct platform_device *, unsigned int); int platform_get_irq_byname(struct platform_device *, const char *); 4、向 platform_device 增加资源 int platform_device_add_resources(struct platform_device *pdev,const struct resource *res,unsigned int num);5、向 platform device 中添加自定义的数据保存在pdev-dev.platform_data指针中 int platform_device_add_data(struct platform_device *pdev,const void *data, size_t size); 3.2.2、Platform Driver 提供的 APIs Platform Driver提供struct platform_driver的分配、注册等功能常用的包括 1、注册/注销 platform_driver 接口 int platform_driver_register(struct platform_driver *); void platform_driver_unregister(struct platform_driver *); 2、主动执行 probe 动作接口 int platform_driver_probe(struct platform_driver *driver,int (*probe)(struct platform_device *)); 3、设置/获取私有数据接口 inline void *platform_get_drvdata(const struct platform_device *pdev); inline void platform_set_drvdata(struct platform_device *pdev,void *data) 4、Platform 初始化 platform驱动工作流程  1. 系统开机内核初始化阶段初始化 platform 总线  2. platform_device 初始化调用 platform_add_devices一次注册多个设备或者 platform_device_register一次注册单个设备这部分一般在 arch/arm/mach 配置文件中在上电开机的时候完成 platform_device 初始化 3. platform_driver 的初始化调用 platform_driver_register 或者 driver_register该过程一般在驱动程序的 init 函数中 4.1、Platform 总线初始化 内核在启动过程中会调用到  kernel_init() – do_basic_setup() – driver_init() – platform_bus_init()  相关的东西就在这里初始化的 driver/base/platform.c int __init platform_bus_init(void) {int error;early_platform_cleanup();error device_register(platform_bus); ------- (1)if (error)return error;error bus_register(platform_bus_type); --- (2)if (error)device_unregister(platform_bus);return error; } 先看1部分通过 device_register 它注册了一个 platform_bus 的设备它的定义在 driver/base 是 struct device platform_bus {.init_name platform, }; EXPORT_SYMBOL_GPL(platform_bus); 定义一个名为 platform 的总线设备其他的platform设备都是它的子设备所以这里先注册这个设备 在看2部分通过 bus_register 注册了一个 platform_bus_type 的 bus它定义是 struct bus_type platform_bus_type {.name platform,.dev_attrs platform_dev_attrs,.match platform_match,.uevent platform_uevent,.pm platform_dev_pm_ops, }; 注册平台类型的 bus将出现 sys 文件系统在 bus 目录下创建一个 platform 的目录以及相关属性文件。 这里创建好 platform 的 bus 了就等相关的设备驱动去注册自己的 platform_device 和 platform_driver 这里我们着重关心一下 probe 的执行时机。 5、Device 和 Driver 匹配执行 probe 现在 platform_bus 已经 Ready那么我们的 device 和 driver 是如何 match 上并且执行 driver 的 probe 的呢 在总线上 device 和 driver 的名字匹配就会调用 driver 的 probe 函数 那么就会存在一个问题到底是先有 device 还是先有 driver因为他们俩注册肯定是有先后顺序的所以需要看看源代码 5.1、platform_driver_register 情况 platform_driver_register 实现了注册一个 platform_driver它的代码在 driver/base/platform.c /*** platform_driver_register - register a driver for platform-level devices* drv: platform driver structure*/ int platform_driver_register(struct platform_driver *drv) {drv-driver.bus platform_bus_type;if (drv-probe)drv-driver.probe platform_drv_probe;if (drv-remove)drv-driver.remove platform_drv_remove;if (drv-shutdown)drv-driver.shutdown platform_drv_shutdown;return driver_register(drv-driver); } EXPORT_SYMBOL_GPL(platform_driver_register); 先把 driver 的 bus 赋值成为了 platform_bus_type代表是属于 platform bus 的最后直接调用到 driver_register 注册到更底层的设备模型它的代码在 driver/base/driver.c int driver_register(struct device_driver *drv) {int ret;struct device_driver *other;BUG_ON(!drv-bus-p);if ((drv-bus-probe drv-probe) ||(drv-bus-remove drv-remove) ||(drv-bus-shutdown drv-shutdown))printk(KERN_WARNING Driver %s needs updating - please use bus_type methods\n, drv-name);other driver_find(drv-name, drv-bus); ------------(1)if (other) {put_driver(other);printk(KERN_ERR Error: Driver %s is already registered, aborting...\n, drv-name);return -EBUSY;}ret bus_add_driver(drv); ----------------------------(2)if (ret)return ret;ret driver_add_groups(drv, drv-groups);if (ret)bus_remove_driver(drv);return ret; } EXPORT_SYMBOL_GPL(driver_register); 先看1调用了 driver_find   struct device_driver *driver_find(const char *name, struct bus_type *bus) {struct kobject *k kset_find_obj(bus-p-drivers_kset, name);struct driver_private *priv;if (k) {priv to_driver(k);return priv-driver;}return NULL; } EXPORT_SYMBOL_GPL(driver_find);看看核心函数 kset_find_obj struct kobject *kset_find_obj(struct kset *kset, const char *name) {return kset_find_obj_hinted(kset, name, NULL); }struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name,struct kobject *hint) {struct kobject *k;struct kobject *ret NULL; .........list_for_each_entry(k, kset-list, entry) {if (kobject_name(k) !strcmp(kobject_name(k), name)) {ret kobject_get(k);break;}} ......... }kset_find_obj通过循环操作根据我们给的名字name在指定的bus中循环对比查看是否有相同的名字name这个name存放在kobj中。其实这就是一个循环链表的遍历过程 所以driver_find 通过我们给定的name在某bus中寻找驱动比对名字看看驱动是否已经装载 总结driver_find过程如下 1. driver_find拿到了drv-name和drv-bus开始找驱动 2. kset_find_obj 通过driver_find传递的bus-p-drivers_kset利用list_for_each_entry遍历kset循环链表。kset结构体中有循环链表指针next和prev 3. 遍历循环链表中每一个kobj中的成员变量name 4. 通过strcmp(kobject_name(k), name)比较drv-name 和kobj中的name如果有相同则表示查找成功 5. return :如果找到则返回device_driver的指针如果没有找到则返回了NULL。 返回到 driver_register 函数如果已经装载了驱动那么直接返回 -EBUSY 在看 2bus_add_driver int bus_add_driver(struct device_driver *drv) {struct bus_type *bus;struct driver_private *priv;int error 0;bus bus_get(drv-bus);if (!bus)return -EINVAL; ....priv kzalloc(sizeof(*priv), GFP_KERNEL); ....klist_init(priv-klist_devices, NULL, NULL); ....if (drv-bus-p-drivers_autoprobe) {error driver_attach(drv);if (error)goto out_unregister;} .... } 内容较多略去了部分内容主要是王指定的 bus 上增加 driver同时给底层的 kobject,kset 等等赋值添加链表等等这里我们关心 if (drv-bus-p-drivers_autoprobe) {error driver_attach(drv);if (error)goto out_unregister;} 这个 drv-bus-p-drivers_autoprobe其实就是 platform_bus_type-subsys_private-drivers_autoprobe 的值在初始化 platform_bus 的时候调用 bus_register 的时候这个值没有设置被默认设置成为了 1 int bus_register(struct bus_type *bus) {int retval;struct subsys_private *priv;priv kzalloc(sizeof(struct subsys_private), GFP_KERNEL);if (!priv)return -ENOMEM;priv-subsys.kobj.kset bus_kset;priv-subsys.kobj.ktype bus_ktype;priv-drivers_autoprobe 1;} 所以这里将会执行到 driver_attach int driver_attach(struct device_driver *drv) {return bus_for_each_dev(drv-bus, NULL, drv, __driver_attach); }int bus_for_each_dev(struct bus_type *bus, struct device *start,void *data, int (*fn)(struct device *, void *)) {struct klist_iter i;struct device *dev;int error 0;if (!bus)return -EINVAL;klist_iter_init_node(bus-p-klist_devices, i,(start ? start-p-knode_bus : NULL));while ((dev next_device(i)) !error)error fn(dev, data);klist_iter_exit(i);return error; } 进而执行到 __driver_attach 函数 static int __driver_attach(struct device *dev, void *data) {struct device_driver *drv data;/** Lock device and try to bind to it. We drop the error* here and always return 0, because we need to keep trying* to bind to devices and some drivers will return an error* simply if it didnt support the device.** driver_probe_device() will spit a warning if there* is an error.*/if (!driver_match_device(drv, dev))return 0;if (dev-parent) /* Needed for USB */device_lock(dev-parent);device_lock(dev);if (!dev-driver)driver_probe_device(drv, dev);device_unlock(dev);if (dev-parent)device_unlock(dev-parent);return 0; } 看注释希望在前方这个 driver_match_device 函数 static inline int driver_match_device(struct device_driver *drv,struct device *dev) {return drv-bus-match ? drv-bus-match(dev, drv) : 1; } 其实便是执行到了 platform_bus 的 platform_match static int platform_match(struct device *dev, struct device_driver *drv) {struct platform_device *pdev to_platform_device(dev);struct platform_driver *pdrv to_platform_driver(drv);/* Attempt an OF style match first */if (of_driver_match_device(dev, drv))return 1;/* Then try to match against the id table */if (pdrv-id_table)return platform_match_id(pdrv-id_table, pdev) ! NULL;/* fall-back to driver name match */return (strcmp(pdev-name, drv-name) 0); } 可以看到有多种 match 上的方式当然最简单的还是 name 一致 当 match 上了后执行 __driver_attach 的 driver_probe_device 函数调用 int driver_probe_device(struct device_driver *drv, struct device *dev) {int ret 0;if (!device_is_registered(dev))return -ENODEV;pr_debug(bus: %s: %s: matched device %s with driver %s\n,drv-bus-name, __func__, dev_name(dev), drv-name);pm_runtime_get_noresume(dev);pm_runtime_barrier(dev);ret really_probe(dev, drv);pm_runtime_put_sync(dev);return ret; } 直接走到了 really_probe 函数看来快看到想要的了 static int really_probe(struct device *dev, struct device_driver *drv) {int ret 0; ...atomic_inc(probe_count); ...dev-driver drv; ...if (dev-bus-probe) {ret dev-bus-probe(dev);if (ret)goto probe_failed;} else if (drv-probe) {ret drv-probe(dev);if (ret)goto probe_failed;} ... } 这里执行到了 driver-probe 函数 总体的流程是 platform_driver_register - driver_register - bus_add_driver - driver_attach - __driver_attach - match ? (0 return 1 -) - driver_probe_device (matched) - really_probe - probe 所以执行到 driver 的 probe 的前提是match 成功也就是device 先存在了再去注册 driver 的情况我们再来看看另外一种情况 5.2、platform_device_register 情况 直接看实现 int platform_device_register(struct platform_device *pdev) {device_initialize(pdev-dev);return platform_device_add(pdev); } EXPORT_SYMBOL_GPL(platform_device_register); 先将 platform_device 的 device 结构初始化然后调用 platform_device_add int platform_device_add(struct platform_device *pdev) {int i, ret 0;if (!pdev)return -EINVAL;if (!pdev-dev.parent)pdev-dev.parent platform_bus;pdev-dev.bus platform_bus_type; ....if (pdev-id ! -1)dev_set_name(pdev-dev, %s.%d, pdev-name, pdev-id);elsedev_set_name(pdev-dev, %s, pdev-name); ....ret device_add(pdev-dev);if (ret 0)return ret;} EXPORT_SYMBOL_GPL(platform_device_add); 设置 bus 为 platform bus type 后算是挂靠到这个 bus 上然后做一些初始化的动作调用到 device_add进入到更底层的设备模块抽象 int device_add(struct device *dev) {struct device *parent NULL;struct class_interface *class_intf;int error -EINVAL;dev get_device(dev);if (!dev)goto done;...if (dev-init_name) {dev_set_name(dev, %s, dev-init_name);dev-init_name NULL;} ...if (!dev_name(dev)) {error -EINVAL;goto name_error;} ...parent get_device(dev-parent);setup_parent(dev, parent);/* use parent numa_node */if (parent)set_dev_node(dev, dev_to_node(parent));/* first, register with generic layer. *//* we require the name to be set before, and pass NULL */error kobject_add(dev-kobj, dev-kobj.parent, NULL);if (error)goto Error;/* notify platform of device entry */if (platform_notify)platform_notify(dev);error device_create_file(dev, uevent_attr);if (error)goto attrError;if (MAJOR(dev-devt)) {error device_create_file(dev, devt_attr);if (error)goto ueventattrError;error device_create_sys_dev_entry(dev);if (error)goto devtattrError;devtmpfs_create_node(dev);} ...error device_add_class_symlinks(dev);if (error)goto SymlinkError;error device_add_attrs(dev);if (error)goto AttrsError;error bus_add_device(dev);if (error)goto BusError;error dpm_sysfs_add(dev);if (error)goto DPMError;device_pm_add(dev);bus_probe_device(dev); ... } 内容较多主要是和底层 kobjectksetparentsys 等等相关操作这里关心到 bus_add_device 函数往期望的 bus 上增加一个 device成功后调用 bus_probe_device void bus_probe_device(struct device *dev) {struct bus_type *bus dev-bus;int ret;if (bus bus-p-drivers_autoprobe) {ret device_attach(dev);WARN_ON(ret 0);} } 这里不用多说了吧调用到了 device_attach和上面的 5.2、platform_driver_register 情况一样形成了匹配后调用了 probe 总体的流程是 platform_device_register - platform_device_add - device_add  - bus_probe_device - driver_attach - __driver_attach - match ? (0 return 1 -) - driver_probe_device (matched) - really_probe - probe 5.3、小结 所以不管是先注册 platform_device 还是 platform_driver只要匹配上了都会去执行到 probe 函数也就是驱动的初始化函数 参考文献 https://blog.csdn.net/Richard_LiuJH/article/details/45825333 https://blog.csdn.net/Richard_LiuJH/article/details/48245715 https://blog.csdn.net/Hansomewang/article/details/78969006 https://blog.csdn.net/fml1997/article/details/77622860 https://blog.csdn.net/thl789/article/details/6723350
http://www.yayakq.cn/news/3583/

相关文章:

  • 微信上开网店怎么开郑州网站优化_郑州网站推广_河南网站建设公司_seo外包顾问服务
  • 网站改版seo群晖wordpress换端口
  • 网站建设流程一般可分为哪几个阶段建设主题网站的顺序是什么样的
  • 长春市建设厅网站采集wordpress整站数据
  • 网站建设首选-云端高科济南赢动网站建设
  • 学院网站建设流程图网站建设最流行语言
  • ui设计与制作西安seo包年服务
  • 关于建立网站的计划四川省凉亭建设工程有限公司网站
  • 静态网页做的网站怎么发到网上个人网站设计论文一万字
  • 电子商务物流网站建设规划方案番禺公司网站建设
  • 网站建设案例代理商天津百度seo排名优化
  • 网站背景居中怎么做分析企业网站建设流程
  • 销售网站建设常遇到的问题小蝌蚪幸福宝入口导航
  • 手机网站设计费用网站托管方案
  • 教做网站群晖 wordpress 慢
  • 齐全的网站建设做微博这样的网站吗
  • 双流县规划建设局网站无锡网站制作一般多少钱
  • python可以做网站模板吗小影wordpress主题
  • 个人网站做淘宝客违规wordpress taxonomy
  • 如何进行网站的宣传和推广设计一个企业网站主页
  • 网站域名 空间申请山东做网站费用
  • 自学网站建设快吗网站开发php还是jsp
  • 三亚文明城市建设服务中心报名网站seo培训机构
  • 北京网站建设市场网站内容 优化
  • 上海网站建设企企业 cms
  • 建网站费用记账wordpress导航栏字体
  • 网站html模板下载青岛哪家公司做网站好
  • 个人可以建门户网站吗网站建设的安全性问题
  • 河南天元建设公司网站山东东营市经济怎么样
  • 主流网站建设做推送实用网站