倒车GPIO触发原理的分析

车载系统中倒车的触发逻辑有很多中,其中可通过GPIO来监听倒车信号的变化。mcu通过通过硬线检测电平变化,向GPIO写入电平值,android驱动和应用监听电平变化实现倒车状态监听。
在旧平台中封装了一个方法直接读取/sys/class/misc/mtgpio/pin节点的内容获取GPIO的电平值。 1为高电平,0为低电平。这种方式虽然简便,但需要赋予应用selinux权限,同时需要应用端开启线程监听变化,存在一定的风险。

    private static final int MODE = 0;
    private static final int INPUT_VALUE = 2;
    private static final int DIRECTION = 5;
    private static final int GPIO_HIGH = 1;
    private static final int GPIO_LOW = 0;
    
    public static int Backcar_Get_GPIO_Status() {
        FileReader reader = null;
        BufferedReader br = null;
        String line_string;
        int gpio_status = -1;
        boolean bfind;

        try {
            reader = new FileReader("/sys/class/misc/mtgpio/pin");
            br = new BufferedReader(reader);
            line_string = br.readLine();

            while(line_string != null) {
                bfind = line_string.trim().startsWith("46:");
                if(bfind) {
                    line_string = line_string.replaceAll("46:","");
                    line_string = line_string.trim();
                    //the match string([MODE] [PULL_SEL] [DIN] [DOUT] [PULL EN] [DIR] [IES] [SMT]));
                    /*0 indicate general gpio; 1 indicate output, 0 indicate input*/
                    if((line_string.charAt(MODE) == '0') && (line_string.charAt(DIRECTION) == '0')) {
                        if (line_string.charAt(INPUT_VALUE) == '1') {
                            gpio_status = GPIO_HIGH;
                        } else {
                            gpio_status = GPIO_LOW;
                        }
                    }
                    break;
                }
                line_string = br.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return gpio_status;
    }

新平台避免应用层直接操作读取,在framework封装一层sdk供应用调用。framework的代码入下

package com.mediatek.backcar;

import android.os.RemoteException;
import android.util.Log;
import java.util.ArrayList;
import vendor.mediatek.hardware.backcar.V1_0.IBackcar;
import vendor.mediatek.hardware.backcar.V1_0.IBackcarCallback;
import vendor.mediatek.hardware.backcar.V1_0.IBackcarCallback.Stub;

public class BackCar {
    private static final String TAG = "[BackCarSDK]";
    private BackCar.Listener mListener;
    private IBackcar mService;
    private IBackcarCallback mCallback;

    public BackCar() {
        this.mListener = null;
        this.mService = null;
        this.mCallback = new BackCar.BackcarCallback();

        try {
            this.mService = IBackcar.getService();
        } catch (RemoteException var3) {
            var3.printStackTrace();
            this.mService = null;
        }
    }

    public boolean setListener(BackCar.Listener listener) {
        if (null == this.mService) {
            Log.e("[BackCarSDK]", "mService = null");
            return false;
        } else {
            this.mListener = listener;
            boolean var3 = true;

            int status;
            try {
                if (null != this.mListener) {
                    status = this.mService.registerEventCallback(this.mCallback);
                } else {
                    status = this.mService.unregisterEventCallback(this.mCallback);
                }
            } catch (RemoteException var5) {
                var5.printStackTrace();
                status = 1;
            }
            return 0 == status;
        }
    }
    
    private class BackcarCallback extends Stub {
        private BackcarCallback() {
        }

        public void eventNotify(int evt, int param1, int param2, int param3) {
            Log.d("[BackCarSDK]", "eventNotify() enter evt = " + evt + ", param1 = " + param1);
            if (BackCar.this.mListener != null) {
                BackCar.this.mListener.onEvent(msg.what, msg.arg1, msg.arg2);
            }
        }
    }

    public interface Listener {
        void onEvent(int var1, int var2, int var3);
    }
}

应用层调用backcar framework对上提供的相关接口,framework再通过JNI调用backcar client客户端接口,通过binder通信到backcar server,实现GPIO信号的传递。
Backcar.java对应BackcarImpl.cpp

vendor/mediatek/proprietary/hardware/bcservice Backcar服务代码以及HIDL_SERVER代码
GPIO极性在backcar hal server代码BackcarImpl.cpp的buttonValue方法。

bc_gpio = !!(value & (1 << 0))

其中value为驱动层获取的多个GPIO位值,倒车GPIO为第一位。

Backcar HIDL接口路径

vendor/mediatek/proprietary/hardware/interfaces/backcar

Backcar Service通过打开/dev/backcardrv节点 向驱动层发送指令进行gpio监测。

驱动层kernel-4.9/drivers/misc/mediatek/backcar/backcar.c 对应/dev/backcardrv驱动节点,通过gpio_get_value方法从GPIO表中获取倒车引脚pin电平值。

通过DTS配置gpio num,路径入下:

kernel-4.9/arch/arm/boot/dts/mediatek_android_demo.dts

可通过adb查看gpio表,依次输入如下指令:

adb root
adb shell
cd /sys/devices/soc/1000b000.pinctrl
cat pin

字段1PIN为gpio号,字段2MODE为设置的模式,字段3PULL_SEL为上拉下拉设置,字段4DIN为gpio输入值。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

言并肃

感谢大哥支持!您的鼓励是我动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值