分类 Android 下的文章

转自: https://blog.csdn.net/u014769864/article/details/71545588

MarkerView

MPAndroidChart 系列:

MPAndroidChart 之LineChart(1)

MPAndroidChart之LineChart(2)MarkerView

MPAndroidChart之LinChart(3)scale缩放

对于MPAndroidChart的基本属性和一些常见的设置前面的一篇博客MPAndroidChart之LineChart(1) http://www.ramlife.org/2021/12/05/479.html 大部分说到了,这篇将要实现MarkerView这个东西,我理解是提示覆盖物,类似百度地图的覆盖物同一个意思,至于其他啥啥的,可以评论里吐口水大笑。

- 阅读剩余部分 -

转自: https://blog.csdn.net/u014769864/article/details/71479591

公司做金融的,之前项目用的MPAndroidChart来完成分时图和K线图图表,不过之前的项目用的MPAndroidChart版本很老很老了,我也只好自己去尝试最新版本的MPAndroidChart了,虽然我也是刚接触MPAndroidChart不久,如果MPAndroidChart 之LineChart不懂基本属性的设置也可以看看MPAndroidChart3.0之LineChart。 https://blog.csdn.net/u014769864/article/details/70888717

MPAndroidChart系列:

MPAndroidChart之LineChart(1)

MPAndroidChart之LineChart(2)MarkerView

MPAndroidChart之LinChart(3)scale缩放

本文MPAndroidChart使用版本:(3的版本了)

compile 'com.github.PhilJay:MPAndroidChart:v3.0.2'

我没有使用gradle依赖,而是把代码拉下来依赖的,因为:

  1. 在使用过程中发现了好多旧版本有的api,新版本的不知道丢哪里去了;
  2. 另外挺多使用的问题,比如缩放,重新设置数据后错乱问题....

但是还是值得使用的,因为大部分的基本图表它都能满足,也灵活,https://github.com/PhilJay/MPAndroidChart 上的星星说明了一切安静。

- 阅读剩余部分 -

检查 io 是否被占用。

  1. adb root, adb shell
  2. cd /sys/class/gpio 进入 gpio 目录
  3. echo 46 > export 获取 gpio_46
  4. 检查上条命令是否提示 /system/bin/sh: can't create export: Read-only file system,如果提示这个,那么说明这个 gpio 被占用了,否则这个 gpio 就是空的。
  5. echo 46 > unexport 释放 gpio_46

驱动代码 (quectel)

不管输入还是输出 gpio,直接仿照这个源文件里面进行添加即可。 比如说这个源码里面提供了四个 gpio,key_home, red_led_en, green_led_en, yellow_led_enSC200R_Android10.0_R04_r023/kernel/msm-4.9/drivers/misc/gpio_control.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/workqueue.h>
#include <linux/errno.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>

#if defined(CONFIG_FB)
#include <linux/notifier.h>
#include <linux/fb.h>
#endif
#include <linux/timer.h>
#include <linux/string.h>

struct quectel_platform_data {
    int key_home;

    int red_led_en;
    int green_led_en;
    int yellow_led_en;
};

struct quectel_platform_data *quec_pdata;

static ssize_t quec_key_home_show(struct device *dev,
                struct device_attribute *attr, char *buf)
{
    return snprintf(buf, 2, "%d\n", __gpio_get_value(quec_pdata->key_home));
}

static ssize_t quec_red_led_en_show(struct device *dev,
                struct device_attribute *attr, char *buf)
{
    return snprintf(buf, 2, "%d\n", __gpio_get_value(quec_pdata->red_led_en));
}

static ssize_t quec_green_led_en_show(struct device *dev,
                struct device_attribute *attr, char *buf)
{
    return snprintf(buf, 2, "%d\n", __gpio_get_value(quec_pdata->green_led_en));
}

static ssize_t quec_yellow_led_en_show(struct device *dev,
                struct device_attribute *attr, char *buf)
{
    return snprintf(buf, 2, "%d\n", __gpio_get_value(quec_pdata->yellow_led_en));
}

static ssize_t quec_red_led_en_store(struct device *dev,
                struct device_attribute *attr,
                const char *buf, size_t size)
{
    unsigned int val;
    if (size > 2)
        return -EINVAL;

    if (sscanf(buf, "%u", &val) != 1)
        return -EINVAL;
    if(val)
        __gpio_set_value(quec_pdata->red_led_en,1);
    else
        __gpio_set_value(quec_pdata->red_led_en,0);
    return size;
}

static ssize_t quec_green_led_en_store(struct device *dev,
                struct device_attribute *attr,
                const char *buf, size_t size)
{
    unsigned int val;
    if (size > 2)
        return -EINVAL;

    if (sscanf(buf, "%u", &val) != 1)
        return -EINVAL;
    if(val)
        __gpio_set_value(quec_pdata->green_led_en,1);
    else
        __gpio_set_value(quec_pdata->green_led_en,0);
    return size;
}

static ssize_t quec_yellow_led_en_store(struct device *dev,
                struct device_attribute *attr,
                const char *buf, size_t size)
{
    unsigned int val;
    if (size > 2)
        return -EINVAL;

    if (sscanf(buf, "%u", &val) != 1)
        return -EINVAL;
    if(val)
        __gpio_set_value(quec_pdata->yellow_led_en,1);
    else
        __gpio_set_value(quec_pdata->yellow_led_en,0);
    return size;
}

static DEVICE_ATTR(key_home, (S_IRUGO | S_IWUSR | S_IWGRP),
            quec_key_home_show,
            NULL);

static DEVICE_ATTR(red_led_en, (S_IRUGO | S_IWUSR | S_IWGRP),
            quec_red_led_en_show,
            quec_red_led_en_store);

static DEVICE_ATTR(green_led_en, (S_IRUGO | S_IWUSR | S_IWGRP),
            quec_green_led_en_show,
            quec_green_led_en_store);

static DEVICE_ATTR(yellow_led_en, (S_IRUGO | S_IWUSR | S_IWGRP),
            quec_yellow_led_en_show,
            quec_yellow_led_en_store);

static struct attribute *quec_attrs[] = {
    &dev_attr_key_home.attr,

    &dev_attr_red_led_en.attr,
    &dev_attr_green_led_en.attr,
    &dev_attr_yellow_led_en.attr,
    NULL
};

static const struct attribute_group quec_attr_grp = {
    .attrs = quec_attrs,
};

static int quectel_misc_parse_dt(struct device *dev, 
        struct quectel_platform_data *pdata)
{
    struct device_node *np = dev->of_node;

    pdata->key_home = of_get_named_gpio(np, "quec,key_home", 0);
    if (pdata->key_home < 0){
        pr_err("%s: get quec,key_home failed\n", __func__);
        return pdata->key_home;
    }

    pdata->red_led_en = of_get_named_gpio(np, "quec,red_led_en", 0);
    if (pdata->red_led_en < 0){
        pr_err("%s: get quec,red_led_en failed\n", __func__);
        return pdata->red_led_en;
    }

    pdata->green_led_en = of_get_named_gpio(np, "quec,green_led_en", 0);
    if (pdata->green_led_en < 0){
        pr_err("%s: get quec,green_led_en failed\n", __func__);
        return pdata->green_led_en;
    }

    pdata->yellow_led_en = of_get_named_gpio(np, "quec,yellow_led_en", 0);
    if (pdata->yellow_led_en < 0){
        pr_err("%s: get quec,yellow_led_en failed\n", __func__);
        return pdata->yellow_led_en;
    }

    return 0;
}

static int quectel_request_io_port(struct quectel_platform_data *pdata)
{
    int ret = 0;

    if (gpio_is_valid(pdata->key_home)) {
        ret = gpio_request(pdata->key_home, "quectel_key_home");
        if (ret) {
            pr_err("%s: Unable to request key_home  [%d]\n", __func__,pdata->key_home);
            goto err_pwr_off;
        }

        ret = gpio_direction_output(pdata->key_home, 0);
        if (ret) {
            pr_err("%s: Unable to set direction for key_home [%d]\n", __func__,pdata->key_home);
            goto err_free_key_home;
        }
    } else {
        pr_err("%s: Invalid key_home [%d]!\n", __func__,pdata->key_home);
        ret = -EINVAL;
        goto err_free_key_home;
    }

    if (gpio_is_valid(pdata->red_led_en)) {
        ret = gpio_request(pdata->red_led_en, "quectel_red_led_en");
        if (ret) {
            pr_err("%s: Unable to request red_led_en  [%d]\n", __func__,pdata->red_led_en);
            goto err_pwr_off;
        }

        ret = gpio_direction_output(pdata->red_led_en, 0);
        if (ret) {
            pr_err("%s: Unable to set direction for red_led_en [%d]\n", __func__,pdata->red_led_en);
            goto err_free_red_led_en;
        }
    } else {
        pr_err("%s: Invalid red_led_en [%d]!\n", __func__,pdata->red_led_en);
        ret = -EINVAL;
        goto err_free_red_led_en;
    }

    if (gpio_is_valid(pdata->green_led_en)) {
        ret = gpio_request(pdata->green_led_en, "quectel_green_led_en");
        if (ret) {
            pr_err("%s: Unable to request green_led_en  [%d]\n", __func__,pdata->green_led_en);
            goto err_pwr_off;
        }

        ret = gpio_direction_output(pdata->green_led_en, 0);
        if (ret) {
            pr_err("%s: Unable to set direction for green_led_en [%d]\n", __func__,pdata->green_led_en);
            goto err_free_green_led_en;
        }
    } else {
        pr_err("%s: Invalid green_led_en [%d]!\n", __func__,pdata->green_led_en);
        ret = -EINVAL;
        goto err_free_green_led_en;
    }

    if (gpio_is_valid(pdata->yellow_led_en)) {
        ret = gpio_request(pdata->yellow_led_en, "quectel_yellow_led_en");
        if (ret) {
            pr_err("%s: Unable to request yellow_led_en  [%d]\n", __func__,pdata->yellow_led_en);
            goto err_pwr_off;
        }

        ret = gpio_direction_output(pdata->yellow_led_en, 0);
        if (ret) {
            pr_err("%s: Unable to set direction for yellow_led_en [%d]\n", __func__,pdata->yellow_led_en);
            goto err_free_yellow_led_en;
        }
    } else {
        pr_err("%s: Invalid yellow_led_en [%d]!\n", __func__,pdata->yellow_led_en);
        ret = -EINVAL;
        goto err_free_yellow_led_en;
    }

    return 0;

err_free_key_home:
    if (gpio_is_valid(pdata->key_home))
        gpio_free(pdata->key_home);
err_free_red_led_en:
    if (gpio_is_valid(pdata->red_led_en))
        gpio_free(pdata->red_led_en);
err_free_green_led_en:
    if (gpio_is_valid(pdata->green_led_en))
        gpio_free(pdata->green_led_en);
err_free_yellow_led_en:
    if (gpio_is_valid(pdata->yellow_led_en))
        gpio_free(pdata->yellow_led_en);
err_pwr_off:
        return ret;

}

static void quec_gpio_free(void)
{
    gpio_free(quec_pdata->key_home);
    gpio_free(quec_pdata->red_led_en);
    gpio_free(quec_pdata->green_led_en);
    gpio_free(quec_pdata->yellow_led_en);
}

static int quec_gpio_probe(struct platform_device *pdev)
{

    int ret;
    struct quectel_platform_data *pdata ;

    pr_err("-----------quectel_probe start--------------\n");

    if (pdev->dev.of_node) {
        pdata = devm_kzalloc(&pdev->dev,
            sizeof(struct quectel_platform_data), GFP_KERNEL);
        if (!pdata) {
            dev_err(&pdev->dev,
                "quec allocate memory for pdata\n");
            return -ENOMEM;
        }
        ret = quectel_misc_parse_dt(&pdev->dev, pdata);
        if (ret) {
            dev_err(&pdev->dev, "parse dts failed \n");
            return PTR_ERR(pdata);
        }
    } else {
        pdata = pdev->dev.platform_data;
    }

    quec_pdata = pdata;

    if(!pdata) {
        dev_err(&pdev->dev, "quec Invalid pdata\n");
        return -EINVAL;
    }

    ret = quectel_request_io_port(pdata);
    if(ret){
        dev_err(&pdev->dev, "request io failed\n");
        return ret;
    }

    ret = sysfs_create_group(&pdev->dev.kobj, &quec_attr_grp);
    if (ret < 0) {
        dev_err(&pdev->dev, "sys file creation failed.\n");
        return -ENOMEM;
    }

    pr_err("-----------quectel_probe success--------------\n");

    return 0;
}

static int quec_gpio_remove(struct platform_device *pdev)
{
    struct quectel_platform_data *pdata = platform_get_drvdata(pdev);

    device_init_wakeup(&pdev->dev, 0);

    sysfs_remove_group(&pdev->dev.kobj, &quec_attr_grp);

    quec_gpio_free();

    kfree(pdata);

    return 0;
}

static const struct of_device_id quec_gpio_match[] = {
        { .compatible = "quec,gpio_driver" },
        {},  
};

static struct platform_driver quec_gpio_driver = {
    .driver = {
            .name = "quec_gpio",
            .owner = THIS_MODULE,
            .of_match_table = quec_gpio_match,
    },   
    .probe = quec_gpio_probe,
    .remove = quec_gpio_remove,
};

module_platform_driver(quec_gpio_driver);

MODULE_DESCRIPTION("misc driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");

makefile

SC200R_Android10.0_R04_r023/kernel/msm-4.9/drivers/misc/Makefile 里面增加 obj-y += gpio_control.o

dtsi

SC200R_Android10.0_R04_r023/kernel/msm-4.9/arch/arm64/boot/dts/qcom/qm215-qrd.dtsi

&soc {
        gpio_ctrl {
                compatible = "quec,gpio_driver";
                quec,key_home = <&tlmm 95 0x00>;
                quec,red_led_en = <&tlmm 93 0x00>;
                quec,green_led_en = <&tlmm 46 0x00>;
                quec,yellow_led_en = <&tlmm 23 0x00>;
        };
};

解除被占用 gpio

SC200R_Android10.0_R04_r023/kernel/msm-4.9/arch/arm64/boot/dts/qcom/msm8917-pinctrl.dtsi 中把被占用的 gpio 去除掉即可。

编译,烧录

如果修改的时驱动源码,那么编译 boot.img,如果修改的是 dts,那么编译 dtbo.img。 然后用 fastboot,把 boot.img, dtbo.img 都烧录进去。

读取 gpio

查找 dts 中对应的节点 key_homefind . -name "*home*", 结果

./devices/platform/soc/soc:input-gpio/key_home
./firmware/devicetree/base/soc/input-gpio/quec,key_home
./module/home_gpio
cd ./devices/platform/soc/soc:input-gpio/
cat key_home

就可以读取到输入的高低电平

输出 gpio

find . -name "*led_en*"

./devices/platform/soc/soc:gpio_ctrl/green_led_en
./devices/platform/soc/soc:gpio_ctrl/red_led_en
./devices/platform/soc/soc:gpio_ctrl/yellow_led_en
./firmware/devicetree/base/__symbols__/front_flash_led_enable
./firmware/devicetree/base/__symbols__/rear_flash_led_enable
./firmware/devicetree/base/soc/gpio_ctrl/quec,green_led_en
./firmware/devicetree/base/soc/gpio_ctrl/quec,yellow_led_en
./firmware/devicetree/base/soc/gpio_ctrl/quec,red_led_en
./firmware/devicetree/base/soc/pinctrl@1000000/tlmm_pmi_flash_led/front_flash_led_enable
./firmware/devicetree/base/soc/pinctrl@1000000/tlmm_pmi_flash_led/rear_flash_led_enable
cd devices/platform/soc/soc\:gpio_ctrl/
echo 1 > green_led_en
echo 0 > green_led_en

就可以设置输出 gpio 的高低电平。

另外一种方法实现针对 led 的 gpio 输出。 (fibcom)

内核本身就有 led 的驱动代码,在 kernel/msm-4.9/drivers/leds/leds-gpio.c 中,所以如果是 led 的用途 gpio,可以直接修改 dtsi 即可。

kernel/msm-4.9/arch/arm64/boot/dts/qcom/sq808-evk/msm8917-pinctrl.dtsi

                gpio_led_active: gpio_led_active {
                        mux {
                                pins = "gpio98", "gpio97", "gpio12";
                                drive-strength = <2>;
                                output-low;
                        };
                };
kernel/msm-4.9/arch/arm64/boot/dts/qcom/sq808-evk/qm215-qrd.dtsi

        gpio-leds {
                compatible = "gpio-leds";
                pinctrl-names = "default";
                pinctrl-0 = <&gpio_led_active>;
                led-red {
                        label = "red";
                        default-state = "keep";
                        gpios = <&tlmm 12 0x00>;
                };
                led-blue{
                        label = "blue";
                        default-state = "off";
                        gpios = <&tlmm 97 0x00>;
                };
                led-green{
                        label = "green";
                        default-state = "off";
                        gpios = <&tlmm 98 0x00>;
                };
        };
kernel/msm-4.9/arch/arm64/configs/sq80x_defconfig

CONFIG_LEDS_GPIO=y

串口

除了 adb 还可以使用串口,但是注意,只有屏幕点亮的情况下,串口命令才能正常工作。 一般先要用 su 提示为 root 用户,然后再使用各种命令。

参考

gpio按键驱动
https://blog.csdn.net/syn_dyf/article/details/104366146

高通GPIO驱动(DTS方式)
https://www.cnblogs.com/linhaostudy/p/8372777.html

高通GPIO配置简介
https://blog.csdn.net/ldinvicible/article/details/52421640

高通DTS 配置 GPIO 中断
https://ciellee.blog.csdn.net/article/details/101226749

高通平台中gpio简单操作和调试
https://blog.csdn.net/s_jason/article/details/73864103?spm=1001.2101.3001.6650.9&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-9.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-9.no_search_link

高通平台GPIO pinctrl调试心得
https://blog.csdn.net/yxw0609131056/article/details/80662462

高通平台直接通过adb控制GPIO电平
https://blog.csdn.net/lhh_qrsly/article/details/110939319?spm=1001.2101.3001.6650.17&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-17.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-17.no_search_link

android控制gpio实现对小灯读写(一)
https://blog.csdn.net/zhonglunshun/article/details/70312945
android驱动学习---led实验
https://www.iteye.com/blog/koliy-1424304

Android字符设备驱动及应用层从jni控制GPIO实战
https://blog.csdn.net/qf0727/article/details/52856490
android jni控制gpio (rk3288)
https://www.cnblogs.com/CZM-/p/9622663.html

今天调试广和通的串口,发现发送没有问题,接收都是乱码。

和供应商联系了之后,解决了这个问题。

确认是否是串口休眠引起的问题。

  1. echo -1 > /sys/bus/platform/devices/7af0000.uart/power/autosuspend_delay_ms 执行这个命令,关闭串口自动休眠。
  2. 重新测试,发现接收正常了,没有乱码。

自动设置串口不休眠。

  1. SQ80X-Android10/kernel/msm-4.9/drivers/tty/serial/msm_serial_hs.c 修改这个文件,

    -       pm_runtime_set_autosuspend_delay(uport->dev, 100);
    +       pm_runtime_set_autosuspend_delay(uport->dev, -1);
  2. 重新编译测试。

准备底包

  1. 把供应商给出的出厂镜像解压
  2. 创建自己的烧录文件夹 customer_sw
  3. 把厂商文件夹中的 rawprogram0_update_original.xml 复制到 customer_sw 中,把厂商提供的 ptool.py 也放到 customer_sw 中。
  4. 安装 python 2.7.6
  5. 运行 python ./ptool.py -x rawprogram0_update_original.xml 生成一系列的文件。
  6. 生成文件中 rawprogram0.xmlpatch0.xml 就是 qfil 需要使用的。
  7. 从厂商文件夹中复制 prog_emmc_firehose_8917_ddr.mbncustomer_sw 中.

指定烧录镜像

rawprogram0.xml 中所有的 ap 侧需要用的可以保留, bp 侧的直接 filename="" 这样即可。 注意:

  1. 一般 persist.img 这个可以不用。
  2. 如果有某些特殊修改,供应商会提供 devcfg,那么 rawprogram0.xml 中对应条目需要指明 filename。

准备镜像

rawprogram0.xml 中所有 filename 没有留空的,相应的镜像从 out 文件夹下面复制到 customer_sw 中。

qfil 配置

  1. download configuration 中,勾选 reset after download,取消勾选 erase all before download
  2. 选择 flat build
  3. select programmer 中选择 prog_emmc_firehose_8917_ddr.mbn
  4. load xml 中 rawprogrammer 中选择 rawprogram0.xml
  5. load xml 中 patch 中选择 patch0.xml
  6. download

编译环境配置问题。

  1. 不是输入 source build/envsetup.sh 而是 source build/envsetup.sh SQ808_CN_10_00
  2. 然后再 lunch sq80x_64-userdebug

dts 配置问题。

  1. out/target/product/sq80x_64/obj/KERNEL_OBJ/arch/arm64/boot/dts/qcom/ 这个文件夹删除掉。
  2. kernel/msm-4.9/arch/arm64/boot/dts/qcom/Makefile 删除 dts-dirs += sq808-fttest

类似的核心芯片情况下,下载烧录 分包 的时候都是使用的 qpst,具体过程如下:

  1. 检查端口不是 9008
  2. flat build
  3. 加载 prog_emmc_firehose_8917_ddr.mbn
  4. 加载 xml, 这里注意,移远是 rawprogram_unsparse.xml, 广和通是 rawprogram0_update.xml,加载 patch0.xml
  5. download

备注

  • 如果广和通整包下载,好像是选择 rawprogram_unsparse.xml
  • 广和通编译的时候,也不是 source build/envsetup.sh 而是 source build/envsetup.sh SQ808_CN_10_00
  • 然后使用 ptool.py 对应的文档来做。相应的 xml 文件可以和 移远的对照改动。
  • 广和通的分包脚本在 win 下可以运行,在 ubuntu 下面有问题。
  • 如果开机只能进入fastboot, 基本可以认为是 boot.imgdtbo.img 有问题。

getevent -l

可以查看 kernel 具体上报上来的按键信息

查看按键有没有注册中断。

  1. cat proc/interrupts | grep home 这个可以看 home 键有没有注册中断。
  2. cat proc/interrupts | grep volume_up 这个可以对照着看这个按键中断注册的情况。

查看设备树中有没有相应的按键节点

ls sys/firmware/devicetree/base/soc/gpio_keys/ 可以查看所有的按键节点。

查看 bid

getprop | grep bid

核对 dtsi 文件

确保 home 按键是在 gpio_key 下面的子节点。

参考:

【实习周记】Android getevent.c源码分析
https://blog.csdn.net/LeeDuoZuiShuai/article/details/97536678

android Input子系统分析
https://blog.csdn.net/xiaoxiaoyu1107/article/details/39400199#overview
android Input子系统分析(内核层->android系统层)
https://www.cnblogs.com/MMLoveMeMM/articles/4119812.html

确定 dts 文件

  1. 直接从串口打印的 log 里面,搜索 Machine,正常就会出现后面的机器标识了,我这边是 QRD
    [    0.000000] OF: fdt:Machine model: QRD
  2. SC200R_Android10.0_R04_r023/kernel/msm-4.9/arch/arm64/boot/dts/qcom$ 下面搜索 QRD
    $ grep -R "\"QRD\""
    qm215-qrd-overlay.dts:  model = "QRD";
    sdm439-qrd-overlay.dts: model = "QRD";
    qcm2150-qrd-overlay.dts:        model = "QRD";
    sdm632-qrd-overlay.dts: model = "QRD";
    sdm429-qrd-overlay.dts: model = "QRD";
  3. 在怀疑的 dts 里面的 model 后面增加一些字符,然后重新编译 kernel,查看打印 log。就能确定到底是哪一个 dts 了,我的如下:
    [    0.000000] OF: fdt:Machine model: QRD qrm215-qrd-overlay

最终的 dts 文件内容,只能通过反编译 fdt 才能知道了。

  1. android 启动后,通过 adb 获取 fdt 文件。 adb pull /sys/firmware/fdt ./
  2. 把 aosp 源码中的 dtc 文件复制出来, ./prebuilts/misc/linux-x86/dtc/dtc
  3. 把 fdt 转为 dts 文件,就可以查看最终的 dts 了。 dtc -I dtb -O dts fdt -o tmp.dts

查看 dts 的包含关系。

使用 SC200R_Android10.0_R04_r023/kernel/msm-4.9/arch/arm64 下面的 DeviceTreeMap.py 可以解析 dts 的相互包含关系。

参考

高通平台dts的匹配过程分析
https://blog.csdn.net/armfpga123/article/details/54313700

高通平台8953 Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇)
https://blog.csdn.net/aiku969/article/details/79878072

如何找到kernel所用的dtsi
https://blog.csdn.net/u013308744/article/details/50204693

Linux DTS(Device Tree Source)设备树详解之三(高通MSM8953实例分析篇)
https://radia.blog.csdn.net/article/details/76574727

Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇)
https://radia.blog.csdn.net/article/details/70800076

linux/android代码中对于不同项目中conf、dts、defconfig文件的处理方法
https://radia.blog.csdn.net/article/details/78270181?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link

Linux内核defconfig在哪,如何确定使用的kernel defconfig和dts配置文件 比较实用 新手福利...
https://blog.csdn.net/weixin_42318030/article/details/116820657?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242.1

如何确定使用的kernel defconfig和dts配置文件 比较实用 新手福利
https://blog.csdn.net/weixin_42082222/article/details/104663389

高通平台defconfig文件的确定
https://blog.csdn.net/qwaszx523/article/details/71425594
初识defconfig
https://www.akr-developers.com/d/108
Linux内核defconfig在哪,如何确定使用的kernel defconfig和dts配置文件 比较实用 新手福利...
https://blog.csdn.net/weixin_42318030/article/details/116820657

如果需要 android 开机时,串口就是 777 的权限,可以修改 device/qcom/msm8937_32/init.target.rc 文件。

on boot
    start rmt_storage
    insmod /system/lib/modules/adsprpc.ko
    chmod 0660 /dev/ttyMSM1
    chmod 0777 /dev/ttyMSM2

类似于这样的改法即可。

改完之后,需要整体编译才行,单独编译 kernel 是没用的,编译 system 和 vendor ,又因为校验通不过,所以只能整体编译,整体烧录。