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

网站策划500字培训如何优化网站

网站策划500字,培训如何优化网站,网页游戏浏览器,企业网站的在线推广方法有哪些嵌入式Linux应用开发-基础知识-第十八章系统对中断的处理② 第十八章 Linux系统对中断的处理 ②18.3 Linux中断系统中的重要数据结构18.3.1 irq_desc数组18.3.2 irqaction结构体18.3.3 irq_data结构体18.3.4 irq_domain结构体18.3.5 irq_chip结构体 18.4 在设备树中指定中断_在… 嵌入式Linux应用开发-基础知识-第十八章系统对中断的处理② 第十八章 Linux系统对中断的处理 ②18.3 Linux中断系统中的重要数据结构18.3.1 irq_desc数组18.3.2 irqaction结构体18.3.3 irq_data结构体18.3.4 irq_domain结构体18.3.5 irq_chip结构体 18.4 在设备树中指定中断_在代码中获得中断18.4.1 设备树里中断节点的语法18.4.1.1 设备树里的中断控制器18.4.1.2 设备树里使用中断 18.4.2 设备树里中断节点的示例18.4.3 在代码中获得中断18.4.3.1 对于 platform_device18.4.3.2 对于 I2C设备、SPI设备18.4.3.3 调用 of_irq_get获得中断号18.4.3.4 对于 GPIO 第十八章 Linux系统对中断的处理 ② 18.3 Linux中断系统中的重要数据结构 本节内容可以从 request_irq(include/linux/interrupt.h)函数一路分析得到。 能弄清楚下面这个图对 Linux中断系统的掌握也基本到位了。 最核心的结构体是 irq_desc之前为了易于理解我们说在 Linux内核中有一个中断数组对于每一个硬件中断都有一个数组项这个数组就是 irq_desc数组。 注意如果内核配置了 CONFIG_SPARSE_IRQ那么它就会用基数树(radix tree)来代替 irq_desc数组。SPARSE的意思是“稀疏”假设大小为 1000的数组中只用到 2个数组项那不是浪费嘛所以在中断比较“稀疏”的情况下可以用基数树来代替数组。 18.3.1 irq_desc数组 irq_desc结构体在 include/linux/irqdesc.h中定义主要内容如下图 每一个 irq_desc数组项中都有一个函数handle_irq还有一个 action链表。要理解它们需要先看中断结构图 外部设备 1、外部设备 n共享一个 GPIO中断 B多个 GPIO中断汇聚到 GIC(通用中断控制器)的 A号中断GIC再去中断 CPU。那么软件处理时就是反过来先读取 GIC获得中断号 A再细分出 GPIO中断 B最后判断是哪一个外部芯片发生了中断。 所以中断的处理函数来源有三 ① GIC的处理函数 假设 irq_desc[A].handle_irq是 XXX_gpio_irq_handler(XXX指厂家)这个函数需要读取芯片的 GPIO控制器细分发生的是哪一个 GPIO中断(假设是 B)再去调用 irq_desc[B]. handle_irq。 注意irq_desc[A].handle_irq细分出中断后 B调用对应的 irq_desc[B].handle_irq。 显然中断 A是 CPU感受到的顶层的中断GIC中断 CPU时CPU读取 GIC状态得到中断 A。 ② 模块的中断处理函数 比如对于 GPIO模块向 GIC发出的中断 B它的处理函数是 irq_desc[B].handle_irq。 BSP开发人员会设置对应的处理函数一般是 handle_level_irq或 handle_edge_irq从名字上看是用来处理电平触发的中断、边沿触发的中断。 注意导致 GPIO中断 B发生的原因很多可能是外部设备 1可能是外部设备 n可能只是某一个设备也可能是多个设备。所以 irq_desc[B].handle_irq会调用某个链表里的函数这些函数由外部设备提供。这些函数自行判断该中断是否自己产生若是则处理。 ③ 外部设备提供的处理函数 这里说的“外部设备”可能是芯片也可能总是简单的按键。它们的处理函数由自己驱动程序提供这是最熟悉这个设备的“人”它知道如何判断设备是否发生了中断如何处理中断。 对于共享中断比如 GPIO中断 B它的中断来源可能有多个每个中断源对应一个中断处理函数。所以 irq_desc[B]中应该有一个链表存放着多个中断源的处理函数。 一旦程序确定发生了 GPIO中断 B那么就会从链表里把那些函数取出来一一执行。 这个链表就是 action链表。 对于我们举的这个例子来说irq_desc数组如下 18.3.2 irqaction结构体 irqaction结构体在 include/linux/interrupt.h中定义主要内容如下图 当调用 request_irq、request_threaded_irq注册中断处理函数时内核就会构造一个 irqaction结构体。在里面保存 name、dev_id等最重要的是 handler、thread_fn、thread。 handler是中断处理的上半部函数用来处理紧急的事情。 thread_fn对应一个内核线程 thread当 handler执行完毕Linux内核会唤醒对应的内核线程。在内核线程里会调用 thread_fn函数。 可以提供 handler而不提供 thread_fn就退化为一般的 request_irq函数。 可以不提供 handler只提供 thread_fn完全由内核线程来处理中断。 也可以既提供 handler也提供 thread_fn这就是中断上半部、下半部。 里面还有一个名为 sedondary的 irqaction结构体它的作用以后再分析。 在 reqeust_irq时可以传入 dev_id为何需要 dev_id作用有 2 ① 中断处理函数执行时可以使用 dev_id ② 卸载中断时要传入 dev_id这样才能在 action链表中根据 dev_id找到对应项 所以在共享中断中必须提供 dev_id非共享中断可以不提供。 18.3.3 irq_data结构体 irq_data结构体在 include/linux/irq.h中定义主要内容如下图 它就是个中转站里面有 irq_chip指针 irq_domain指针都是指向别的结构体。 比较有意思的是 irq、hwirqirq是软件中断号hwirq是硬件中断号。比如上面我们举的例子在 GPIO中断 B是软件中断号可以找到 irq_desc[B]这个数组项GPIO里的第 x号中断这就是 hwirq。 谁来建立 irq、hwirq之间的联系呢由 irq_domain来建立。irq_domain会把本地的 hwirq映射为全局的 irq什么意思比如 GPIO控制器里有第 1号中断UART模块里也有第 1号中断这两个“第 1号中断”是不一样的它们属于不同的“域”──irq_domain。 18.3.4 irq_domain结构体 irq_domain结构体在 include/linux/irqdomain.h中定义主要内容如下图 当我们后面从设备树讲起如何在设备树中指定中断设备树的中断如何被转换为 irq时irq_domain将会起到极大的作为。 这里基于入门的解度简单讲讲在设备树中你会看到这样的属性 interrupt-parent gpio1; interrupts 5 IRQ_TYPE_EDGE_RISING; 它表示要使用 gpio1里的第 5号中断hwirq就是 5。 但是我们在驱动中会使用 request_irq(irq, handler)这样的函数来注册中断irq是什么它是软件中断号它应该从“gpio1的第 5号中断”转换得来。 谁把 hwirq转换为 irq由 gpio1的相关数据结构就是 gpio1对应的 irq_domain结构体。 irq_domain结构体中有一个 irq_domain_ops结构体里面有各种操作函数主要是 ① xlate 用来解析设备树的中断属性提取出 hwirq、type等信息。 ② map 把 hwirq转换为 irq。 18.3.5 irq_chip结构体 irq_chip结构体在 include/linux/irq.h中定义主要内容如下图 这个结构体跟“chip”即芯片相关里面各成员的作用在头文件中也列得很清楚摘录部分如下 * irq_startup: start up the interrupt (defaults to -enable if NULL) * irq_shutdown: shut down the interrupt (defaults to -disable if NULL) * irq_enable: enable the interrupt (defaults to chip-unmask if NULL) * irq_disable: disable the interrupt * irq_ack: start of a new interrupt * irq_mask: mask an interrupt source * irq_mask_ack: ack and mask an interrupt source * irq_unmask: unmask an interrupt source * irq_eoi: end of interrupt 我们在 request_irq后并不需要手工去使能中断原因就是系统调用对应的 irq_chip里的函数帮我们使能了中断。 我们提供的中断处理函数中也不需要执行主芯片相关的清中断操作也是系统帮我们调用 irq_chip中的相关函数。 但是对于外部设备相关的清中断操作还是需要我们自己做的。 就像上面图里的“外部设备 1“、“外部设备 n”外设备千变万化内核里可没有对应的清除中断操作。 18.4 在设备树中指定中断_在代码中获得中断 18.4.1 设备树里中断节点的语法 参考文档 内核 Documentation\devicetree\bindings\interrupt-controller\interrupts.txt 18.4.1.1 设备树里的中断控制器 中断的硬件框图如下 在硬件上“中断控制器”只有 GIC这一个但是我们在软件上也可以把上图中的“GPIO”称为“中断控制器”。很多芯片有多个 GPIO模块比如 GPIO1、GPIO2等等。所以软件上的“中断控制器”就有很多个GIC、GPIO1、GPIO2等等。 GPIO1连接到 GICGPIO2连接到 GIC所以 GPIO1的父亲是 GICGPIO2的父亲是 GIC。 假设 GPIO1有 32个中断源但是它把其中的 16个汇聚起来向 GIC发出一个中断把另外 16个汇聚起来向 GIC发出另一个中断。这就意味着 GPIO1会用到 GIC的两个中断会涉及 GIC里的 2个 hwirq。 这些层级关系、中断号(hwirq)都会在设备树中有所体现。 在设备树中中断控制器节点中必须有一个属性interrupt-controller表明它是“中断控制器”。 还必须有一个属性#interrupt-cells表明引用这个中断控制器的话需要多少个 cell。 #interrupt-cells的值一般有如下取值 ① #interrupt-cells1 别的节点要使用这个中断控制器时只需要一个 cell来表明使用“哪一个中断”。 ② #interrupt-cells2 别的节点要使用这个中断控制器时需要一个 cell来表明使用“哪一个中断” 还需要另一个 cell来描述中断一般是表明触发类型 第 2个 cell的 bits[3:0] 用来表示中断触发类型(trigger type and level flags) 1 low-to-high edge triggered上升沿触发 2 high-to-low edge triggered下降沿触发 4 active high level-sensitive高电平触发 8 active low level-sensitive低电平触发 示例如下 vic: intc10140000 { compatible arm,versatile-vic; interrupt-controller; #interrupt-cells 1; reg 0x10140000 0x1000; }; 如果中断控制器有级联关系下级的中断控制器还需要表明它的“interrupt-parent”是谁用了interrupt-parent”中的哪一个“interrupts”请看下一小节。 18.4.1.2 设备树里使用中断 一个外设它的中断信号接到哪个“中断控制器”的哪个“中断引脚”这个中断的触发方式是怎样的 这 3个问题在设备树里使用中断时都要有所体现。 ① interrupt-parentXXXX 你要用哪一个中断控制器里的中断 ② interrupts 你要用哪一个中断 Interrupts里要用几个 cell由 interrupt-parent对应的中断控制器决定。在中断控制器里有 “#interrupt-cells”属性它指明了要用几个 cell来描述中断。 比如 i2c7000c000 { gpioext: gpio-adnp41 { compatible ad,gpio-adnp; interrupt-parent gpio; interrupts 160 1; gpio-controller; #gpio-cells 1; }; ...... }; interrupt-controller; #interrupt-cells 2; ③ 新写法interrupts-extended 一个“interrupts-extended”属性就可以既指定“interrupt-parent”也指定“interrupts”比如 interrupts-extended intc1 5 1, intc2 1 0; 18.4.2 设备树里中断节点的示例 以 xxxxxx_IMX6ULL开发板为例在 arch/arm/boot/dts目录下可以看到 2个文件imx6ull.dtsi、xxxxxx_imx6ull-14x14.dts把里面有关中断的部分内容抽取出来。 从设备树反推 IMX6ULL的中断体系如下比之前的框图多了一个“GPC INTC” GPC INTC的英文是General Power Controller, Interrupt Controller。它提供中断屏蔽、中断状态查询功能实际上这些功能在 GIC里也实现了个人觉得有点多余。除此之外它还提供唤醒功能这才是保留它的原因。 18.4.3 在代码中获得中断 之前我们提到过设备树中的节点有些能被转换为内核里的 platform_device有些不能回顾如下 A. 根节点下含有 compatile属性的子节点会转换为 platform_device B. 含有特定 compatile属性的节点的子节点会转换为 platform_device 如果一个节点的 compatile属性它的值是这 4者之一 “simple-bus”,“simple-mfd”,“isa”,“arm,amba-bus”, 那么它的子结点(需含 compatile属性)也可以转换为 platform_device。 C. 总线 I2C、SPI节点下的子节点不转换为 platform_device 某个总线下到子节点应该交给对应的总线驱动程序来处理, 它们不应该被转换为 platform_device。 18.4.3.1 对于 platform_device 一个节点能被转换为 platform_device如果它的设备树里指定了中断属性那么可以从 platform_device中获得“中断资源”函数如下可以使用下列函数获得 IORESOURCE_IRQ资源即中断号 /** * platform_get_resource - get a resource for a device * dev: platform device * type: resource type // 取哪类资源IORESOURCE_MEM、IORESOURCE_REG * // IORESOURCE_IRQ等 * num: resource index // 这类资源中的哪一个 */ struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num); 18.4.3.2 对于 I2C设备、SPI设备 对于 I2C设备节点I2C总线驱动在处理设备树里的 I2C子节点时也会处理其中的中断信息。一个I2C设备会被转换为一个 i2c_client结构体中断号会保存在 i2c_client的 irq成员里代码如下(drivers/i2c/i2c-core.c) 对于 SPI设备节点SPI总线驱动在处理设备树里的 SPI子节点时也会处理其中的中断信息。一个SPI设备会被转换为一个 spi_device结构体中断号会保存在 spi_device的 irq成员里代码如下(drivers/spi/spi.c) 18.4.3.3 调用 of_irq_get获得中断号 如果你的设备节点既不能转换为 platform_device它也不是 I2C设备不是 SPI设备那么在驱动程序中可以自行调用 of_irq_get函数去解析设备树得到中断号。 18.4.3.4 对于 GPIO 参考drivers/input/keyboard/gpio_keys.c 可以使用 gpio_to_irq或 gpiod_to_irq获得中断号。 举例假设在设备树中有如下节点 gpio-keys { compatible gpio-keys; pinctrl-names default; user { label User Button; gpios gpio5 1 GPIO_ACTIVE_HIGH; gpio-key,wakeup; linux,code KEY_1; }; }; 那么可以使用下面的函数获得引脚和 flag button-gpio of_get_gpio_flags(pp, 0, flags); bdata-gpiod gpio_to_desc(button-gpio); 再去使用 gpiod_to_irq获得中断号 irq gpiod_to_irq(bdata-gpiod);
http://www.yayakq.cn/news/1968/

相关文章:

  • 水果网店网站建设策划书wordpress 浏览器不居中
  • 网站怎么添加背景wordpress的vps建站流程
  • 建材网站建设方案上海虹桥站
  • 西乡城建局网站脚本外链平台
  • 湖南seo网站策划一键生成ppt免费
  • 一级a做爰片凤凰网站wix和WordPress做小程序
  • 网站建设挣钱网站建设工程师工资
  • 做网站和微信公众号如何招生建筑资料网
  • 山东住房和建设庭官网站官投资管理公司注册条件
  • 网站怎么做跳转链接制作网站品牌公司
  • 中国建设银行官网站账户商品网络广告创意策划
  • linux系统网站架构最新网站开发技术
  • 石家庄做网站邮箱电话南京网站建设哪里好
  • 营口网站建设哪家好淘宝客网站都用什么做
  • 宁波企业建站系统深圳市住房和建设局网站-%3e认租申请
  • 网站建设猫腻展台设计网站都有哪些
  • 建设厅公积金中心网站it外包兼职
  • 南京网站建设培训班服装设计师的个人网站
  • php外贸网站陕西省建设八大员官方网站
  • 盘锦网站建设平台黄页网站推广下载免费
  • 宁波网站建设制作哪家好网站做备案到哪去
  • 医院网站建设标书网站建设 云计算
  • 烟台汽车租赁网站建设南京做网站哪家好
  • 铝木门窗网站建设专业瓷砖美缝网站怎么做
  • 合肥高新城建设计院网站徐州列表网
  • 新手学做网站推荐软件免费建材网站模板
  • 团购网站建设报价有源代码怎么制作网站
  • 哪个网站有做阿里巴巴流量一个网页前端和后端
  • 网站建设源码下载网站开发人员 组织架构
  • 网络服务器搭建与配置济南做网站优化的公司