Linux下SPI设备驱动实验:使用内核提供的读写SPI设备中的数据的函数

news/2024/5/2 15:06:12

一. 简介

前面文章的学习,已经实现了 读写SPI设备中数据的功能。文章如下:

Linux下SPI设备驱动实验:验证读写SPI设备中数据的函数功能-CSDN博客

本文来使用内核提供的读写SPI设备中的数据的API函数,来实现读写SPI设备中数据。

二.  Linux下SPI设备驱动实验:使用内核提供的读写SPI设备中的数据的函数

1. 内核提供的读写SPI设备中的数据的函数

所使用内核源码为NXP官方提供。读写SPI设备中的数据的函数所在内核源码路径为:

/linux-imx-rel_imx_4.1.15_2.1.0_ga/include/linux/spi/spi.h

(1)  读取SPI设备中数据的函数

spi_read函数
int spi_read(struct spi_device *spi, void *buf, size_t len)
spi_write_then_read函数
/* this copies txbuf and rxbuf data; for small transfers only! */
int spi_write_then_read(struct spi_device *spi, const void *txbuf, unsigned n_tx,void *rxbuf, unsigned n_rx);

(2) 向SPI设备中写数据的函数

int spi_write(struct spi_device *spi, const void *buf, size_t len)

2.  使用内核提供的读写SPI设备中的数据的函数

这里的代码与前一篇文章相比,不同的是 读写SPI设备中数据的函数实现。

读写SPI设备中数据的函数实现如下(spi_icm20608.c文件中):

static int spi_write_regs(struct icm20608_Dev* dev, u8 reg_addr, void* buf, int len)
{int ret = 0;unsigned char value = 0;struct spi_device* spi_dev = (struct spi_device*)dev->private_data;value = reg_addr & ~0x80; //最高为位清0(写标志位)//发送要写入的寄存器地址ret = spi_write(spi_dev, &value, 1); if(ret)printk("spi_write_regs: spi_write reg_addr error\n");//发送要写入SPI设备中的数据ret = spi_write(spi_dev, buf, len); if(ret)printk("spi_write_regs: spi_write  data error\n");return ret;
}static int spi_read_regs(struct icm20608_Dev* dev, u8 reg_addr, void* buf, int len)
{int ret = 0;unsigned char value = 0;struct spi_device* spi_dev = (struct spi_device*)dev->private_data;value = reg_addr | 0x80; //最高为置1(读标志位)
#if  0    //发送要读取的寄存器的地址ret = spi_write(spi_dev, &value, 1);if(ret < 0)printk("spi_read_regs: spi_write reg_addr error\n");//接收SPI设备中的数据 ret = spi_read(spi_dev, buf, len);if(ret)printk("spi_read_regs: spi_read data error\n");
#endifspi_write_then_read(spi_dev, &value, 1, buf, len);return ret;
}/*ICM20608设备初始化(即SPI设备初始化)*/
static int icm20608_register_init(struct icm20608_Dev* dev)
{unsigned char value = 0;spi_write_reg_onebyte(&icm20608_dev, ICM20_PWR_MGMT_1, 0x80); /*复位,复位后为0x40,睡眠模式 */mdelay(50);spi_write_reg_onebyte(&icm20608_dev, ICM20_PWR_MGMT_1, 0x01);  /*关闭睡眠,自动选择时钟 */mdelay(50);value = spi_read_reg_onebyte(&icm20608_dev,ICM20_WHO_AM_I);printk("ICM20_WHO_AM_I: 0x%02X\r\n", value);if((value != ICM20608G_ID) && (value != ICM20608D_ID)){return 1;}value = spi_read_reg_onebyte(&icm20608_dev,ICM20_PWR_MGMT_1);printk("ICM20_PWR_MGMT_1: 0x%02X\r\n", value);return 0;
}

可以看出,读SPI设备中数据的实现函数中,有一段屏蔽的代码段,如下代码段:

    ret = spi_write(spi_dev, &value, 1);if(ret < 0)printk("spi_read_regs: spi_write reg_addr error\n");//接收SPI设备中的数据 ret = spi_read(spi_dev, buf, len);if(ret)printk("spi_read_regs: spi_read data error\n");

这里先写了SPI设备的寄存器地址,然后从SPI设备中读取数据。

经过测试,这段代码最后 SPI读取数据是不对的,也就是存在问题。正点原子的左神说是,可能的原因是 在发送寄存器地址前片选信号是拉低的,之后片选信号拉高了,然后在从SPI深圳中读取数据前,片选信号再拉低。这样导致时序混乱。

所以,这里从SPI设备中读取数据调用了 spi_write_then_read函数,不过根据该函数的注释信息,说这个函数只适用于小数量的数据传输!

三.  测试

将 编译的驱动进行编译后,将新生成的驱动模块拷贝到开发板系统中,加载驱动模块如下:

可以看出,寄存器ICM20_PWR_MGMT_1在 ICM20608初始化函数中最后写入了0x01,这里读出来也是 0x01,确定读写SPI设备函数运行正常。

卸载模块:

卸载驱动模块时, remove函数也运行了,也不存在错误的信息。


http://www.mrgr.cn/p/86887860

相关文章

4*5的矩阵(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int i 0;int j 0;int result 0;//嵌套循环输出&#xff1b;for (i 1; i < 4; i){//列…

【unity】【C#】游戏音乐播放和发布

今天我们来认识一下有关 unity 音乐的一些知识 我们先创建 AudioClips 文件夹&#xff0c;这个文件夹通常就是 unity 中存放音乐的文件夹&#xff0c;然后拖进音乐文件进去 这里为大家提供了两个音乐&#xff0c;有需要可以自取 百度网盘&#xff1a;https://pan.baidu.com/s…

Hotcoin4月16日上新热门资产:头部RWA技术提供方Centrifuge(CFG)

Hotcoin持续为全球600万用户发掘优质潜力资产&#xff0c;热门币种交易上热币。一文快速了解今日上新资产:Centrifuge(CFG) 推荐指数 8.2 交易对 CFG/USDT 交易时间 4月16日 19:00 资产赛道 RWA 项目简介 Centrifuge是一个去中心化资产融资协议&#xff0c;专注于释放现实世界资…

使用Python工具库SnowNLP对评论数据标注(二)

这一次用pandas处理csv文件 comments.csv import pandas as pd from snownlp import SnowNLPdf pd.read_csv("C:\\Users\\zhour\\Documents\\comments.csv")#{a: [1, 2, 3], b: [4, 5, 6], c: [7, 8, 9]}是个字典 emotions[] for txt in df[sentence]:s SnowNLP(…

二刷大数据(三)- Flink1.17

目录 Flink概念与SparkStreaming区别分层API 工作流程部署模式**Local Mode****Standalone Mode****YARN Mode****Kubernetes Mode****Application Mode** 运行架构stand alone 核心概念算子链任务槽 窗口窗口**窗口的目的与作用****时间窗口&#xff08;Time Windows&#xff…

uniapp中scroll-view初始化的时候 无法横向滚动到某个为止

项目需求 实现日历&#xff08;13天&#xff09;默认高亮第六天 并定位到第六 左边右边各六天&#xff08;可以滑动&#xff09; 直接上代码 <template><scroll-view class"scroll-X":show-scrollbar"true" :scroll-x"scrollable":…

C++的线程

#include<iostream> #include<thread> #include<unistd.h> using namespace std; void myrun() {while(true){cout<<"I am a thread"<<endl;sleep(1);} } int main() {thread t(myrun);t.join();return 0; } 如果不添加-lpthread就会报…

2024年华中杯数学建模竞赛ABC题思路分析

简单分析一下各个题目可能需要用到的方法和模型&#xff0c;完整代码和成品论文见文末 A题 太阳能路灯光伏板的朝向设计问题: 1. 球面几何、天文学相关知识,如赤纬角、太阳高度角、时角等概念和公式 2. 太阳辐射模型,根据太阳能辐射强度、大气衰减系数等计算地表太阳辐射强度…

Day09 React———— 第九天

ReactRoter 一个路径 path 对应一个组件 component 当我们在浏览器中访问一个 path 的时候&#xff0c;path 对应的组件会在页面中进行渲染 基础用法 import { createBrowserRouter, RouterProvider } from "react-router-dom"; const router createBrowserRoute…

如何在Vue3中使用H.265视频EasyPlayer.js流媒体播放器?

H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;可支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff0c;能支持WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#…

3D可视化技术:研发基地的科技新篇章

在科技日新月异的今天&#xff0c;我们生活在一个充满无限可能性的时代。而在这个时代中&#xff0c;3D可视化技术正以其独特的魅力&#xff0c;引领着科技领域的新一轮变革。 3D可视化技术通过三维图像的方式&#xff0c;将现实世界或虚拟世界中的物体、场景等以立体、逼真的形…

【嵌入式之中断】

Cortex-M4集成了嵌套式矢量型中断控制器(Nested Vectored Interrupt Controller (NVIC))来实现高效的异常和中断处理。NVIC实现了低延迟的异常和中断处理&#xff0c;以及电源管理控制。它和内核是紧密耦合的。 凡是打断程序顺序执行的事件都称为异常&#xff08;exception&am…

VN6501使用方法(学习笔记)

1:总体简介 VNA6501可以进行CAN Stress测试&#xff0c;可以进行采样点测试。此外VN6501还能够定制&#xff0c;外围测试电路&#xff08;通过软件配置&#xff0c;部分情况是需要连接VN6501的部分接口&#xff09;。 关于外围测试电路&#xff08;添加电容&#xff0c;电阻&…

<计算机网络自顶向下> 可靠数据传输的原理(未完成)

可靠数据传输&#xff08;rdt&#xff1a;Reliable Data Transfer&#xff09;的原理 rdt在应用层&#xff0c;传输层和数据链路层都很重要是网络TOP10问题之一信道的不可靠特点决定了可靠数据传输rdt的复杂性rdt_send: 被上层&#xff08;如应用层&#xff09;调用&#xff0…

机器学习和深度学习--李宏毅(笔记与个人理解)Day11-12

Day11 when gradient is small…… 怎么知道是局部小 还是鞍点&#xff1f; using Math 这里巧妙的说明了hessan矩阵可以决定一个二次函数的凹凸性 也就是 θ \theta θ 是min 还是max&#xff0c;最后那个有些有些 哈 是一个saddle&#xff1b; 然后这里只要看hessan矩阵是不…

基于数据库现有表导出为设计文档

1.查询 SELECTCOLUMN_NAME 字段名,COLUMN_COMMENT 字段描述,COLUMN_TYPE 字段类型,false as 是否为主键 FROMINFORMATION_SCHEMA.COLUMNS wheretable_NAME region -- 表名2.查询结果 3.导出为excel

学习云计算HCIE选择誉天有什么优势?

誉天云计算课程优势实战性强 课程注重实践操作&#xff0c;通过实际案例和实验操作&#xff0c;让学员深入了解云计算的应用场景和实际操作技能。课程内容全面 涵盖所有云计算涉及的IT基础知识、服务器、存储、网络等方面的基础知识&#xff0c;开源操作系统Linux&#xff0c;开…

吴恩达机器学习笔记(1-1到2-1)

吴恩达机器学习笔记(1-1到2-1) https://www.bilibili.com/video/BV164411b7dx?p=1 https://www.bilibili.com/video/BV164411b7dx?p=2 https://www.bilibili.com/video/BV164411b7dx?p=3 https://www.bilibili.com/video/BV164411b7dx?p=4 机器学习-吴恩达 一、初学 1、什…

YAML教程-1-基础入门

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go YAML简介 YAML&#xff08;YAML Aint Markup Language&#xff09;是一种用于数据序列化的人类可读格式。它广泛用于配置文件、数据交换、持续集成/持续部署&#xff08;CI/CD&#xff09;等领域。YAML的设计目标…

注意,把Python库安装在一个环境里,可能会“非常危险”!

如果说谁写Python不用第三方库&#xff0c;我敬他是条汉子。如今到处是轮子的时代&#xff0c;Python第三方库管理成了开发者们头疼的问题。 可能在看这篇文章的很多人&#xff0c;都没用过Python虚拟环境&#xff0c;不知道安装Python库需要考虑版本兼容问题。 那么把所有要…