您尚未登录。

楼主 #1 2017-12-20 13:18:33

lzx1044364960
会员
注册时间: 2017-12-15
已发帖子: 35
积分: 35

MT7620如何实现一键弹出U盘

openwrt在MT7620a中实现了自动挂载U盘或硬盘,




但是不能自动卸载,还得手动umount,

请问各大神如何实现一键umonut弹出u盘?

离线

#2 2017-12-20 13:45:53

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: MT7620如何实现一键弹出U盘

/etc/mdev.conf

mmcblk([0-9]+)p([0-9]+) 0:0 660 */sbin/automount.sh $MDEV X${ACTION}
mmcblk([0-9]+)          0:0 660 */sbin/automount.sh $MDEV X${ACTION}
sd([a-z]+)([0-9]+)      0:0 660 */sbin/automount.sh $MDEV X${ACTION}
sd([a-z]+)              0:0 660 */sbin/automount.sh $MDEV X${ACTION}

/sbin/automount.sh

#! /bin/sh

# debugging message
#echo "MDEV=$1 : ACTION=$2 : SUBSYSTEM=$SUBSYSTEM : DEVPATH=$DEVPATH : DEVNAME=$DEVNAME" >> /dev/console

if [ "$1" == "" ]; then
    echo "parameter is none" > /tmp/error.txt
    exit 1
fi

MNT=$1
#if [ $(echo $1 | grep mmcblk) ]; then
#    if [ $(echo $1 | grep p[25]) ]; then
#        MNT=sdcard2
#    else
#        MNT=sdcard
#    fi
#elif [ $(echo $1 | grep sd) ]; then
#    if [ $(echo $1 | grep p[25]) ]; then
#        MNT=nandcard2
#    else
#        MNT=nandcard
#    fi
#fi

# there is no ACTION, it is for initial population
if [ "$2" = "X" ]; then
    mounted=`mount | grep $1 | wc -l`
    if [ $mounted -ge 1 ]; then
        # mounted, assume the ACTION is remove
        #ACT=Xremove
        # only set add for initial population
        ACT=Xadd
    else
        # not mounted, assume the ACTION is add
        ACT=Xadd
    fi
else
    ACT=$2
fi

if [ "$ACT" = "Xremove" ]; then
    # umount the device
    echo "$ACT /mnt/udisk" >> /tmp/mdev.log
    if ! umount -l "/mnt/udisk"; then
        exit 1
    else
        rm -f "/mnt/udisk"
        echo "[Umount FS]: /dev/$1 -X-> /mnt/udisk" > /dev/console
    fi

    if ! rmdir "/mnt/udisk"; then
        exit 1
    fi
else
    # mount the device
    mounted=`mount | grep $1 | wc -l`
    #echo "par=$1,mounted=$mounted,MNT=$MNT" > /dev/console
    if [ $mounted -ge 1 ]; then
        #echo "device $1 is already mounted" > /dev/console
        exit 0
    fi

    if ! mkdir -p "/mnt/udisk"; then
        exit 1
    fi

    if [ $(echo $1 | grep mtd) ]; then
        if mount -t jffs2 "/dev/$1" "/mnt/udisk"; then
            echo "[Mount JFFS2]: /dev/$1 --> /mnt/udisk" > /dev/console
            echo "$ACT /mnt/udisk" >> /tmp/mdev.log
        elif mount -t yaffs2 -o"inband-tags" "/dev/$1" "/mnt/$1"; then
            echo "[Mount YAFFS2]: /dev/$1 --> /mnt/udisk" > /dev/console
            echo "$ACT /mnt/$1" >> /tmp/mdev.log
        elif mount -t ubifs "/dev/$1" "/mnt/udisk"; then
            echo "[Mount UBIFS]: /dev/$1 --> /mnt/udisk" > /dev/console
            echo "$ACT /mnt/udisk" >> /tmp/mdev.log
        else
            # failed to mount, clean up mountpoint
            if ! rmdir "/mnt/udisk"; then
                exit 1
            fi
        fi
    else
        # try vfat only
        if mount -t vfat -o noatime,shortname=mixed,utf8 "/dev/$1" "/mnt/udisk"; then
#            ln -s /mnt/$1 /mnt/udisk
            echo "[Mount VFAT]: /dev/$1 --> /mnt/udisk" > /dev/console
            echo "$ACT /mnt/udisk" >> /tmp/mdev.log
        else
            # failed to mount, clean up mountpoint
            if ! rmdir "/mnt/udisk"; then
                exit 1
            fi
            exit 1
        fi
    fi
fi

上面是我的rootfs里面的 /etc/mdev.conf, /sbin/automount.sh,
在新唐nuc972, n32926, 全志V3s均可以正常卸载U盘和TF卡,
仅供参考。





离线

楼主 #3 2017-12-20 14:45:31

lzx1044364960
会员
注册时间: 2017-12-15
已发帖子: 35
积分: 35

Re: MT7620如何实现一键弹出U盘

这个脚本是什么情况下卸载呢?是拔掉U盘就自动卸载么?

离线

#4 2017-12-20 14:58:02

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: MT7620如何实现一键弹出U盘

lzx1044364960 说:

这个脚本是什么情况下卸载呢?是拔掉U盘就自动卸载么?

对,拔出U盘后台执行的 /sbin/mdev 会执行 /sbin/automount.sh 的 umount 命令:

if [ "$ACT" = "Xremove" ]; then
    # umount the device
    echo "$ACT /mnt/udisk" >> /tmp/mdev.log
    if ! umount -l "/mnt/udisk"; then
        exit 1
    else
        rm -f "/mnt/udisk"
        echo "[Umount FS]: /dev/$1 -X-> /mnt/udisk" > /dev/console
    fi
    if ! rmdir "/mnt/udisk"; then
        exit 1
    fi

widora neo是拔出U盘是可以正常卸载的。





离线

#5 2017-12-20 15:00:50

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: MT7620如何实现一键弹出U盘

如果你的 MT7620a 不能正常卸载,先检查脚本有没有执行,如果执行了,检查是不是没写卸载函数,或者卸载函数有bug?





离线

楼主 #6 2017-12-20 15:07:43

lzx1044364960
会员
注册时间: 2017-12-15
已发帖子: 35
积分: 35

Re: MT7620如何实现一键弹出U盘

我现在想添加一个按键,当自动挂载上以后按下按键就umount,但是我现在不明白的是当按键按下触发异常以后是调用哪些路径下的脚本

离线

#7 2017-12-20 15:10:40

daydayup
会员
注册时间: 2017-10-09
已发帖子: 343
积分: 343

Re: MT7620如何实现一键弹出U盘

你想通过按下按键触发自己写的类式 umount.sh 脚本?

离线

#8 2017-12-20 15:23:51

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: MT7620如何实现一键弹出U盘

试一试这样:
echo umount.sh > /proc/sys/kernel/hotplug

umount.sh里面打印一些消息即可。
如果拔出来没有执行 umount.sh, 估计你的驱动有问题了。





离线

楼主 #9 2017-12-20 15:30:16

lzx1044364960
会员
注册时间: 2017-12-15
已发帖子: 35
积分: 35

Re: MT7620如何实现一键弹出U盘

嗯嗯!对!我参考了一键复位来做的,一键复位中修改了DTS中MT7620a.dts文件来修改GPIO口:(下面的S2用来复位,准备用S3来做一键U盘弹出)
  gpio-keys-polled {
                compatible = "gpio-keys";
                #address-cells = <1>;
                #size-cells = <0>;
                poll-interval = <20>;
                s2 {
                        label = "reset";
                        gpios = <&gpio0 1 1>;
                        linux,code = <0x198>;
                };
                s3 {
                        label = "S3";
                        gpios = <&gpio0 2 1>;
                        linux,code = <0x101>;
                };
        };

然后cd /etc/rc.button
     vi reset   如下:   

#!/bin/sh

[ "${ACTION}" = "released" ] || exit 0

. /lib/functions.sh

logger "$BUTTON pressed for $SEEN seconds"

if [ "$SEEN" -lt 1 ]
then
        echo "REBOOT" > /dev/console
        sync
        reboot
elif [ "$SEEN" -gt 5 ]
then
        echo "FACTORY RESET" > /dev/console
        jffs2reset -y && reboot &
fi

return 0


这样就可以实现一键复位了,可是一键弹出U盘就不知该如何下手了

离线

#10 2017-12-20 15:38:16

daydayup
会员
注册时间: 2017-10-09
已发帖子: 343
积分: 343

Re: MT7620如何实现一键弹出U盘

lzx1044364960 说:

嗯嗯!对!我参考了一键复位来做的,一键复位中修改了DTS中MT7620a.dts文件来修改GPIO口:(下面的S2用来复位,准备用S3来做一键U盘弹出)
  gpio-keys-polled {
                compatible = "gpio-keys";
                #address-cells = <1>;
                #size-cells = <0>;
                poll-interval = <20>;
                s2 {
                        label = "reset";
                        gpios = <&gpio0 1 1>;
                        linux,code = <0x198>;
                };
                s3 {
                        label = "S3";
                        gpios = <&gpio0 2 1>;
                        linux,code = <0x101>;
                };
        };

然后cd /etc/rc.button
     vi reset   如下:   

#!/bin/sh

[ "${ACTION}" = "released" ] || exit 0

. /lib/functions.sh

logger "$BUTTON pressed for $SEEN seconds"

if [ "$SEEN" -lt 1 ]
then
        echo "REBOOT" > /dev/console
        sync
        reboot
elif [ "$SEEN" -gt 5 ]
then
        echo "FACTORY RESET" > /dev/console
        jffs2reset -y && reboot &
fi

return 0


这样就可以实现一键复位了,可是一键弹出U盘就不知该如何下手了

这个问题不大。
umount.sh

umount /mnt/udisk

/etc/rc.button 里面调用 umount.sh 即可。
一般在嵌入式系统只挂载U盘里面的第一个磁盘,而且是挂载到同一个文件夹。

离线

楼主 #11 2017-12-20 15:58:29

lzx1044364960
会员
注册时间: 2017-12-15
已发帖子: 35
积分: 35

Re: MT7620如何实现一键弹出U盘

在/etc/rc.button目录下有如下文件:
  failsafe  power     reset     rfkill 
我是要在/etc/rc.button目录下建一个文件调用umount.sh 呢?还是在上面的哪一个文件里调用umount.sh  按键按下系统是怎么找到这个脚本文件的呢?这点我一直没想明白 

离线

#12 2017-12-20 16:26:38

daydayup
会员
注册时间: 2017-10-09
已发帖子: 343
积分: 343

Re: MT7620如何实现一键弹出U盘

lzx1044364960 说:

在/etc/rc.button目录下有如下文件:
  failsafe  power     reset     rfkill 
我是要在/etc/rc.button目录下建一个文件调用umount.sh 呢?还是在上面的哪一个文件里调用umount.sh  按键按下系统是怎么找到这个脚本文件的呢?这点我一直没想明白 

umount.sh可以放文件系统任意地方, 比如/sbin/umount.sh
执行的时候用绝对目录就可以了。
/etc/rc.button 以前没有这么用过,不是看到你说,我都不知道能这么用。

离线

#13 2017-12-20 16:29:58

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: MT7620如何实现一键弹出U盘

涨见识了: Button按键的检测

在OpenWRT中,按键的检测也是通过Hotplug机制来实现的。

它首先写了一个内核模块:gpio_button_hotplug, 用于监听按键,有中断和 poll 两种方式。然后在发出事件的同时, 将记录并计算得出的两次按键时间差也作为 uevent 变量发出来。这样在用户空间收到这个 uevent事件时就知道该次按键按下了多长时间。

hotplug.json中有描述, 如果 uevent 中含有BUTTON 字符串, 而且SUBSYSTEM 为 "button", 则执行/etc/rc.button/下的 %BUTTON%脚本来处理。

细节描述如下: 当按键时,则触发button_hotplug_event函数(gpio-button-hotplug.c)

调用button_hotplug_create_event产生uevent事件,调用button_hotplug_fill_event填充事件(JSON格式),并最终调用button_hotplug_work发出uevent广播。

上述广播,被守护进程procd中的hotplug_handler (procd/plug/hotplug.c) 收到,并根据etc/hotplug.json中预先定义的JSON内容匹配条件,定位到对应的执行函数,具体如下所示,命中了两个条目,所以会依次执行这两个条目队列中的操作函数:

[ "if",
    [ "and",
        [ "has", "BUTTON" ],
        [ "eq", "SUBSYSTEM", "button" ],
    ],
    [ "exec", "/etc/rc.button/%BUTTON%" ]
],

[ "if",
    [ "eq", "SUBSYSTEM",
    [ "net", "input", "usb", "ieee1394", "block", "atm", "zaptel", "tty", "button" ]
    ],
    [ "exec", "/sbin/hotplug-call", "%SUBSYSTEM%" ]
],
在rc.button目录下,我们定义了reset按钮的执行脚本:

root@OpenWrt:/etc/rc.button# cat reset
#!/bin/sh

[ "${ACTION}" = "released" ] || exit 0

. /lib/functions.sh

logger "$BUTTON pressed for $SEEN seconds"

if [ "$SEEN" -lt 1 ]
then
        echo "REBOOT" > /dev/console
        sync
        reboot
elif [ "$SEEN" -gt 5 ]
then
        echo "FACTORY RESET" > /dev/console
        jffs2reset -y && reboot &
fi
从脚本中我们可以清晰地看出,当按键时间小于1s时,执行reboot重启命令,当按键时间超过5s时,执行恢复出厂设置并重启命令。

第二个条目,由于默认情况下没有在/etc/hotplug.d目录下创建button子目录,因此执行为空。

使用 export DBGLVL=10; procd -h /etc/hotplug.json 截获一些打印信息看看:

root@OpenWrt:/etc/rc.button# export DBGLVL=10; procd -h /etc/hotplug.json
procd:hotplug_handler_debug(404): {{"HOME":"\/","PATH":"\/sbin:\/bin:\/usr\/sbin:\/usr\/bin","SUBSYSTEM":"button","ACTION":"pressed","BUTTON":"reset","SEEN":"42949450","SEQNUM":"331"}}
procd: rule_handle_command(355): Command: exec
procd: rule_handle_command(357):  /etc/rc.button/reset
procd: rule_handle_command(358):
procd: rule_handle_command(360): Message:
procd: rule_handle_command(362):  HOME=/
procd: rule_handle_command(362):  PATH=/sbin:/bin:/usr/sbin:/usr/bin
procd: rule_handle_command(362):  SUBSYSTEM=button
procd: rule_handle_command(362):  ACTION=pressed
procd: rule_handle_command(362):  BUTTON=reset
procd: rule_handle_command(362):  SEEN=42949450
procd: rule_handle_command(362):  SEQNUM=331
procd: rule_handle_command(363):
procd: queue_next(281): Launched hotplug exec instance, pid=987
procd: rule_handle_command(355): Command: exec
procd: rule_handle_command(357):  /sbin/hotplug-call
procd: rule_handle_command(357):  button
procd: rule_handle_command(358):
procd: rule_handle_command(360): Message:
procd: rule_handle_command(362):  HOME=/
procd: rule_handle_command(362):  PATH=/sbin:/bin:/usr/sbin:/usr/bin
procd: rule_handle_command(362):  SUBSYSTEM=button
procd: rule_handle_command(362):  ACTION=pressed
procd: rule_handle_command(362):  BUTTON=reset
procd: rule_handle_command(362):  SEEN=42949450
procd: rule_handle_command(362):  SEQNUM=331
procd: rule_handle_command(363):
procd: queue_proc_cb(286): Finished hotplug exec instance, pid=987
...





离线

#14 2017-12-20 17:38:39

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: MT7620如何实现一键弹出U盘

widora neo 也支持button这种玩法:widora/openwrt_widora





离线

楼主 #15 2017-12-20 17:43:57

lzx1044364960
会员
注册时间: 2017-12-15
已发帖子: 35
积分: 35

Re: MT7620如何实现一键弹出U盘

大哥你在贴子上的回复我看到了,我非常感谢你的热心帮助,,不过有点没太明白,具体疑问如下:我在DTS中定义了
tp1.png
tp2.png
就相当于给
tp3.png
BUTTON赋值为“reset”所以就去执行/etc/rc.button/下的reset里的脚本文件?如果在DTS里改成
tp4.png
是不是就去执行/etc/rc.button/下的hello(当然前提得有这个文件),你看我的理解对么?

离线

楼主 #16 2017-12-20 17:51:01

lzx1044364960
会员
注册时间: 2017-12-15
已发帖子: 35
积分: 35

Re: MT7620如何实现一键弹出U盘

我在DTS中定义了:
label = "reset";

gpio-keys-polled {
                compatible = "gpio-keys";
                #address-cells = <1>;
                #size-cells = <0>;
                poll-interval = <20>;
                s2 {
                        label = "reset";
                        gpios = <&gpio0 1 1>;
                        linux,code = <0x198>;
                };
                s3 {
                        label = "S3";
                        gpios = <&gpio0 2 1>;
                        linux,code = <0x101>;
                };
        };

就相当于给
hotplug.json中有描述, 如果 uevent 中含有BUTTON 字符串, 而且SUBSYSTEM 为 "button", 则执行/etc/rc.button/下的 %BUTTON%脚本来处理。 
BUTTON赋值为“reset”所以就去执行/etc/rc.button/下的reset里的脚本文件?如果在DTS里改成
label = "hello";
是不是就去执行/etc/rc.button/下的hello(当然前提得有这个文件),你看我的理解对么?

离线

#17 2017-12-20 18:06:03

goodgoodstudy
会员
注册时间: 2017-09-15
已发帖子: 61
积分: 61

Re: MT7620如何实现一键弹出U盘

根据看到的资料,我觉得是这样,不过以前没试过。有空拿出我的widora neo出来试一试

离线

楼主 #18 2017-12-21 13:36:46

lzx1044364960
会员
注册时间: 2017-12-15
已发帖子: 35
积分: 35

Re: MT7620如何实现一键弹出U盘

不对!好像不是这样的,我在DTS中改了 label = "hello";

gpio-keys-polled {
                compatible = "gpio-keys";
                #address-cells = <1>;
                #size-cells = <0>;
                poll-interval = <20>;
                s2 {
                        label = "hello";
                        gpios = <&gpio0 1 1>;
                        linux,code = <0x198>;
                };
                s3 {
                        label = "S3";
                        gpios = <&gpio0 2 1>;
                        linux,code = <0x101>;
                };
        };

编译后固件里/etc/rc.button/ 没有hello这个脚本文件还是reset ,an按下按键依然可以复位,所以好像不是上面描述那样的

   failsafe  power     reset     rfkill

离线

#19 2017-12-21 13:49:55

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: MT7620如何实现一键弹出U盘

脚本应该自己写在 rootfs里面吧,肯定不是自动生成的。





离线

楼主 #20 2017-12-21 14:10:02

lzx1044364960
会员
注册时间: 2017-12-15
已发帖子: 35
积分: 35

Re: MT7620如何实现一键弹出U盘

我的意思是说经过我刚刚的改动 ,按之前的理解

hotplug.json中有描述, 如果 uevent 中含有BUTTON 字符串, 而且SUBSYSTEM 为 "button", 则执行/etc/rc.button/下的 %BUTTON%脚本来处理。
 
BUTTON赋值为“hello”了所以就去执行/etc/rc.button/下的hello脚本文件,但是/etc/rc.button/下没有hello这个文件,所以应该没有任何反应才对,但实际上板子却复位了

离线

#21 2017-12-21 14:21:23

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: MT7620如何实现一键弹出U盘

那就奇怪了。只有openwrt 才有hotplug button的功能,别的linux有没有加这个功能.

建议在 button-hotplug.c 添加跟踪打印语句,方便调试。





离线

#22 2019-10-26 11:57:35

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: MT7620如何实现一键弹出U盘

感谢各位,此贴已收录到精华帖合集: https://whycan.cn/t_3019.html





离线

#23 2024-11-01 15:24:03

baidxi
会员
注册时间: 2018-10-27
已发帖子: 36
积分: 36.5

Re: MT7620如何实现一键弹出U盘

@晕哥
这完全就是一个伪需求,而且实现也是个掩耳盗铃的行为。
当内核检测到U盘被拔出时,设备已经断开,这时候再umount已经没了意义。
真正有意义的是绑定到按键上,按一下或长按多少秒再扫行umount行为,执行完,亮个灯,如果执行失败,就闪灯这种,才有意义 。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn