最近调试一个项目,在gpio,dts上闷逼了一把。搞了很多问题。
1. 添加Dts文件里GPIO,同时去掉相同的GPIO配置项,注意去掉要干净,否则会导致死机
pio: pinctrl@1000b000 {
compatible = "mediatek,pinctrl";
reg = <0 0x1000b000 0 0x1000>;
mediatek,pctl-regmap = <&syscfg_pctl_a>,
<&syscfg_pctl_lt>,
<&syscfg_pctl_lm>,
<&syscfg_pctl_lb>,
<&syscfg_pctl_bl>,
<&syscfg_pctl_bm>,
<&syscfg_pctl_rb>,
<&syscfg_pctl_rt>;
sec_nfc_pin: sec-nfc {
compatible = "sum,sec_nfc_pin";
};
&节点名字, &表示的意思是,一个节点的开头标识
&sec_nfc_pin {
pinctrl-names = "default", "sec_pd_high", "sec_pd_low", "sec_wake_high", "sec_wake_low", "sec_irq_inpull";
pinctrl-0 = <&sec_nfc_default>;
pinctrl-1 = <&sec_nfc_pd_high>;
pinctrl-2 = <&sec_nfc_pd_low>;
pinctrl-3 = <&sec_nfc_wake_high>;
pinctrl-4 = <&sec_nfc_wake_low>;
pinctrl-5 = <&sec_nfc_irq_inpull>;
status = "okay";
};
中断Gpio方式
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
sec-nfc@27 {
compatible = "sec-nfc";
reg = <0x27>;
sec-nfc,ven-gpio = <&pio 10 0>;/*pw rst gpio_10*/
sec-nfc,firm-gpio = <&pio 27 0>;/*wake gpio_12*/
sec-nfc,irq-gpio = <&pio 12 0>;/*irq gpio_27*/
sec-nfc,clk_req-gpio = <&pio 136 0>;/*gpio_136*/
};
sec_nfc_irq_inpull: state_sec_irq_inpull {
pins_cmd_dat {
pins =
input-enable;
};
2, 使用GPIO函数
共用设备Dts节点
of_get_named_gpio(spi->dev.of_node,"nfc,irq-gpio", 0);
独立gpio节点方式:
node = of_find_compatible_node(NULL, NULL, "vendor,sec_nfc_pin");
pdev = of_find_device_by_node(node);
pinctrl_gpios = devm_pinctrl_get(&pdev->dev);
pinctrl_lookup_state(pinctrl_gpios, "sec_power_high");
pinctrl_select_state(pinctrl_gpios, pins_pd_high); // 输出高低电平,需要预先在dts里定义好
irq_num = of_get_named_gpio_flags(np, "nfc,irq-gpio", 0, NULL);
gpio_get_value(irq_num); // 标准Linux系统调用函数,注意参数gpio的获取
gpio_set_value()
GPIO函数另外一种使用组合
gpio_request(pdata->ven, "nfc_wake");
gpio_direction_output(pdata->ven, NFC_PW_OFF);
gpio_direction_input()
3、中断号获取和设置
node = of_find_compatible_node(NULL, NULL, "mediatek,irq_nfc-eint"); // 通过DWS工具生成关联节点
irq = irq_of_parse_and_map(node, 0);
request_threaded_irq(client->irq, NULL, sec_nfc_irq_thread_fn,
1 标志性log 格式:Selinux权限问题
avc: denied { 操作权限 } for pid=7201 comm=“进程名” scontext=u:r:源类型:s0 tcontext=u:r:目标类型:s0 tclass=访问类别 permissive=0
Kenel log:
avc: denied { execheap } for pid=7201 comm="com.baidu.input" scontext=u:r:untrusted_app:s0tcontext=u:r:untrusted_app:s0tclass=processpermissive=0
Logcat log:
com.baidu.input: type=1400audit(0.0:29): avc: denied { execheap } for scontext=u:r:untrusted_app:s0tcontext=u:r:untrusted_app:s0tclass=processpermissive=0
2. 在sepolicy中添加相应权限
2.1 修改依据:
log 信息:
avc: denied { 操作权限 } for pid=7201 comm=“进程名” scontext=u:r:源类型:s0 tcontext=u:r:目标类型:s0 tclass=访问类别 permissive=0
2.2 修改步骤:
找相应的“源类型.te ”文件
有两个位置可能存在相应的te文件:
位置一:LINUX/android/external/sepolicy
位置二:LINUX/android/device/qcom/sepolicy/common
2.3 按如下格式在该文件中添加:
allow 源类型 目标类型:访问类别 {权限};
3. 添加权限后的neverallowed冲突
3.1 编译报错:
libsepol.check_assertion_helper: neverallow on line xxx ofexternal/sepolicy/domain.te ……
3.2 原因:
新添加的sepolicy项目违反了domain.te 中规定的的总策略原则。所以该条权限策略不能添加,如果强行添加的话有CTS测试失败的风险。
3.3 解决方法:
1.从运行log中找到要访问的目标名称,一般是name字段后的名称
avc: denied { read write } for pid=303 comm="mediaserver" name="tfa9890"dev="tmpfs" ino=3880 scontext=u:r:mediaserver:s0tcontext=u:object_r:device:s0tclass=chr_file permissive=0
2.找到相应的*_contexts文件。
一般有file_contexts, genfs_contexts, property_contexts, service_contexts 等文件
3.在contexts文件中指定要访问的目标为一个“源类型 ”有权限访问的“目标类型”
如:在file_contexts中添加: /dev/tfa9890 u:object_r:audio_device:s0