Openwrt中LED的控制

由于公司没有使用openwrt的平台,而是使用LSDK的平台,所以好多东西都需要移植。只是内核版本升级到3.3.8,故需要把openwrt中应用层的接口移植到LSDK的平台上,所以简单研究了一下LED的控制流程。部分总结如下,后续继续补充:

主要涉及到的几个模块:

linux/kernels/linux-3.3.8/drivers/leds/ledtrig-gpio.ko
linux/kernels/linux-3.3.8/drivers/leds/ledtrig-timer.ko
linux/kernels/linux-3.3.8/drivers/leds/leds-gpio.ko
linux/kernels/linux-3.3.8/drivers/leds/ledtrig-default-on.ko
linux/kernels/linux-3.3.8/drivers/leds/ledtrig-netdev.ko

GPIO初始化文件:

linux/kernels/linux-3.3.8/arch/mips/ath79/mach-ap147.c

配置文件:

/etc/config/system
/etc/init.d/led
root@openwrt:# cat /etc/init.d/led 
#!/bin/sh /etc/rc.common
# Copyright (C) 2008 OpenWrt.org

START=96

load_led() {
    local name
    local sysfs
    local trigger
    local dev
    local mode
    local default
    local delayon
    local delayoff
    local interval

    config_get sysfs $1 sysfs
    config_get name $1 name "$sysfs"
    config_get trigger $1 trigger "none"
    config_get dev $1 dev
    config_get mode $1 mode "link"
    config_get_bool default $1 default "nil"
    config_get delayon $1 delayon
    config_get delayoff $1 delayoff
    config_get interval $1 interval "50"
    config_get port_state $1 port_state
    config_get delay $1 delay "150"
    config_get message $1 message ""

    if [ "$trigger" = "rssi" ]; then
        # handled by rssileds userspace process
        return
    fi

    [ -e /sys/class/leds/${sysfs}/brightness ] && {
        echo "setting up led ${name}"
        [ "$default" != nil ] && {
            [ $default -eq 1 ] &&
                echo 1 >/sys/class/leds/${sysfs}/brightness
            [ $default -eq 1 ] ||
                echo 0 >/sys/class/leds/${sysfs}/brightness
        }
        echo $trigger > /sys/class/leds/${sysfs}/trigger
        case "$trigger" in
        "netdev")
            [ -n "$dev" ] && {
                echo $dev > /sys/class/leds/${sysfs}/device_name
                echo $mode > /sys/class/leds/${sysfs}/mode
            }
            ;;

        "timer")
            [ -n "$delayon" ] && \
                echo $delayon > /sys/class/leds/${sysfs}/delay_on
            [ -n "$delayoff" ] && \
                echo $delayoff > /sys/class/leds/${sysfs}/delay_off
            ;;

        "usbdev")
            [ -n "$dev" ] && {
                echo $dev > /sys/class/leds/${sysfs}/device_name
                echo $interval > /sys/class/leds/${sysfs}/activity_interval
            }
            ;;

        "port_state")
            [ -n "$port_state" ] && \
                echo $port_state > /sys/class/leds/${sysfs}/port_state
            ;;

        "morse")
            echo $message > /sys/class/leds/${sysfs}/message
            echo $delay > /sys/class/leds/${sysfs}/delay
            ;;

        switch[0-9]*)
            local port_mask

            config_get port_mask $1 port_mask
            [ -n "$port_mask" ] && \
                echo $port_mask > /sys/class/leds/${sysfs}/port_mask
            ;;
        esac
    }
}

start() {
    [ -e /sys/class/leds/ ] && {
        config_load system
        config_foreach load_led led
    }
}
root@openwrt:# cat /etc/config/system
# Heartbeat led
config 'led'
    option 'sysfs'      'wrt160nl:amber:wps'
    option 'trigger'    'heartbeat'

#WLAN led
config 'led' 'wlan_led'
        option 'name'           'WLAN'
        option 'sysfs'          'tl-wr1043nd:green:wlan'
        option 'trigger'        'netdev'
        option 'dev'            'wlan0'
        option 'mode'           'link tx rx'

#3G led
#The 3G LED lits up in blue when an USB-dongle properly registers with the #3G/EDGE/GPRS network. Tested on Asus's WL-330N3G router.

config 'led'
        option 'name'           '3G'
        option 'sysfs'          'asus:blue:3g'
        option 'trigger'        'netdev'
        option 'dev'            '3g-wan'
        option 'mode'           'link'

#Timer led - 500ms ON, 2000ms OFF
config 'led'
    option 'sysfs'      'wrt160nl:blue:wps'
    option 'trigger'    'timer'
    option 'delayon'    '500'
    option 'delayoff'   '2000'

1. GPIO口注册

修改对应的参考板mach文件即可,如linux/kernels/linux-3.3.8/arch/mips/ath79/mach-ap147.c。
1)、定义对应的GPIO口:

#define AP147_GPIO_LED_WLAN     12
#define AP147_GPIO_LED_WLAN_V2      4
#define AP147_GPIO_LED_SYS      0
#define AP147_GPIO_LED_SYS_V2       1
#define AP147_GPIO_LED_SIG1     1
#define AP147_GPIO_LED_SIG2     2
#define AP147_GPIO_LED_SIG3     3
#define AP147_GPIO_LED_NET      4

#define AP147_GPIO_LED_WAN      16
#define AP147_GPIO_LED_WAN_V2       2
#define AP147_GPIO_LED_LAN1     16
#define AP147_GPIO_LED_LAN1_V2      15
#define AP147_GPIO_LED_LAN2     15
#define AP147_GPIO_LED_LAN2_V2      16
#define AP147_GPIO_LED_LAN3     14
#define AP147_GPIO_LED_LAN3_V2      0
#define AP147_GPIO_LED_LAN4     11
#define AP147_GPIO_LED_LAN4_V2      3

#define AP147_GPIO_BTN_WPS      17
#define AP147_GPIO_BTN_WPS_V2       14

#define AP147_KEYS_POLL_INTERVAL    20  /* msecs */
#define AP147_KEYS_DEBOUNCE_INTERVAL    (3 * AP147_KEYS_POLL_INTERVAL)

#define AP147_MAC0_OFFSET       0
#define AP147_MAC1_OFFSET       6
#define AP147_WMAC_CALDATA_OFFSET   0x1000

#define AP147_MAX_LED_WPS_GPIOS         6
#define AP147_MAX_BOARD_VERSION         2

#define AP147_V2_ID         17
#define AP147_WMAC1_CALDATA_OFFSET  0x5000
#define BOARDID_OFFSET          0x20

#define BOARD_V1        0
#define BOARD_V2        1

2)、注册:

static struct gpio_led ap147_leds_gpio[] __initdata = {
    {
        .name       = "ap147:green:status",
        .gpio       = AP147_GPIO_LED_SYS,
        .active_low = 1,
    },
    {
        .name       = "ap147:green:sig1",
        .gpio       = AP147_GPIO_LED_SIG1,
        .active_low = 1,
    },
    {
        .name       = "ap147:green:sig2",
        .gpio       = AP147_GPIO_LED_SIG2,
        .active_low = 1,
    },
    {
        .name       = "ap147:green:sig3",                                                                                                                                                                    
        .gpio       = AP147_GPIO_LED_SIG3,
        .active_low = 1,
    },
    {
        .name       = "ap147:green:net",
        .gpio       = AP147_GPIO_LED_NET,
        .active_low = 1,
    },
    {
        .name       = "ap147:green:wlan",
        .gpio       = AP147_GPIO_LED_WLAN,
        .active_low = 1,
    }
};

static struct gpio_keys_button ap147_gpio_keys[] __initdata = {
    {
        .desc       = "WPS button",
        .type       = EV_KEY,
        .code       = BTN_0,
        .debounce_interval = AP147_KEYS_DEBOUNCE_INTERVAL,
        .gpio       = AP147_GPIO_BTN_WPS,
        .active_low = 1,
    },
};

static void __init ap147_gpio_led_setup(int board_version)
{
    ath79_gpio_direction_select(ap147_gpios[board_version][WAN], true);
    ath79_gpio_direction_select(ap147_gpios[board_version][LAN1], true);
    ath79_gpio_direction_select(ap147_gpios[board_version][LAN2], true);
    ath79_gpio_direction_select(ap147_gpios[board_version][LAN3], true);
    ath79_gpio_direction_select(ap147_gpios[board_version][LAN4], true);

    ath79_gpio_output_select(ap147_gpios[board_version][WAN],
            QCA953X_GPIO_OUT_MUX_LED_LINK5);
    ath79_gpio_output_select(ap147_gpios[board_version][LAN1],
            QCA953X_GPIO_OUT_MUX_LED_LINK1);
    ath79_gpio_output_select(ap147_gpios[board_version][LAN2],
            QCA953X_GPIO_OUT_MUX_LED_LINK2);
    ath79_gpio_output_select(ap147_gpios[board_version][LAN3],
            QCA953X_GPIO_OUT_MUX_LED_LINK3);
    ath79_gpio_output_select(ap147_gpios[board_version][LAN4],
            QCA953X_GPIO_OUT_MUX_LED_LINK4);

    if (board_version == BOARD_V2) {
        ap147_leds_gpio[0].active_low = 0;
        ap147_leds_gpio[0].gpio = AP147_GPIO_LED_SYS_V2;
        ap147_leds_gpio[1].gpio = AP147_GPIO_LED_WLAN_V2;
        ap147_gpio_keys[0].gpio = AP147_GPIO_BTN_WPS_V2;
    }
    ath79_register_leds_gpio(-1, ARRAY_SIZE(ap147_leds_gpio),
            ap147_leds_gpio);
    ath79_register_gpio_keys_polled(-1, AP147_KEYS_POLL_INTERVAL,
            ARRAY_SIZE(ap147_gpio_keys),
            ap147_gpio_keys);
}

static void __init ap147_setup(void)
{
    u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);

    u8 board_id = *(u8 *) (art + AP147_WMAC1_CALDATA_OFFSET + BOARDID_OFFSET);
    pr_info("AP147 Reference Board Id is %d\n",(u8)board_id);
    ath79_register_m25p80(NULL);

    if (board_id == AP147_V2_ID) {
        /* Disabling the JTAG due to conflicting GPIO's.
         * Can be re-enabled dynamically by writing appropriate
         * value to GPIO_FUNCTION_ADDRESS register
         */
        ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE);
        ap147_gpio_led_setup(BOARD_V2);
    } else {
        ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE);
        ap147_gpio_led_setup(BOARD_V1);
    }

    ath79_register_usb();
    ath79_register_pci();

    ath79_register_wmac(art + AP147_WMAC_CALDATA_OFFSET, NULL);

    ath79_register_mdio(0, 0x0);
    ath79_register_mdio(1, 0x0);

    ath79_init_mac(ath79_eth0_data.mac_addr, art + AP147_MAC0_OFFSET, 0);
    ath79_init_mac(ath79_eth1_data.mac_addr, art + AP147_MAC1_OFFSET, 0);

    /* WAN port */
    ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
    ath79_eth0_data.speed = SPEED_100;
    ath79_eth0_data.duplex = DUPLEX_FULL;
    ath79_eth0_data.phy_mask = BIT(4);
    ath79_register_eth(0);

    /* LAN ports */
    ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII;
    ath79_eth1_data.speed = SPEED_1000;
    ath79_eth1_data.duplex = DUPLEX_FULL;
    ath79_switch_data.phy_poll_mask |= BIT(4);
    ath79_switch_data.phy4_mii_en = 1;
    ath79_register_eth(1);
}

MIPS_MACHINE(ATH79_MACH_AP147, "AP147", "Qualcomm Atheros AP147 reference board",
         ap147_setup);

2. 自定义控制LED打开/关闭

# 自定义4G信号灯的信号强度
# sysfs=ap147:green:sig1
root@OpenWrt:/# echo 1 >/sys/class/leds/${sysfs}/brightness # 打开
root@OpenWrt:/# echo 0 >/sys/class/leds/${sysfs}/brightness # 关闭

3. 自动事件触发LED打开/关闭

# wifi 2.4G的灯由系统自己控制
# sysfs=ap147:green:wlan
root@OpenWrt:/# echo 255 > /sys/class/leds/${sysfs}/brightness
root@OpenWrt:/# echo netdev > /sys/class/leds/${sysfs}/trigger
root@OpenWrt:/# echo ath0 > /sys/class/leds/${sysfs}/device_name
root@OpenWrt:/# echo 'tx rx' > /sys/class/leds/${sysfs}/mode

4. 自定义事件触发LED打开/关闭/闪烁

# 系统灯周期闪烁
# sysfs=ap147:green:status
root@OpenWrt:/# echo 255 > /sys/class/leds/${sysfs}/brightness
root@OpenWrt:/# echo timer > /sys/class/leds/${sysfs}/trigger
root@OpenWrt:/# echo 1000 > /sys/class/leds/${sysfs}/delay_on
root@OpenWrt:/# echo 1000 > /sys/class/leds/${sysfs}/delay_off

5. 网口灯自动闪烁


网口灯也可以实现手动配置和自动闪烁,不过这个配置已经在驱动完成了,详看mach-ap147.c文件。如果想移植为通用的,即可删除mach文件中的配置,只进行注册即可,配置由应用层完成。
    ath79_gpio_direction_select(ap147_gpios[board_version][WAN], true);
    ath79_gpio_direction_select(ap147_gpios[board_version][LAN1], true);
    ath79_gpio_direction_select(ap147_gpios[board_version][LAN2], true);
    ath79_gpio_direction_select(ap147_gpios[board_version][LAN3], true);
    ath79_gpio_direction_select(ap147_gpios[board_version][LAN4], true);

    ath79_gpio_output_select(ap147_gpios[board_version][WAN],
            QCA953X_GPIO_OUT_MUX_LED_LINK5);
    ath79_gpio_output_select(ap147_gpios[board_version][LAN1],
            QCA953X_GPIO_OUT_MUX_LED_LINK1);
    ath79_gpio_output_select(ap147_gpios[board_version][LAN2],
            QCA953X_GPIO_OUT_MUX_LED_LINK2);
    ath79_gpio_output_select(ap147_gpios[board_version][LAN3],
            QCA953X_GPIO_OUT_MUX_LED_LINK3);
    ath79_gpio_output_select(ap147_gpios[board_version][LAN4],
            QCA953X_GPIO_OUT_MUX_LED_LINK4);

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐