Changes between Initial Version and Version 1 of OpenWrt/gpio

10/22/2017 05:28:45 AM (2 years ago)



  • OpenWrt/gpio

    v1 v1  
     3= OpenWrt GPIO =
     4This page discusses aspects of GPIO particular to the OpenWrt BSP. For GPIO hardware and Linux basics please refer to the [wiki:gpio gpio] page.
     7== Linux gpiolib / gpio class ==
     8The standard Linux way of working with GPIO's uses a gpio class accessed via {{{/sys/class/gpio/*}}} implemented through {{{gpiolib}}} (CONFIG_GPIOLIB, {{{drivers/gpio/gpiolib*}}}). For userspace access this requires sysfs kernel support (CONFIG_SYSFS) and the sysfs filesystem mounted which is standard for most linux systems including the Gateworks OpenWrt based BSP).
     10This framework allows kernel board-support to define GPIO configuration (direction, direction-changeable, user-friendly name, state, and userspace configurable). The benefit of this standard method is:
     11 1. its a linux standard
     12 2. it allows you to configure GPIO's in such a way that users don't have the ability to change them to invalid states per hardware design (although OpenWrt {{{gpioctl}}} defeats this protection)
     13 3. it allows you to name gpio's with a user-friendly name
     15For details on using the Linux gpio class from userspace see the [wiki:gpio#gpiolib gpio] page.
     18== OpenWrt gpioctl - NOW DEPRECATED ==
     19The older method of controlling GPIO's used by OpenWrt was the {{{gpioctl}}} userspace utility and the kernel driver ({{{package/feeds/packages/gpiotoggling}}}). This was is an OpenWrt creation (as opposed to a 'linux standard' driver/API). It has the benefit (or downside depending on your point of view) of having 'full control' over the GPIO's even if the user should not. It was created at a time where linux-gpio was changing and lacked some standardization.
     21The downside of this application/API:
     22 1. it is not linux standard (It has been removed from current OpenWrt trunk and thus won't be present in future Gateworks firmware)
     23 2. it does not allow you to determine the current configuration mode of a pin (input/output)
     24 3. it is not as easy to script (need to use sed/awk/grep)
     25 4. it can override GPIO configuration in cases where board-support does not wish to allow you to do so
     27This driver/application can be useful however if a GPIO is not configured/exported correctly in the kernel and it can co-exist just fine with the more standard gpio-class mechanism shown below.
     29Example usage:
     32# configure gpio8 as an input
     33gpioctl dirin 8
     35# get current state of gpio8
     36gpioctl get 8
     38# configure gpio8 as an output
     39gpioctl dirout 8
     41# set gpio8 state
     42gpioctl set 8 ;# high
     43gpioctl clear 8 ;# low
     48== OpenWrt init script for configuring GPIO ==
     49If you wish to configure a GPIO differently from its power-on state, bootloader config state (if any), kernel config state (if any), you may do so in userspace. A common way to control board initialization is through init scripts.
     51An example OpenWrt init-script that runs only at 'boot' time:
     52 * {{{/etc/init.d/gpio}}}
     55#!/bin/sh /etc/rc.common
     56# Copyright (C) 2006
     59boot() {
     60    [ -d /sys/class/gpio ] && {
     61        # Custom GPIO Configuration:
     62        # GW2382 - steer USB from FP to PCIe:
     63        echo 0 > /sys/class/gpio/gpio10/value
     64    }
     67 * to enable make sure this script is executable and enabled via:
     70chmod +x /etc/init.d/gpio
     71/etc/init.d/gpio enable
     75== OpenWrt gpio-button-hotplug driver ==
     76Our modern OpenWrt based BSP's use OpenWrt {{{procd}}} as PID1. One of {{{procd}}}'s features is to catch messages from the kernel and act upon them, much in the way a conventional linux system uses a hotplug helper and udev. The {{{/etc/hotplug.json}}} file configures how various events are handled:
     77 * using makedev to create device nodes in /dev on 'add' events and removing the nodes on 'remove' events
     78 * facilitate firmware loading
     79 * calling {{{/sbin/hotplug-call}}} on platform subsystem events
     80 * calling {{{/etc/rc.button/$BUTTON}}} on button events
     81 * calling {{{/sbin/hotplug-call}}} on various subsystem events (such as net, input, usb, block, atm, tty, button)
     83Button events:
     84 - {{{/sbin/hotplug-call}}} will have the following defined:
     85  - {{{BUTTON}}} - button name
     86  - {{{ACTION}}} - pressed|released
     87  - {{{SEQNUM}}} - a numeric value that increments with the event message
     88  - {{{SEEN}}} - number of seconds since last button event from driver
     89   * this can be used to determine how long a button has been 'held' for 'released' events. If a button is released and {{{SEEN=8}}} it has been held for 8 seconds
     91The {{{gpio-button-hotplug}}} driver is the Linux kernel driver that creates hotplug events for GPIO based buttons. The {{{gpio-button-hotplug}}} out-of-tree driver is an OpenWrt custom driver that takes the place of the in-kernel {{{gpio-keys}}} (KEYBOARD_GPIO) and {{{gpio_keys_polled}}} (KEYBOARD_GPIO_POLLED) drivers and instead of emiting linux input events it emits uevent messages to the button subsystem which tie into the OpenWrt hotplug daemon.
     92Note that for Ventana this uses the {{{gpio_keys}}} device-tree node to map gpio-240 to the {{{user_pb}}} button event.
     94=== Gateworks Button Hotplug package ===
     95The Gateworks [ button-hotplug-gw] package installs the {{{/etc/hotplug.d/button/00-button}}} handler which does the following using UCI configuration for one or more buttons:
     96 * catching multiple successive button events (ie 3x press/release)
     97 * min and max hold times (ie catch a button release after being held for 10 secs)
     99Example configuration ({{{/etc/config/system}}}):
     102# catch BTN_0 pressed and released 3 times in quick succession (held for <1 sec each time):
     103config button
     104        option button 'BTN_0'
     105        option action 'released'
     106        option handler 'logger BTN_0 pressed: 3x'
     107        option repeat '3'
     109# catch BTN_0 released after behind held for 0 to 3 seconds
     110config button
     111        option button 'BTN_0'
     112        option action 'released'
     113        option handler 'logger BTN_0 pressed: 0-3s'
     114        option min '0'
     115        option max '3'
     117# catch BTN_0 released after behind held for 8 to 10 seconds
     118config button
     119        option button 'BTN_0'
     120        option action 'released'
     121        option handler 'logger BTN_0 pressed: 8-10s'
     122        option min '5'
     123        option max '20'
     125 * Note that the {{{logread}}} application can be used to read the output of the system log. By default {{{logger}}} will not send info to the serial console:
     128logread -f # show all new log activity
     131Note that to use the user pushbutton present on the front panel of most Gateworks boards, you must configure the Gateworks System Controller (GSC) to not hard-reset the board on a button press:
     134i2cset -f -y 0 0x20 0 0x00 # disable pushbutton hard reset
     135i2cset -f -y 0 0x20 11 0xff # enable all interrupts
     138Refer to the [wiki:gsc#pushbutton GSC pushbutton] wiki section for information on properly configuring your board for pushbutton events and the [wiki:gsc#IRQ_GPIO_CHANGE GSC IRQ_GPIO_CHANGE] wiki section for information on GSC interrupts.
     140==== Factory Reset ====
     141In our latest [ OpenWrt branch], we have added a factory reset handler through the above-mentioned button handler to factory reset the board. On first boot, the system uci entries default to the following:
     144> uci show system
     149system.@button[0].handler='logger BTN_0 pressed'
     159From the above, we can see that to invoke the factory reset, the pushbutton must be held for a minimum of 15s, to a maximum of 999s. This will invoke the function "factory_reset" which can be found in {{{/etc/hotplug.d/button/factory_reset}}}. The script will attempt to write to the console and log that a factory reset is occurring, as well as attempt to take over the user LEDs to make it a solid 'red' color. Change the {{{uci}}} entries to match your desired outcome.
     161Please note that at the very least, both the IRQ_PB and IRQ_GPIO_CHANGE must be enabled in the gsc:
     164i2cset -f -y 0 0x20 11 0x11 # enable IRQ_PB and IRQ_GPIO_CHANGE
     168== GPIO based LEDs ==
     169GPIO's that drive LED's are controlled via the [wiki:gpio#led_class Linux led class]. OpenWrt has a UCI method of configuring LED's on boot via {{{/etc/config/system}}}.
     171By default, the Gateworks OpenWrt BSP installs the '''userled-heartbeat'' package which sets the '''heartbeat''' trigger on the '''user1''' led. On most boards this is the green LED on the front-panel bi-color LED and results in the LED blinking green twice a second like a heartbeat.
     173This is accomplished from the following configuration in {{{/etc/config/system}}}:
     176config led
     177        option default '0'
     178        option name 'heartbeat'
     179        option sysfs 'user1'
     180        option trigger 'heartbeat'
     184See also:
     185 * [wiki:gpio#led_class Linux LED class]