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

wordpress源代码怎么修改有利于优化的网站模板

wordpress源代码怎么修改,有利于优化的网站模板,wordpress主题 苏醒,昆明营销型网站建设从 4.8 版开始#xff0c;Linux 内核引入了基于字符设备的新用户空间 API#xff0c;用于管理和控制 GPIO#xff08;通用输入/输出#xff09;。这篇文章介绍了新接口的基本原理#xff0c;并通过一个简单的教程/示例演示了如何使用新 API 控制 GPIO。 教程中使用的硬件是… 从 4.8 版开始Linux 内核引入了基于字符设备的新用户空间 API用于管理和控制 GPIO通用输入/输出。这篇文章介绍了新接口的基本原理并通过一个简单的教程/示例演示了如何使用新 API 控制 GPIO。 教程中使用的硬件是 Raspberry Pi 3B但代码是通用的可用于任何嵌入式硬件。 From the version 4.8, the Linux kernel introduces a new user space API based on character devices for managing and controlling GPIOs ( General-Purpose Input/Output). This post presents the basic of the new interface as well as a simple tutorial/example to demonstrate how to use the new API to control GPIOs. The hardware used in the tutorial is the Raspberry Pi 3B but the code is generic and can be used on any embedded hardware. The old user space interface 在 Linux 内核 4.8 之前在用户空间管理 GPIO 的唯一接口是 sysfs 接口。GPIO 通过 /sys/class/gpio 中的导出文件进行配置和控制。可通过该接口执行 GPIO 的基本操作 通过 /sys/class/gpio/export 导出 GPIO 通过 /sys/class/gpio/export 配置 GPIO 方向输入/输出 通过 /sys/class/gpio/gpioX/direction 配置 GPIO 方向输入/输出 通过 /sys/class/gpio/gpioX/value 读写 GPIO 值 该接口简单易用但也有一些缺点 缺乏批量 GPIO 读写功能GPIO 配置选项有限例如无法将 GPIO 配置为低电平有效、漏极开路、开源等。 当两个或多个进程同时访问同一个 GPIO 时可能会出现竞赛条件问题。 从 GPIO 轮询事件不可靠 等等。 Before the Linux kernel 4.8, the only interface to manage GPIO in user space is the sysfs interface. GPIOs are configured and controlled via exported files in /sys/class/gpio. Basic GPIO operations that can be performed via this interface: * Export a GPIO via /sys/class/gpio/export * Configure the GPIO direction (input/output) via: /sys/class/gpio/gpioX/direction * Read/write GPIO value via /sys/class/gpio/gpioX/value This interface is simple and easy to use but it has some drawbacks: * Lack of bulk GPIO reads and writes, GPIO configuration options are limited (for example: unable to configure a GPIO as Active low, open drain, open source etc.) * Race condition problems may occur when two or more processes accessing the same GPIO at the same time. * Polling event from GPIO is not reliable * etc. The new Character Device interface 自 4.8 版起Linux 内核引入了基于字符设备的新用户空间 GPIO 接口。用户空间的 GPIO 控制器接口以字符设备的形式提供 /dev/gpiochipX。基本的文件操作如 open()、read()、write()、ioctl()、poll()、close()都可以用来与 GPIO 控制器交互。 本节将详细介绍如何使用这一新 API通过 ioctl 接口配置和控制 GPIO。 基本上要与 GPIO 控制器交互我们首先需要使用传统的文件打开操作打开字符设备 Since version 4.8, Linux kernel introduces a new user-space GPIO interface based on character device. Interface to the GPIO controller is available in user space in form of a character device: /dev/gpiochipX. Basic file operations such as open(), read(), write(), ioctl(), poll(), close() can be used to interact with the GPIO controller. This section will detail on how to use this new API to configure and control GPIO via the ioctl interface. Basically, to interact with the GPIO controller, we first need to open character device using the traditional file open operation: // include API header for the new interface #include linux/gpio.h #include unistd.h #include fcntl.h #include string.h #include errno.h #include sys/ioctl.h #include stdint.h #include stdlib.h #define DEV_NAME /dev/gpiochip0 void func() { int fd, ret; fd open(DEV_NAME, O_RDONLY); if (fd 0) { printf(Unabled to open %%s: %%s, dev_name, strerror(errno)); return; } /* control GPIO here, such as: - configure - read - write - polling */ (void)close(fd); } 请注意我们以只读模式打开字符设备 /dev/gpiochip0所有 GPIO 控制操作都将在打开的文件描述符 fd 上执行。 Note that we open the character device /dev/gpiochip0 in read only mode, all GPIO control operations will be performed on the opened file descriptor fd. 本教程包括以下操作 读取 GPIO 芯片和线路信息 GPIO 读写操作批量模式。 GPIO 事件轮询 This tutorial covers the following operations: * GPIO chip and lines information reading * GPIO read and write operations (in bulk mode). * GPIO event polling 通过 IOCTL 接口获取 GPIO 芯片信息 GPIO 芯片信息存储在一个结构类型为 gpiochip_info 的结构中可通过 IOCTL GPIO_GET_CHIPINFO_IOCTL 请求进行查询 Get GPIO chip information via the IOCTL interface GPIO chip information is stored in a structure of type struct gpiochip_info and can be queried via the IOCTL GPIO_GET_CHIPINFO_IOCTL request: struct gpiochip_info info; struct gpioline_info line_info; int fd, ret; // open the device fd open(DEV_NAME, O_RDONLY); if (fd 0) { printf(Unabled to open %%s: %%s, dev_name, strerror(errno)); return; } // Query GPIO chip information ret ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, info); if (ret -1) { printf(Unable to get chip info from ioctl: %%s, strerror(errno)); close(fd); return; } printf(Chip name: %%s\n, info.name); printf(Chip label: %%s\n, info.label); printf(Number of lines: %%d\n, info.lines); 在第 13 行我们使用 IOCTL 接口GPIO_GET_CHIPINFO_IOCTL 请求从内核中查询芯片信息。结构信息包含芯片名称、芯片标签以及重要的 GPIO 线路数。在此基础上我们可以通过对文件描述符发出 IOCTL GPIO_GET_LINEINFO_IOCTL 请求进一步查询各 GPIO 线路的状态。每个 GPIO 的线路信息都存储在一个结构类型为 struct gpioline_info 的结构中 On line 13 we query the chip info from the kernel using the IOCTL interface (GPIO_GET_CHIPINFO_IOCTL request). The structure info contains the chip name, the chip label, and importantly the number of GPIO lines. From here, we can further query the state of each GPIO lines by issuing the IOCTL GPIO_GET_LINEINFO_IOCTL request on the file descriptor. The line information for each GPIO is stored in a structure of type: struct gpioline_info: struct gpioline_info line_info; for (int i 0; i info.lines; i) { line_info.line_offset i; ret ioctl(fd, GPIO_GET_LINEINFO_IOCTL, line_info); if (ret -1) { printf(Unable to get line info from offset %%d: %%s, i, strerror(errno)); } else { printf(offset: %%d, name: %%s, consumer: %%s. Flags:\t[%%s]\t[%%s]\t[%%s]\t[%%s]\t[%%s]\n, i, line_info.name, line_info.consumer, (line_info.flags GPIOLINE_FLAG_IS_OUT) ? OUTPUT : INPUT, (line_info.flags GPIOLINE_FLAG_ACTIVE_LOW) ? ACTIVE_LOW : ACTIVE_HIGHT, (line_info.flags GPIOLINE_FLAG_OPEN_DRAIN) ? OPEN_DRAIN : ..., (line_info.flags GPIOLINE_FLAG_OPEN_SOURCE) ? OPENSOURCE : ..., (line_info.flags GPIOLINE_FLAG_KERNEL) ? KERNEL : ); } } 在第 4 行我们将 line_info 结构的 line_offset 属性设置为要查询的 GPIO 线路/偏移量然后通过 GPIO_GET_LINEINFO_IOCTL 请求调用 ioctl 函数。 下面是在 Raspberry Pi 3B 上执行代码的输出示例 On line 4, we set the line_offset property of the structure line_info to the GPIO line/offset that we want to query before calling the ioctl function with the GPIO_GET_LINEINFO_IOCTL request. Below is the example output of the code executed on a Raspberry Pi 3B: Chip name: gpiochip0 Chip label: pinctrl-bcm2835 Number of lines: 54 offset: 0, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 1, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 2, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 3, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 4, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 5, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 6, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 7, name: , consumer: spi0 CS1. Flags:    [OUTPUT]    [ACTIVE_LOW]    [...]    [...]    [KERNEL] offset: 8, name: , consumer: spi0 CS0. Flags:    [OUTPUT]    [ACTIVE_LOW]    [...]    [...]    [KERNEL] offset: 9, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 10, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 11, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 12, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 13, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 14, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 15, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 16, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 17, name: , consumer: ads7846_pendown. Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [KERNEL] offset: 18, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 19, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 20, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 21, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 22, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 23, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 24, name: , consumer: dc. Flags:    [OUTPUT]    [ACTIVE_HIGHT]    [...]    [...]    [KERNEL] offset: 25, name: , consumer: reset. Flags:    [OUTPUT]    [ACTIVE_LOW]    [...]    [...]    [KERNEL] offset: 26, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 27, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 28, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 29, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 30, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 31, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 32, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 33, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 34, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 35, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 36, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 37, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 38, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 39, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 40, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 41, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 42, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 43, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 44, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 45, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 46, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 47, name: , consumer: . Flags:    [OUTPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 48, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 49, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 50, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 51, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 52, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] offset: 53, name: , consumer: . Flags:    [INPUT]    [ACTIVE_HIGHT]    [...]    [...]    [] 问题GPIO 偏移bcm2835与 raspberry Pi 的物理引脚输出之间的映射关系是什么 如果我们看一下树莓派的引脚布局 这里的偏移量对应于上述模式中的 BCMx 引脚。例如偏移量 17 对应 BCM 17物理引脚 11。 Question: what is exactly the mapping between GPIO offsets (bcm2835) and the physical pinout of the raspberry Pi ? Well, if we look at the Raspberry pinout: The offsets here correspond to the BCMx pins on the schema above. For example the offset 17 correspond to the BCM 17 (physical pin 11) (批量通过 IOCTL 接口向输出 GPIO 写值 假设我们要将引脚 11 和 13BCM 17 和 BCM 27配置为 OUTPUT并在引脚 11 上写入高电平 (1)在引脚 13 上写入低电平 (0)。 新的 API 允许以批量模式执行配置、读取和写入操作它可以在单个 IOCTL 请求中处理多个 GPIO 线路。 (Bulk) Writing values to output GPIOs via the IOCTL interface Let say we want to configure pin 11 and 13 (BCM 17 and BCM 27) as OUTPUT and we want to write HIGH (1) on pin 11 and LOW (0) on pin 13. The new API allows to perform configuration, read and write operation in bulk mode, it can handle multiple GPIO lines in a single IOCTL request. 基本上要向 GPIO 写入数值我们首先需要将其配置为 OUTPUT。具体方法如下 在结构类型为 struct gpiohandle_request 的结构中填写配置值 通过 IOCTL 接口向 GPIO 控制器发出 GPIO_GET_LINEHANDLE_IOCTL请求获得已配置 GPIO 的线路句柄 Basically, to write values to GPIOs, we first need to configured them as OUTPUTs. This can be done by : * Filling configuration values in a struct of type struct gpiohandle_request * Issuing a GPIO_GET_LINEHANDLE_IOCTL to the GPIO controller via the IOCTL interface to request a lines handle of the configured GPIOs // open the device fd ... ... struct gpiohandle_request rq; rq.lineoffsets[0] 17; rq.lineoffsets[1] 27; rq.lines 2; rq.flags GPIOHANDLE_REQUEST_OUTPUT; ret ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, rq); close(fd); if (ret -1) { printf(Unable to line handle from ioctl : %%s, strerror(errno)); close(fd); return; } 在 rq 结构中我们需要指定要配置的行数偏移 17 和偏移 27以及行标志。在本例中我们使用 GPIOHANDLE_REQUEST_OUTPUT 标志将两行17 和 27配置为输出。 如果 IOCTL GPIO_GET_LINEHANDLE_IOCTL 请求成功单行句柄将以文件描述符rq.fd的形式设置到结构 rqstruct gpiohandle_request的属性 fd 中。该文件描述符用于向配置的 GPIO 写入值。现在可以安全关闭设备文件 (fd) 描述符。 要向两个 GPIO 写入数值只需将数值填入一个 struct gpiohandle_data 类型的结构然后在行句柄文件描述符上使用该结构执行一个 IOCTL GPIOHANDLE_SET_LINE_VALUES_IOCTL请求 In the structure rq, we need to specify which lines (offset 17, offset 27) and the number of lines we want to configured as well as the lines flags. In this case we use the flag GPIOHANDLE_REQUEST_OUTPUT to configure the two lines (17 and 27) as outputs. If the IOCTL GPIO_GET_LINEHANDLE_IOCTL request successes, a single lines handle is set to the property fd of the structure rq (struct gpiohandle_request) in form of a file descriptor (rq.fd). This file descriptor should be used to write values to the configured GPIOs. The device file (fd) descriptor can now be safety closed. To write values to the two GPIOs, simply fill the values to a structure of type struct gpiohandle_data, then perform a IOCTL GPIOHANDLE_SET_LINE_VALUES_IOCTL request with this structure on the lines handle file descriptor struct gpiohandle_data data; data.values[0] 1; // HIGH offset 17 data.values[1] 0; // LOW offset 27 ret ioctl(rq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, data); if (ret -1) { printf(Unable to set line value using ioctl : %%s, strerror(errno)); } // do something else close(rq.fd); (Bulk) reading input GPIOs values via the IOCTL interface [(批量通过 IOCTL 接口读取输入 GPIO 值] GPIO 的读取操作遵循与写入操作相同的原则。所需的修改如下: 用 GPIOHANDLE_REQUEST_INPUT 代替 GPIOHANDLE_REQUEST_OUTPUT 用 GPIOHANDLE_GET_LINE_VALUES_IOCTL 代替 GPIOHANDLE_SET_LINE_VALUES_IOCTL The GPIOs reading operation follows the same principle as the writing operation. The modifications necessary are to: * Replace GPIOHANDLE_REQUEST_OUTPUT with GPIOHANDLE_REQUEST_INPUT * Replace GPIOHANDLE_SET_LINE_VALUES_IOCTL with GPIOHANDLE_GET_LINE_VALUES_IOCTL struct gpiohandle_request rq; struct gpiohandle_data data; int fd, ret; // open the device fd ... ... rq.lineoffsets[0] 17; rq.lineoffsets[1] 27; rq.flags GPIOHANDLE_REQUEST_INPUT; rq.lines 2; ret ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, rq); close(fd); if (ret -1) { printf(Unable to get line handle from ioctl : %%s, strerror(errno)); return; } ret ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, data); if (ret -1) { printf(Unable to get line value using ioctl : %%s, strerror(errno)); } else { printf(Value of GPIO at offset 17: %%d and offset 27: %%d\n, data.values[0], data.values[1]); } close(rq.fd); GPIO event polling 新 API 为使用传统轮询 API文件描述符轮询 GPIO 事件如上升沿、下降沿或两个沿提供了一种方便的方法。GPIO 事件轮询有两个基本步骤 以文件描述符的形式通过 IOCTL 接口请求 GPIO 线路上的事件句柄 对该文件描述符执行传统轮询 下面的代码段请求偏移量 17BCM 17处 GPIO 的事件句柄。 The new API provides a convenient way to poll GPIO events such as raising edge, falling edge or both edges using the traditional polling API (on file descriptors). Two basic steps for GPIO event polling: * Request the event handle on a GPIO line in form of a file descriptor (via the IOCTL interface) * Perform traditional polling on that file descriptor The following snippet requests a event handle on the GPIO at offset 17 (BCM 17). #include sys/poll.h ... struct gpioevent_request rq; int fd, ret; // open the device fd ... rq.lineoffset 17; rq.eventflags GPIOEVENT_EVENT_RISING_EDGE; ret ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, rq); close(fd); if (ret -1) { printf(Unable to get line event from ioctl : %%s, strerror(errno)); close(fd); return; } 请注意在第 10 行和第 11 行我们配置了事件句柄以监听偏移 17 处 GPIO 上的上升沿事件 (GPIOEVENT_EVENT_RISING_EDGE)。 如果请求成功行事件文件描述符将被设置为结构 rqstruct gpioevent_request的 fd 属性。可以对该文件描述符 (rq.fd) 执行传统的轮询操作。 Note that on lines 10 and 11, we configure the event handle to listen to the rising edge event (GPIOEVENT_EVENT_RISING_EDGE) on the GPIO at offset 17. If the request successes, the line event file descriptor is set to the fd property of the structure rq (struct gpioevent_request). The traditional polling operation can the be performed on this file descriptor (rq.fd). struct pollfd pfd; pfd.fd rq.fd; pfd.events POLLIN; ret poll(pfd, 1, -1); if (ret -1) { printf(Error while polling event from GPIO: %%s, strerror(errno)); } else if (pfd.revents POLLIN) { printf(Rising edge event on GPIO offset: %%d, of %%s\n, offset, dev_name); } close(rq.fd); 上面的代码只是简单地阻塞直到事件被触发轮询超时设置为-1。请注意轮询 API 可以同时轮询多个文件描述符因此可以轮询多个 GPIO 线路上的事件。 The code above simply blocks until the event is triggered (polling timeout set to -1). Note that the polling API can poll multiple file descriptors at the same time, thus, it is able to poll events on multiple GPIO lines. Final code 下面是本帖中介绍的所有 GPIO 操作的完整工作代码 Bellow is the complete working code of all GPIO operations presented in this post: #include linux/gpio.h #include unistd.h #include fcntl.h #include string.h #include errno.h #include sys/ioctl.h #include stdio.h #include stdint.h #include getopt.h #include stdlib.h #include sys/poll.h typedef enum { APP_OPT_GPIO_LIST, APP_OPT_GPIO_READ, APP_OPT_GPIO_WRITE, APP_OPT_GPIO_POLL, APP_OPT_UNKNOWN } app_mode_t; typedef struct { char *dev; int offset; uint8_t val; app_mode_t mode; } app_opt_t; static void gpio_list(const char *dev_name) { struct gpiochip_info info; struct gpioline_info line_info; int fd, ret; fd open(dev_name, O_RDONLY); if (fd 0) { printf(Unabled to open %%s: %%s, dev_name, strerror(errno)); return; } ret ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, info); if (ret -1) { printf(Unable to get chip info from ioctl: %%s, strerror(errno)); close(fd); return; } printf(Chip name: %%s\n, info.name); printf(Chip label: %%s\n, info.label); printf(Number of lines: %%d\n, info.lines); for (int i 0; i info.lines; i) { line_info.line_offset i; ret ioctl(fd, GPIO_GET_LINEINFO_IOCTL, line_info); if (ret -1) { printf(Unable to get line info from offset %%d: %%s, i, strerror(errno)); } else { printf(offset: %%d, name: %%s, consumer: %%s. Flags:\t[%%s]\t[%%s]\t[%%s]\t[%%s]\t[%%s]\n, i, line_info.name, line_info.consumer, (line_info.flags GPIOLINE_FLAG_IS_OUT) ? OUTPUT : INPUT, (line_info.flags GPIOLINE_FLAG_ACTIVE_LOW) ? ACTIVE_LOW : ACTIVE_HIGHT, (line_info.flags GPIOLINE_FLAG_OPEN_DRAIN) ? OPEN_DRAIN : ..., (line_info.flags GPIOLINE_FLAG_OPEN_SOURCE) ? OPENSOURCE : ..., (line_info.flags GPIOLINE_FLAG_KERNEL) ? KERNEL : ); } } close(fd); } static void gpio_write(const char *dev_name, int offset, uint8_t value) { struct gpiohandle_request rq; struct gpiohandle_data data; int fd, ret; printf(Write value %%d to GPIO at offset %%d (OUTPUT mode) on chip %%s\n, value, offset, dev_name); fd open(dev_name, O_RDONLY); if (fd 0) { printf(Unabled to open %%s: %%s, dev_name, strerror(errno)); return; } rq.lineoffsets[0] offset; rq.flags GPIOHANDLE_REQUEST_OUTPUT; rq.lines 1; ret ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, rq); close(fd); if (ret -1) { printf(Unable to line handle from ioctl : %%s, strerror(errno)); return; } data.values[0] value; ret ioctl(rq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, data); if (ret -1) { printf(Unable to set line value using ioctl : %%s, strerror(errno)); } else { usleep(2000000); } close(rq.fd); } static void gpio_read(const char *dev_name, int offset) { struct gpiohandle_request rq; struct gpiohandle_data data; int fd, ret; fd open(dev_name, O_RDONLY); if (fd 0) { printf(Unabled to open %%s: %%s, dev_name, strerror(errno)); return; } rq.lineoffsets[0] offset; rq.flags GPIOHANDLE_REQUEST_INPUT; rq.lines 1; ret ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, rq); close(fd); if (ret -1) { printf(Unable to get line handle from ioctl : %%s, strerror(errno)); return; } ret ioctl(rq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, data); if (ret -1) { printf(Unable to get line value using ioctl : %%s, strerror(errno)); } else { printf(Value of GPIO at offset %%d (INPUT mode) on chip %%s: %%d\n, offset, dev_name, data.values[0]); } close(rq.fd); } static void gpio_poll(const char *dev_name, int offset) { struct gpioevent_request rq; struct pollfd pfd; int fd, ret; fd open(dev_name, O_RDONLY); if (fd 0) { printf(Unabled to open %%s: %%s, dev_name, strerror(errno)); return; } rq.lineoffset offset; rq.eventflags GPIOEVENT_EVENT_RISING_EDGE; ret ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, rq); close(fd); if (ret -1) { printf(Unable to get line event from ioctl : %%s, strerror(errno)); close(fd); return; } pfd.fd rq.fd; pfd.events POLLIN; ret poll(pfd, 1, -1); if (ret -1) { printf(Error while polling event from GPIO: %%s, strerror(errno)); } else if (pfd.revents POLLIN) { printf(Rising edge event on GPIO offset: %%d, of %%s\n, offset, dev_name); } close(rq.fd); } static void help(const char *app) { fprintf(stderr, Usage: %%s options dev_name.\n Options:\n \t -i: print gpio chip info\n \t -r offset: Read GPIO value at offset (INPUT mode)\n \t -w offset: Write GPIO value at offset (OUTPUT mode). Option -v should be set\n \t -v 0|1: value that should be written to the GPIO, used only with option -w\n \t -p offset: Polling raising event on the GPIO at offset\n, app); } int main(int argc, char *const *argv) { int ret; app_opt_t opt; opt.val 0; opt.dev NULL; opt.mode APP_OPT_UNKNOWN; while ((ret getopt(argc, argv, lr:w:p:v:)) ! -1) { switch (ret) { case l: opt.mode APP_OPT_GPIO_LIST; break; case r: opt.mode APP_OPT_GPIO_READ; opt.offset atoi(optarg); break; case w: opt.mode APP_OPT_GPIO_WRITE; opt.offset atoi(optarg); break; case v: opt.val (uint8_t)atoi(optarg); break; case p: opt.mode APP_OPT_GPIO_POLL; opt.offset atoi(optarg); break; default: help(argv[0]); return -1; } } if (optind argc || opt.mode APP_OPT_UNKNOWN) { help(argv[0]); return -1; } opt.dev argv[optind]; switch (opt.mode) { case APP_OPT_GPIO_LIST: gpio_list(opt.dev); break; case APP_OPT_GPIO_WRITE: gpio_write(opt.dev, opt.offset, opt.val); break; case APP_OPT_GPIO_READ: gpio_read(opt.dev, opt.offset); break; case APP_OPT_GPIO_POLL: gpio_poll(opt.dev, opt.offset); break; default: help(argv[0]); return -1; } return 0; } 参考 Control GPIO using the new Linux user space GPIO API (lxsang.me)
http://www.w-s-a.com/news/664642/

相关文章:

  • 个人网站建设实验心得seo课程简介
  • 免费自助建站系统下载推广app网站
  • 用scala做的网站标题关键词优化技巧
  • 百度网站评级wordpress忘记admin
  • 建筑标准下载网站263企业邮箱 登陆
  • 旅游房地产网站建设德保网站建设
  • 网站高端建设wordpress订单系统
  • 建设网站成本增加网站备案
  • 行业网站建设方案百度云图片转wordpress
  • 如何建设网站推广平台营销客户管理软件
  • 网站制作南宁如何撰写一个网站规划建设方案
  • 建站网站和维护需要会什么杭州人防质监站网址
  • 唐山免费做网站莱芜吧贴吧最新消息
  • 韶关市建设工程造价网站网络营销的平台有哪些
  • 网站建设费大概多少钱成都网站建设低价
  • 做表格的网站东莞常平房价
  • 国家级建设网站高密做网站哪家强价位
  • 江西省新的建设厅三类人员网站做标记网站
  • 做最精彩绳艺网站产品设计培训
  • 营销型网站建设品牌深圳网络推广最新招聘
  • 单位网站等级保护必须做吗广州app软件开发公司
  • 免费flash网站模板怎么仿网站链接
  • 泉州网站建设哪家好平面设计转行做什么比较好
  • 忘记网站备案账号设计一个网站
  • 国内购物网站哪个最好海珠营销网站建设报价
  • 小型网站搭建logo免费制作
  • dede 网站模板哈尔滨房产信息网官方网站
  • 设计师个人作品集模板班级优化大师网页版登录
  • 高端网站建设教学网站开发前期准备工作
  • 网站评论列表模板设计官网的