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

给vps安装wordpress中山网站百度优化

给vps安装wordpress,中山网站百度优化,网络策划营销方案,电子商务网站的建设目标1. GPIO子系统视频概述 1.1 GPIO子系统的作用 芯片内部有很多引脚#xff0c;这些引脚可以接到GPIO模块#xff0c;也可以接到I2C等模块。 通过Pinctrl子系统来选择引脚的功能(mux function)、配置引脚#xff1a; 当一个引脚被复用为GPIO功能时#xff0c;我们可以去设… 1. GPIO子系统视频概述 1.1 GPIO子系统的作用 芯片内部有很多引脚这些引脚可以接到GPIO模块也可以接到I2C等模块。 通过Pinctrl子系统来选择引脚的功能(mux function)、配置引脚 当一个引脚被复用为GPIO功能时我们可以去设置它的方向、设置/读取它的值。 GPIO名为General Purpose Input/Output通用目的输入/输出就是常用的引脚。 GPIO可能是芯片自带的也可能通过I2C、SPI接口扩展 GPIO有一些通用功能、通用属性。 1.2 通用功能 可以设为输出让它输出高低电平 可以设为输入读取引脚当前电平 可以用来触发中断 对于芯片自带的GPIO它的访问时很快的可以在获得spinlocks的情况下操作它。 但是对于通过I2C、SPI等接口扩展的GPIO访问它们时可能导致休眠所以这些GPIO Expander就不能在获得spinlocks的情况下使用。 1.3 通用属性 Active-High and Active-Low 以LED为例需要设置GPIO电平。但是有些电路可能是高电平点亮LED有些是低电平点亮LED。 可以使用如下代码 gpiod_set_value(gpio, 1); // 输出高电平点亮LED gpiod_set_value(gpio, 0); // 输出低电平点亮LED 对应同一个目标点亮LED对于不同的LED就需要不同的代码原因在于上面的代码中1、0表示的是物理值。 如果能使用逻辑值同样的逻辑值在不同的配置下输出对应的物理值就可以保持代码一致比如 gpiod_set_value(gpio, 1); // 输出逻辑1// 在Active-High的情况下它会输出高电平// 在Active-Low的情况下它会输出低电平 Open Drain and Open Source 有多个GPIO驱动同时驱动一个电路时就需要设置Open Drain或Open Source。 Open Drain引脚被设置为低电平时才会驱动电路典型场景是I2C接口。 Open Source引脚被设置为高电平时才会驱动电路 1.4 GPIO子系统的作用 管理GPIO既能支持芯片本身的GPIO也能支持扩展的GPIO。 提供统一的、简便的访问接口实现输入、输出、中断。 2. GPIO子系统层次与数据结构 2.1 GPIO子系统的层次 2.1.1 层次 2.1.2 GPIOLIB向上提供的接口 概述向上接口主要有几类获得GPIO,设置方向读值写值释放GPIO; 在Linux内核中GPIOLIB 是一个通用的 GPIO (通用输入输出) 抽象层它提供了一组 API 供驱动程序和用户空间程序使用。以下是 GPIOLIB 向上提供的主要接口及其说明 gpio_request: 请求一个GPIO引脚。如果成功内核将保留该引脚供请求者使用并返回一个唯一的GPIO编号。 gpio_free: 释放一个之前请求的GPIO引脚使其可供其他驱动程序使用。 gpio_direction_input: 将GPIO引脚配置为输入模式。 gpio_direction_output: 将GPIO引脚配置为输出模式并可选地设置初始输出值。 gpio_get_value: 读取GPIO引脚的输入值。 gpio_set_value: 写入GPIO引脚的输出值。 gpio_get_value_cansleep: 与gpio_get_value类似但此函数可以在睡眠上下文中使用。 gpio_set_value_cansleep: 与gpio_set_value类似但此函数可以在睡眠上下文中使用。 gpio_cansleep: 检查对GPIO引脚的操作是否可以在睡眠上下文中执行。 gpio_to_irq: 将GPIO引脚转换为中断号以便可以请求中断。 irq_to_gpio: 将中断号转换回GPIO引脚。 gpiochip_add: 注册一个gpio_chip结构体它描述了一组GPIO引脚及其操作函数。 gpiochip_remove: 移除之前注册的gpio_chip。 gpiochip_line_config: 配置gpio_chip中的特定引脚。 gpiochip_request_own: 请求对gpio_chip中的引脚的所有权。 gpiochip_request_unown: 释放对gpio_chip中的引脚的所有权。 gpiochip_set: 为gpio_chip中的多个引脚设置值。 gpiochip_clear: 清除gpio_chip中的多个引脚的值。 gpiochip_set_direction: 为gpio_chip中的多个引脚设置方向。 gpiochip_get_direction: 获取gpio_chip中引脚的方向。 这些接口为内核中的驱动程序提供了一种通用的方式来操作硬件GPIO引脚同时隐藏了具体的硬件细节。此外GPIOLIB 还提供了一些辅助函数用于处理GPIO引脚的请求和释放以及配置引脚的输入/输出模式。 2.1.3 GPIOLIB向下提供的接口 概述获得引脚释放引脚配置引脚读取\写入值清除引脚获取地址获取标签信息配置中断 chip.request: 用于请求一个 GPIO 引脚。硬件驱动程序需要实现此函数来请求并分配一个 GPIO 引脚。 chip.free: 用于释放一个之前请求的 GPIO 引脚。硬件驱动程序需要实现此函数来释放并回收该引脚。 chip.direction_input: 配置 GPIO 引脚为输入模式。硬件驱动需要实现此函数来设置引脚方向。 chip.direction_output: 配置 GPIO 引脚为输出模式并可设置初始输出值。硬件驱动需要实现此函数。 chip.get: 读取 GPIO 引脚的值。硬件驱动需要实现此函数来返回引脚的当前状态。 chip.set: 向 GPIO 引脚写入高电平。硬件驱动需要实现此函数来设置引脚状态。 chip.clear: 向 GPIO 引脚写入低电平。硬件驱动需要实现此函数来清除引脚状态。 chip.set_config: 配置 GPIO 引脚的参数如上拉/下拉、驱动强度等。硬件驱动需要实现此函数。 chip.to_irq: 如果支持将 GPIO 引脚转换为中断号。硬件驱动需要实现此函数。 chip.dbg_show: 用于调试目的显示 GPIO 引脚的状态。硬件驱动可以提供此函数。 chip.label: 获取 GPIO 芯片的标签。硬件驱动需要提供此函数。 chip.base: 获取 GPIO 芯片的基地址通常用于芯片注册。 chip.ngpio: 获取 GPIO 芯片支持的 GPIO 引脚数量。 chip.parent: 获取 GPIO 芯片的父设备通常用于设备树集成。 chip.of_node: 获取 GPIO 芯片的设备树节点。 chip.of_xlate: 用于设备树中 GPIO 引脚的转换硬件驱动需要实现此函数。 这些接口定义在 struct gpio_chip 结构体中硬件平台的 GPIO 驱动程序需要填充这个结构体并实现相应的函数。这样GPIOLIB 可以与底层硬件交互而上层的驱动程序和应用程序则可以使用 GPIOLIB 提供的通用接口来操作 GPIO 引脚。 2.2 重要的3个核心数据结构 记住GPIO Controller的要素这有助于理解它的驱动程序 一个GPIO Controller里有多少个引脚有哪些引脚 需要提供函数设置引脚方向、读取/设置数值 需要提供函数把引脚转换为中断 以Linux面向对象编程的思想一个GPIO Controller必定会使用一个结构体来表示这个结构体必定含有这些信息 GPIO引脚信息 控制引脚的函数 中断相关的函数 2.2.1 gpio_device 每个GPIO Controller用一个gpio_device来表示 里面每一个gpio引脚用一个gpio_desc来表示 gpio引脚的函数(引脚控制、中断相关)都放在gpio_chip里 2.2.2 gpio_chip 我们并不需要自己创建gpio_device编写驱动时要创建的是gpio_chip里面提供了 控制引脚的函数 中断相关的函数 引脚信息支持多少个引脚各个引脚的名字 实现GPIOLIB向下提供的接口函数  2.2.3 gpio_desc  我们去使用GPIO子系统时首先是获得某个引脚对应的gpio_desc。 gpio_device表示一个GPIO Controller里面支持多个GPIO。 在gpio_device中有一个gpio_desc数组每一引脚有一项gpio_desc。 2.3  怎么编写GPIO Controller驱动程序 分配、设置、注册gpioc_chip结构体示例drivers\gpio\gpio-74x164.c 3. 编写一个虚拟GPIO控制器的驱动程序 概述核心分配/设置/注册一个gpio_chip结构体。 头文件支持定义全局变量结构体指针chip 定义一个全局变量用于模拟GPIO的 #include linux/module.h // 模块化编程支持 #include linux/err.h // 错误处理 #include linux/init.h // 模块初始化和清理宏 #include linux/io.h // IO操作 #include linux/mfd/syscon.h // 系统控制 #include linux/of.h // 设备树操作 #include linux/of_device.h // 设备树设备操作 #include linux/of_address.h // 设备树地址解析 #include linux/gpio/consumer.h // GPIO消费者 #include linux/gpio/driver.h // GPIO驱动 #include linux/slab.h // 内存分配 #include linux/regmap.h // 寄存器映射static struct gpio_chip * g_virt_gpio; // 定义一个全局的gpio_chip指针 static int g_gpio_val 0; // 定义一个全局变量用于模拟GPIO值 定义设备树匹配表设置GPIO属性-方向输入和输出获取GPIO的值设置GPIO的值 // 设备树匹配表 static const struct of_device_id virtual_gpio_of_match[] {{ .compatible 100ask,virtual_gpio, },{ }, };// 设置GPIO方向为输出 static int virt_gpio_direction_output(struct gpio_chip *gc,unsigned offset, int val) {printk(set pin %d as output %s\n, offset, val ? high : low);return 0; }// 设置GPIO方向为输入 static int virt_gpio_direction_input(struct gpio_chip *chip,unsigned offset) {printk(set pin %d as input\n, offset);return 0; }// 获取GPIO值 static int virt_gpio_get_value(struct gpio_chip *gc, unsigned offset) {return (g_gpio_val (1offset)) ? 1 : 0; }// 设置GPIO值 static void virt_gpio_set_value(struct gpio_chip *gc,unsigned offset, int val) {if (val)g_gpio_val | (1 offset);elseg_gpio_val ~(1 offset); } 平台驱动探测函数分配设置设置函数设置值注册在内核中添加身份信息 // 平台设备探测函数 static int virtual_gpio_probe(struct platform_device *pdev) {int ret;printk(KERN_INFO %s %s %d\n, __FILE__, __FUNCTION__, __LINE__);/* 1. 分配gpio_chip */g_virt_gpio devm_kzalloc(pdev-dev, sizeof(*g_virt_gpio), GFP_KERNEL);/* 2. 设置gpio_chip *//* 2.1 设置函数 */g_virt_gpio-label pdev-name;g_virt_gpio-direction_output virt_gpio_direction_output;g_virt_gpio-direction_input virt_gpio_direction_input;g_virt_gpio-get virt_gpio_get_value;g_virt_gpio-set virt_gpio_set_value;g_virt_gpio-parent pdev-dev;g_virt_gpio-owner THIS_MODULE;/* 2.2 设置base、ngpio值 */g_virt_gpio-base -1;ret of_property_read_u32(pdev-dev.of_node, ngpios, g_virt_gpio-ngpio);/* 3. 注册gpio_chip */ret devm_gpiochip_add_data(g_virt_gpio, NULL);return 0; } 定义平台设备移除函数定义虚拟GPIO驱动结构体定义入口函数注册平台驱动出口函数反注册平台驱动 // 平台设备移除函数 static int virtual_gpio_remove(struct platform_device *pdev) {printk(KERN_INFO %s %s %d\n, __FILE__, __FUNCTION__, __LINE__);return 0; }// 虚拟GPIO驱动结构体 static struct platform_driver virtual_gpio_driver {.probe virtual_gpio_probe,.remove virtual_gpio_remove,.driver {.name 100ask_virtual_gpio,.of_match_table of_match_ptr(virtual_gpio_of_match),} };/* 1. 入口函数 */ static int __init virtual_gpio_init(void) { printk(KERN_INFO %s %s %d\n, __FILE__, __FUNCTION__, __LINE__);/* 1.1 注册一个platform_driver */return platform_driver_register(virtual_gpio_driver); }/* 2. 出口函数 */ static void __exit virtual_gpio_exit(void) {printk(KERN_INFO %s %s %d\n, __FILE__, __FUNCTION__, __LINE__);/* 2.1 反注册platform_driver */platform_driver_unregister(virtual_gpio_driver); }module_init(virtual_gpio_init); module_exit(virtual_gpio_exit);MODULE_LICENSE(GPL); 4. GPIO子系统与Pinctrl子系统的交互 4.1 使用GPIO前应该设置Pinctrl 假设使用这个虚拟的GPIO Controller的pinA来控制LED 要使用pinA来控制LED首先要通过Pinctrl子系统把它设置为GPIO功能然后才能设置它为输出引脚、设置它的输出值。 所以在设备树文件里应该添加Pinctrl的内容 virtual_pincontroller {compatible 100ask,virtual_pinctrl;myled_pin: myled_pin {functions gpio;groups pin0;configs 0x11223344;}; };gpio_virt: virtual_gpiocontroller {compatible 100ask,virtual_gpio;gpio-controller;#gpio-cells 2;ngpios 4; };myled {compatible 100ask,leddrv;led-gpios gpio_virt 0 GPIO_ACTIVE_LOW;pinctrl-names default;pinctrl-0 myled_pin; }; 这段代码包含了三个主要部分分别定义了三个不同的设备节点它们在设备树Device Tree中用于描述硬件设备的配置和它们之间的关系。以下是对每个部分的解释 virtual_pincontroller 节点 compatible 属性指定了设备的兼容字符串用于确定使用哪个驱动程序。myled_pin 是一个子节点代表一个具体的引脚配置。functions 属性定义了引脚的复用功能这里是 gpio表示该引脚被用作通用输入输出。groups 属性指定了引脚组这里是 pin0。configs 属性提供了引脚的配置参数这里使用了一个32位的十六进制数 0x11223344。 gpio_virt 节点 同样使用 compatible 属性来指定驱动程序。gpio-controller 表示这是一个GPIO控制器。#gpio-cells 属性定义了每个GPIO引脚需要多少个单元来描述这里是 2通常表示一个单元用于GPIO号另一个用于标志。ngpios 属性定义了控制器拥有的GPIO引脚数量这里是 4表示有4个GPIO引脚。这个节点可能与 virtual_pincontroller 节点相关联用于控制引脚的GPIO功能。 myled 节点 compatible 属性指定了LED驱动的兼容字符串。led-gpios 属性定义了控制LED的GPIO引脚格式为 gpio_virt 0 GPIO_ACTIVE_LOW表示使用 gpio_virt 控制器的第0号引脚且为低电平有效。pinctrl-names 和 pinctrl-0 属性用于指定引脚控制的名称和默认配置这里引用了 myled_pin 节点。 设备树节点之间的关系 gpio_virt 节点定义了一个GPIO控制器它可能控制着一些物理或虚拟的GPIO引脚。myled 节点定义了一个LED设备它使用 gpio_virt 控制器的第0号引脚来控制LED的开关。virtual_pincontroller 节点定义了一个虚拟的引脚控制器它可能用于更复杂的引脚控制逻辑比如配置引脚的复用功能、配置参数等。 代码作用 这段设备树配置告诉内核如何初始化和配置相关的硬件设备特别是如何将特定的GPIO引脚配置为控制LED并指定了引脚的其他配置参数。当内核启动时它将解析设备树中的这些节点并根据这些信息加载相应的驱动程序初始化硬件设备。 在嵌入式Linux系统中设备树是一种重要的机制用于描述硬件设备的配置特别是在没有BIOS或UEFI等传统固件的情况下。设备树允许内核以一种硬件无关的方式来初始化和控制硬件设备。 但是很多芯片并不要求在设备树中把把引脚复用为GPIO功能。 比如STM32MP157在它的设备树工具STM32CubeMX即使把引脚配置为GPIO功能它也不会在设备树中出现。 原因在于GPIO走了后门。 现实的芯片中并没有Pinctrl这样的硬件它的功能大部分是在GPIO模块中实现的。 Pinctrl是一个软件虚拟处理的概念它的实现本来就跟GPIO密切相关。 甚至一些引脚默认就是GPIO功能。 按理说 一个引脚可能被用作GPIO也可能被用作I2CGPIO和I2C这些功能时相同低位的。 要用作GPIO需要先通过Pinctrl把引脚复用为GPIO功能。 但是Pinctrl和GPIO关系密切当你使用gpiod_get获得GPIO引脚时它就偷偷地通过Pinctrl把引脚复用为GPIO功能了。 4.2 GPIO和Pinctrl的映射关系 从上图可知 左边的Pinctrl支持8个引脚在Pinctrl的内部编号为0~7 图中有2个GPIO控制器 GPIO0内部引脚编号为0~3假设在GPIO子系统中全局编号为100~103 GPIO1内部引脚编号为0~3假设在GPIO子系统中全局编号为104~107 假设我们要使用pin1_1应该这样做 根据GPIO1的内部编号1可以换算为Pinctrl子系统中的编号5 使用Pinctrl的函数把第5个引脚配置为GPIO功能 数据结构 4.3 GPIO调用Pinctrl的过程 GPIO子系统中的request函数用来申请某个GPIO引脚 它会导致Pinctrl子系统中的这2个函数之一被调用pmxops-gpio_request_enable或pmxops-request 调用关系如下 gpiod_getgpiod_get_indexdesc of_find_gpio(dev, con_id, idx, lookupflags);ret gpiod_request(desc, con_id ? con_id : devname);ret gpiod_request_commit(desc, label);if (chip-request) {ret chip-request(chip, offset);} 这段代码片段是Linux内核中使用GPIO描述符gpiodAPI处理GPIO线的一部分。这个API用于以更抽象的方式处理GPIO允许更好的硬件抽象使跨不同硬件平台的GPIO操作变得更容易。以下是每个函数的作用详解。 - gpiod_get_index 函数可能是获取特定索引GPIO线GPIO描述符的包装器或过程的一部分。 - of_find_gpio 函数使用设备树根据设备和连接ID找到GPIO描述符。 - gpiod_request 函数使用描述符请求GPIO线并为GPIO线的使用请求一个标签。 - gpiod_request_commit 函数提交GPIO请求使GPIO线准备好使用。 - 如果GPIO芯片有一个自定义的请求函数 (chip-request)这里会调用它来执行任何必要的硬件特定设置。 这段代码片段是通常涉及配置GPIO线例如将其设置为输入或输出配置上拉/下拉电阻等并然后用于其预定目的例如从传感器读取输入驱动LED等的更大过程中的一部分。确切的实现细节可以根据硬件平台和正在使用的GPIO线的具体要求而有所不同。   我们编写GPIO驱动程序时所设置chip-request函数一般直接调用gpiochip_generic_request它导致Pinctrl把引脚复用为GPIO功能。 gpiochip_generic_request(struct gpio_chip *chip, unsigned offset)pinctrl_request_gpio(chip-gpiodev-base offset)ret pinctrl_get_device_gpio_range(gpio, pctldev, range); // gpio是引脚的全局编号/* Convert to the pin controllers number space */pin gpio_to_pin(range, gpio);ret pinmux_request_gpio(pctldev, range, pin, gpio);ret pin_request(pctldev, pin, owner, range); 代码流程解释 gpiochip_generic_request 函数被调用以请求一个GPIO。pinctrl_request_gpio 函数使用设备的基地址和GPIO偏移量来计算全局GPIO编号。pinctrl_get_device_gpio_range 函数根据全局GPIO编号获取引脚控制器设备和GPIO的编号范围。通过gpio_to_pin将全局GPIO编号转换为引脚控制器的编号空间。pinmux_request_gpio 函数请求引脚复用确保引脚可以被用作所需的功能。pin_request 函数在引脚控制器中实际请求引脚保留它并标记为已使用。 这个过程是Linux内核中处理GPIO请求的标准方式确保了在不同硬件平台上对GPIO的请求是统一和一致的。通过这种方式驱动程序可以请求和使用GPIO而不必担心底层硬件的具体细节。 Pinctrl子系统中的pin_request函数就会把引脚配置为GPIO功能 static int pin_request(struct pinctrl_dev *pctldev,int pin, const char *owner,struct pinctrl_gpio_range *gpio_range) {const struct pinmux_ops *ops pctldev-desc-pmxops;/** If there is no kind of request function for the pin we just assume* we got it by default and proceed.*/if (gpio_range ops-gpio_request_enable)/* This requests and enables a single GPIO pin */status ops-gpio_request_enable(pctldev, gpio_range, pin);else if (ops-request)status ops-request(pctldev, pin);elsestatus 0; } 这段代码是一个名为 pin_request 的静态函数它的作用是请求reserve一个特定的引脚pin以供驱动程序或其他用途使用。 这个 pin_request 函数是引脚控制子系统中的一个关键组件它确保了对特定引脚的独占访问防止多个驱动程序同时使用同一个引脚。这是嵌入式系统和硬件抽象中常见的需求特别是在多个硬件设备可能需要使用相同物理引脚的情况下。
http://www.hkea.cn/news/14272153/

相关文章:

  • 建网站多少钱可以卖货的旅游电子商务 网站建设
  • asp怎么新建网站安 网站建设
  • 高校学校网站建设海南省交通建设局网站首页
  • 长沙专业外贸网站建设网站开发全程实例课本代码
  • 凡科网官方网站重庆网站公司设计
  • 张店网站建设价格网上做兼职正规网站有哪些
  • 静态网站怎么建设哪些行业做网站多
  • 山东城乡建设厅网站怎样做国际网站平台
  • 删除西部数码网站管理助手在线制作网站 如何禁止蜘蛛收录网站
  • 合肥公司门户网站制作网站建设协议书模板 完整版
  • wordpress做网站怎么样温州网站建设和运营
  • 怎样建官方网站商务网站需求说明书
  • 建设企业网站平台书本翻页 网站模板
  • 研学网站平台建设方案上海知名的网站建设公
  • asp网站如何建设长沙百度快速排名优化
  • 找外包公司做网站给源码吗wordpress 外网访问
  • 商业网站 技术网站横幅背景图片
  • 做招聘网站的怎么让人注册简历wordpress设置导航条
  • 做网站要钱吗?企业vi设计主要包括哪些内容
  • 情侣博客网站模板下载青岛网站定制开发
  • 自己的电脑做服务器搭建网站企业网站如何宣传
  • 没有网站怎么推广网站中文通用网址域名
  • 遵义祥云平台网站建设企业网站cms程序
  • 网站开发使用的技术有哪些自己制作头像app软件
  • python做音乐网站软件外包怎么样
  • 中国网站访问量排行可以兑换微信红包的捕鱼游戏
  • 做基网站wordpress 漏洞 利用
  • 无锡网站商城建设网站设计需要什么技术
  • 杭州老牌的网站建设新闻页面设计
  • wordpress安装脚本seo技术最新黑帽