【问题标题】:SPI driver, searching where to startSPI驱动,搜索从哪里开始
【发布时间】:2019-06-05 12:54:31
【问题描述】:

我是 Android 开发新手,但我想编写一个 SPI 驱动程序来连接一个 SPI IC,然后是一个 Android 应用程序来从 IC 发送和接收数据。

从那里,我真的不知道在哪里创建驱动程序(以及它应该包含什么)以及如何在此之上链接应用程序。我有一个可定制的 Android 内核(9.0 Pie,APQ8096_LA.UM.7.5.r1-03100-8x96.0_P_v5.0)及其所有 .dts、.dtsi、.c 等。我还有一个评估板和足够的映射文档。

我用谷歌搜索了一个星期,但没有找到我要找的东西。我了解了一些关于设备树系统的知识。由于我有一个Snapdragon 820 msm8996,我修改了“msm8996-blsp.dtsi”和“msm8996-pinctrl.dtsi”。 我有这段代码:

msm8996-pinctrl.dtsi

&soc {
...
    spi_0 {
        spi_0_active: spi_0_active {
            spi_0 {
                pins = "gpio0", "gpio1", "gpio2", "gpio3";
                function = "blsp_spi1";
                drive-strength = <6>;
                bias-disable;
            };

        };

        spi_0_sleep: spi_0_sleep {
            spi_0 {
                pins = "gpio0", "gpio1", "gpio2", "gpio3";
                function = "blsp_spi1";
                drive-strength = <6>;
                bias-disable;
            };
        };
    };
...          

msm8996-blsp.dtsi

&soc {
...
    spi_0: spi@7575000 { //QUP Base address for BLSP1_QUP0
        compatible = "qcom,spi-qup-v2"; //Manufacturer and Model
        #address-cells = <1>;
        #size-cells = <0>;
        reg-names = "spi_physical", "spi_bam_physical";
        reg = <0x07575000 0x600>,
        <0x07544000 0x2b000>;
        interrupt-names = "spi_irq", "spi_bam_irq";
        interrupts = <0 95 0>, <0 238 0>;
        spi-max-frequency = <5000000>; //Maximum supported frequency in HZ
        qcom,infinite-mode = <0>;
        qcom,use-bam; // Enable BAM mode
        /* Add BAM pipes */
        qcom,bam-consumer-pipe-index = <12>;
        qcom,bam-producer-pipe-index = <13>;
        qcom,ver-reg-exists;
        qcom,master-id = <86>;
        qcom,use-pinctrl;
        pinctrl-names = "spi_default", "spi_sleep";
        pinctrl-0 = <&spi_0_active>;
        pinctrl-1 = <&spi_0_sleep>;
        clock-names = "iface_clk", "core_clk";
        clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
        <&clock_gcc clk_gcc_blsp1_qup1_spi_apps_clk>;
        status = "enabled";
    }
...

我用

构建这个内核
$ ./build.sh msm8996 -j $(nproc)

我用 fastboot 刷了我的评估板,然后我进入了 adb。

$ adb root
$ adb wait-for-device
$ adb shell
# cd /sys/class/spi_master
# ls
// Nothing here

考虑到我的 spi 地址是在 @7575000 定义的,我希望输出是

# spi_0

我的代码启用它是否正确(我还不擅长设备树)?如果是这样,为什么 adb 不可见,我应该如何使其可见?使用 Android 应用程序访问此 SPI 的下一步应该是什么?

我搜索了stackoverflow等很多地方,但为Android编写设备驱动程序似乎并不常见......

【问题讨论】:

  • @Fantômas 你为什么删掉标题中的“Android”?
  • 因为绝对不需要在 TITLE 中重复一个 TAG。
  • 标题编辑的元参考:this onealso this,可能还有其他一些。如果产品/软件名称作为普通英语句子的一部分,我不介意留下产品/软件名称,但此页面的 &lt;title&gt; 已经以 android 为前缀,因为这是问题的主要标签。
  • 所以这是关于 SPI 控制器驱动程序(与 SPI 设备驱动程序相比)。设备树文件“告诉”Linux 设备驱动子系统将哪些值传递给哪个驱动程序(spi 控制器基地址到哪个 spi 控制器驱动程序)。驱动程序仍然有一个 _probe() 函数来检查外围设备是否按预期响应并对其进行初始化 - 如果失败,您将在 sysfs 中没有 spi_master。您对 C 和内核编译的信心如何?您可以将 printk 添加到驱动程序的 probe() 中吗?或者在此之前,检查 spi 主驱动程序是否真的知道您的设备树字符串(我相信使用了“兼容”)。
  • @domen 如果我理解,有 2 层“内核”驱动程序:与设备/外围驱动程序(即 SPI、数据总线、内存等)通信的驱动程序(称为自定义驱动程序)。那么,我需要编写一个自定义驱动程序,通过 android SPI 设备驱动程序以结构化方式与我的设备通信吗?对于 C 语言,我对它完全有信心,但对内核编译完全没有信心,这是我第一次使用它。

标签: android adb linux-device-driver spi device-tree


【解决方案1】:

您无需为 snapdragon 编写 SPI 驱动程序,它已经在内核中。也许你需要写一些东西把它连接到你的设备上。

将 spi 控制器暴露给用户空间的最简单方法是 mapping spidev to your device

您的内核(使用CONFIG_SPI_SPIDEV=y 配置标志添加)和设备树中必须支持此功能总线下

类似这样的:

&spi_0 {
   spidev@1 {
      #address-cells = <1>;
      #size-cells = <1>;
      compatible = "linux, spidev";
      spi-max-frequency = <20000000>;
      reg = <1>;   
   };
};

设备树与内核一起编译,其中包含您的 gpio 映射和 DMA 配置,因此同一个内核可以为多个板提供服务。确保 android 正在使用您新编译的内核和设备树,有时它会意外使用其中一个预编译的内核进行构建。

在这些步骤之后,您应该在 /dev 中有一个 /dev/spidev0.0(或其他数字) 配合ioctl可以使用复杂的运算。

要验证您的软件是否已完全连接到您的 SPI 总线,请将一根电线从 MOSI 连接到 MISO,SPI writeread 命令将回显它接收到的相同数据 - 移除电线并验证没有任何东西。

此时您应该开始与传感器通信,并开发其控制软件。

在上述情况下,我会开始检查内核启动的日志打印,以验证它正确识别硬件并加载驱动程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    相关资源
    最近更新 更多