Linux下SPI设备驱动实验:创建SPI节点及SPI设备子节点

一. 简介

SPI 驱动框架和 I2C 很类似,都分为主机控制器驱动和设备驱动。主机控制器驱动一般由半导体厂商写好,我们来编写SPI设备驱动代码。
前一篇文章分析了 IMX6U系列芯片的 SPI中片选信号的处理,文章如下:
I.MX6ULL SPI 主机控制器驱动:软件片选处理(片选信号)-CSDN博客
接下来我们就来学习如何在 Linux 下编写 SPI 设备驱动。本实验的最终目的就是驱动 I.MX6U
ALPHA 开发板上的 ICM-20608 这个 SPI 接口的六轴传感器,可以在应用程序中读取 ICM-20608
的原始传感器数据。

这里主要学习创建SPI节点及ICM20608设备(SPI从设备)子节点。

二.  ICM20608设备的硬件原理图

ICM20608设备的硬件原理图如下所示:

通过硬件原理图可以看出,ICM20608设备(SPI设备)的SPI使用的是(IMX6ULL的)SPI3接口,的四个IO对应如下:

SPI3_CS  ->  UART2_TXD   //片选信号
SPI3_SCLK  -> UART2_RXD  //时钟信号
SPI3_MISO  -> UART2_RTS  //主收从发
SPI3_MOSI  -> UART2_CTS  //主发从收

三. 创建SPI节点及SPI设备子节点

这里学习支持设备树的情况下,通过设备节点信息来描述SPI设备信息,方法就是在设备树文件中创建SPI节点及SPI设备节点,IO的pinctrl节点。

1. 创建IO的pinctrl节点

打开ubuntu系统,通过 vscode软件打开 Linux内核源码(NXP官方提供。在 imx6ull-14x14-evk.dts设备树文件中添加 SPI的 pinctrl节点信息。

注意:这里开发板使用的 Nand_Flash版的ALPHA开发板,所对应的设备树文件为 imx6ull-alientek-nand.dts,设备树根节点不在这个文件中,所以要找到 imx6ull-alientek-nand.dts调用的上层设备树文件imx6ull-14x14-evk.dts。调用关系如下:

imx6ull-alientek-nand.dts -> imx6ull-14x14-evk-gpmi-weim.dts -> imx6ull-14x14-evk.dts

打开 imx6ull-14x14-evk.dts设备树文件,在 "&iomuxc"节点下添加 SPI的 pinctrl节点:

/*WeiWuXian //2024/04/15*/pinctrl_ecspi3: icm20608{fsl,pins = <MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20  0x10b0 /* CS */MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK 0x10b0 /* SCLK */MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI   0x10b0 /* MOSI */MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO   0x10b0 /* MISO */>;};   

UART2_TX_DATA 这个 IO ICM20608 的片选信号,这里我们并没有将其复用为 ECSPI3

SS0 信号,而是将其复用为了普通的 GPIO 。这里选择软件片选使用,NXP的针对 IMX6U系列的SPI 主机控制器驱动中,有实现SPI的软件片选!!

注意:这里添加好 IO以后,需要在设备树文件中检查这四个IO是否有其他设备在使用,复用的话,这里配置就不能使用了。如果有其他设备使用到,则需要删除掉。

在imx6ull-14x14-evk.dts设备树文件中 分别搜索 UART2_TX,UART2_RX,UART2_CTS,以及UART2_RTS,有其他设备使用则需要屏蔽掉,如下设备有使用到则屏蔽掉:

		pinctrl_uart2: uart2grp {fsl,pins = </*	MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX	0x1b0b1MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX	0x1b0b1  */MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS	0x1b0b1MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS	0x1b0b1>;};pinctrl_uart2dte: uart2dtegrp {fsl,pins = </*	MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX	0x1b0b1MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX	0x1b0b1  */MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS	0x1b0b1MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS	0x1b0b1>;};
..........................pinctrl_flexcan2: flexcan2grp{fsl,pins = </*	MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX	0x1b020MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX	0x1b020  */>;};

2. 创建SPI节点及SPI设备子节点

 关于所创建的SPI节点可以查看 SPI节点的绑定文档,在Linux内核源码如下目录下:

/linux-imx-rel_imx_4.1.15_2.1.0_ga\Documentation\devicetree\bindings\spi\fsl-imx-cspi.txt

也就是 fsl-imx-spi.txt 绑定文档 ,该文档说明了SPI节点如何创建,包括SPI节点必须写的属性或可选的属性,也会有SPI节点的举例。

我们也可以参考 imx6qdl-sabresd.dtsi 这个设备树头文件中关于 SPI节点的内容,在此文件里面找到如下所示内容:

&ecspi1 {fsl,spi-num-chipselects = <1>;cs-gpios = <&gpio4 9 0>;pinctrl-names = "default";pinctrl-0 = <&pinctrl_ecspi1>;status = "okay";flash: m25p80@0 {#address-cells = <1>;#size-cells = <1>;compatible = "st,m25p32";spi-max-frequency = <20000000>;reg = <0>;};
};

imx6ull-14x14-evk .dts 文件中并没有 ecspi3 节点,这是因为 NXP 官方的 6ULL EVK 开发板上没有连接 SPI 设备。

在 imx6ull-14x14-evk.dts设备树文件的最后,添加 SPI节点及SPI设备子节点:

&ecspi3 {fsl,spi-num-chipselects = <1>; /*片选数量*/cs-gpios = <&gpio1 20 0>;  /*设置为软件片选*/pinctrl-names = "default";pinctrl-0 = <&pinctrl_ecspi3>;status = "okay";  icm20608: icm20608@0 {compatible = "alientek,icm20608"; /*设备与驱动匹配(设备树匹配方法)*/spi-max-frequency = <8000000>; /*SPI从设备icm20608最大支持频率*/reg = <0>;  /*SPI通道*/};
};

这里也需要检查  gpio1 20是否有其他设备使用,即在 imx6ull-14x14-evk.dts设备树文件中进行搜索 "gpio1 20"字符串是否在其他设备中使用到,如果有就必须删除或屏蔽掉。

& ecspi3: 意思是向 ecspi3节点追加内容,根设备树文件 imx6ull.dtsi中其实已经存在 ecspi3节点(NXP官方写的),这里是在NXP官方提供的 ecspi3节点信息基础上追加(或更改)信息。

2 行,设置当前片选数量为 1 ,因为就只接了一个 ICM20608

3 行,一定要使用  “cs-gpios” 属性来描述片选引脚,SPI 主机驱动就会控制片选引脚,SPI主机控制器驱动实现了SPI的软件片选功能, 后面我们在编写SPI设备驱动时,软件上不用手动设置片选电平的高低。

5 行,设置 IO 要使用的 pinctrl 子节点,也就是我们在示例代码 62.5.1.1 中新建的pinctrl_ecspi3

6 行, imx6ull.dtsi 文件中默认将 ecspi3 节点状态 (status) 设置为“ disable ”,这里我们要将其改为 “ okay ” 。

8~12 行,icm20608 设备子节点,因为 icm20608 连接在 ECSPI3 的第 0 个通道上,因此,@后面为 0

9 行设置节点属性兼容值为“alientek,icm20608”。

10 行设置 SPI 最大时钟频 率为 8MHz,这是 ICM20608 SPI 接口所能支持的最大的时钟频率。

11 行,icm20608 连接在通道 0 上,因此 reg 0

编译设备树文件

imx6ull-alientek-emmc.dts 文件修改完成以后,重新编译设备树文件
ubuntu终端进入 上面的Linux内核源码的根目录下,输入如下命令编译设备树:
make dtbs

这里可以正常编译通过。会生成新的设备树文件 imx6ull-alientek-nand.dtb。

接下来开发板上电后加载运行新的设备树文件,测试SPI节点及icm20608设备子节点是否创建好。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2968970.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

学习Python先从了解Python开始

Python是一种高级编程语言&#xff0c;它的语法简洁易读&#xff0c;功能强大&#xff0c;应用领域广泛。Python不仅适用于数据科学、机器学习、Web开发等领域&#xff0c;还可以用于自动化脚本编写、游戏开发等。在本文中&#xff0c;我们将探讨Python的特点、应用领域以及未来…

噪声系数测试之增益法

提到增益法测试噪声系数,大家并不陌生,这是一种简洁的测试方法,精度不如Y因子法,但是在某些测试场合,比如只有频谱仪而没有噪声头时,且待测件具有非常高的增益时,就可以使用增益法测试噪声系数。 增益法测试噪声系数的连接示意图如图1所示,其思路为:DUT输入端端接50 …

【UE 材质】雨水流淌效果

在上一篇&#xff08;【UE 材质】雨滴效果&#xff09;基础上继续实现雨水从顶部沿着墙壁侧面向下流淌的效果 效果 步骤 1. 下载所需纹理 2. 新建一个材质函数&#xff0c;这里命名为“MF_Weather_Drips”&#xff0c;在材质函数中添加如下节点 其中输入节点的默认值分别为…

【leetcode面试经典150题】61. 反转链表 II(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

【MIT6.824】lab2C-persistence, lab2D-log compaction 实现笔记

引言 lab2C的实验要求如下 Complete the functions persist() and readPersist() in raft.go by adding code to save and restore persistent state. You will need to encode (or “serialize”) the state as an array of bytes in order to pass it to the Persister. Us…

WebLogic 数据源连接泄露

编码时&#xff0c;有时会忘记释放使用的数据源连接&#xff0c;造成连接泄露&#xff0c;没有连接资源可用。 现象 java.sql.SQLException: Cannot obtain XAConnectionat weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1691)at weblogic.jdbc.jta.…

hackthebox - Redeemer

2024.4.19 TASK 1 Which TCP port is open on the machine? 6379 TASK 2 Which service is running on the port that is open on the machine? redis TASK 3 What type of database is Redis? Choose from the following options: (i) In-memory Database, (ii) Traditiona…

logisim 图解超前进位加法器原理解释

鄙人是视频作者&#xff0c;文件在视频简介的网盘链接。 找规律图解超前进位加法器与原理解释_哔哩哔哩_bilibili 一句话就是“把能导致进位到这个位置的情况全都穷举一遍。” 穷举情况看图中算式。 视频讲解比较啰嗦。

JavaFX--基础简介(1)

一、介绍 中文官网&#xff1a;JavaFX中文官方网站OpenJFX 是一个开源项目,用于桌面、移动端和嵌入式系统的下一代客户端应用程序平台。openjfx.cn是OpenJFX(JavaFX)的标准中文翻译网站&#xff0c;致力于方便开发者阅读官方文档和教程。https://openjfx.cn/ JavaFX 是一个开…

GUI04-深入分析基于框架窗口的应用

复杂应用最常见的桌面程序&#xff0c;基本都使用框架式的主窗口。本节涉及&#xff1a; 常见的应用中&#xff0c;哪些使用了框架窗口&#xff1f;wxWidgets 项目配置详解&#xff08;为将来手工写wxWigets项目配置打基础&#xff09;&#xff1b;复习如何使用Code::Blocks的向…

javaagent使用

Java Agent是什么&#xff1f; Java Agent是Java平台提供的一个强大工具&#xff0c;它可以在运行时修改或增强Java应用程序的行为。是在JDK1.5以后引入的&#xff0c;它能够在不影响正常编译的情况下修改字节码&#xff0c;相当于是在main方法执行之前的拦截器&#xff0c;也叫…

MySQL高级(索引-性能分析-profile)

show profiles 能够在做SQL优化时帮助我们了解时间都耗费到哪去了。通过 have_profiling参数&#xff0c;能够看到当前MySQL 是否支持 profile 操作&#xff1a; select have_profiling 默认 profiling 是关闭的 select profiling; 可以通过 set 语句在 session / global 级…

unordered系列关联式容器和开散列与闭散列的模拟实现

文章目录 unordered系列关联式容器底层结构哈希的概念哈希冲突哈希函数常见哈希函数 哈希冲突的解决闭散列开散列 闭散列模拟实现基本框架基本函数 开散列模拟实现 unordered系列关联式容器 之前我们讲到&#xff0c;STL提供了底层为红黑树的一系列关联式容器&#xff0c;可以…

java项目连接sqlserver时报ssl相关错误,如何解决?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

MySQL数据库-优化慢查询

1、什么是慢查询&#xff1f; 慢查询就是SQL执行时间过长&#xff0c;严重影响用户体验的SQL查询语句。当它频繁出现时数据库的性能和稳定性都会受到威胁 慢查询是数据库性能瓶颈的常见原因&#xff0c;是指SQL执行时间超过阈值&#xff1b;可能由于复杂的连接、缺少索引、不恰…

ssd回收站清空几天可找回?ssd数据回收站删除如何恢复

随着固态硬盘&#xff08;SSD&#xff09;的普及&#xff0c;越来越多的用户选择使用SSD作为他们的主要存储设备。然而&#xff0c;与传统的硬盘相比&#xff0c;SSD的数据恢复可能更具挑战性。当我们在SSD上误清空回收站后&#xff0c;很多人都会问&#xff1a;这些数据还能恢…

浅浅了解一下 LibTorch

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ LibTorch 是 PyTorch 提供的一个二进制发行版&#xff0c;包含了所有必要的头文件、库和 CMake 配置文件&#xff0c;便于开发者依赖 PyTorch 开发应用。用户可以从 PyTorch 官网下载包含最新 LibTorch…

超实用!2024年必看的10个导航栏设计

如果说到UI设计中最常用的组件&#xff0c;一定有导航栏。对一个网站/APP来说&#xff0c;导航栏就像旅途中的指南针&#xff0c;告诉用户现在在哪里&#xff0c;可以到哪里去。 一个直观、易用的导航栏能显著提升用户体验&#xff0c;增加网站的点击率和浏览量。不过&#xf…

React Hooks(常用)笔记

一、useState&#xff08;保存组件状态&#xff09; 1、基本使用 import { useState } from react;function Example() {const [initialState, setInitialState] useState(default); } useState(保存组件状态) &#xff1a;React hooks是function组件(无状态组件) &#xf…

LeetCode 113—— 路径总和 II

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 看到树的问题一般我们先考虑一下是否能用递归来做。 假设 root 节点的值为 value&#xff0c;如果根节点的左子树有一个路径总和等于 targetSum - value&#xff0c;那么只需要将根节点的值插入到这个路径列表中…