当前位置: 首页 > article >正文

【RK3588开发】SPI回环

SPI回环1内核SPI子系统使能修改内核配置需要先加载默认配置然后图形界面修改后需保存配置在以下目录下勾选图中的选项****Device Drivers —​ -[*] SPI support—至少勾选以下选项Rockchip SPI controller driverRockschip SPI controller misc devicesUser mode SPI device driver support2设备树spi0{statusokay;assigned-clockscru CLK_SPI1;assigned-clock-rates200000000;num-cs2;pinctrl-0spi0m2_cs0spi0m2_cs1spi0m2_pins;max-freq48000000;/* spi internal clk, dont modify */spi_dev0{compatiblerockchip,spidev;reg0;spi-max-frequency12000000;spi-lsb-first;};};这样写设备树系统会有个/dev/spidev0_0的设备这里0_0,代表第一个SPI总线0和片选03应用程序①SPI 驱动数据缓存机制在spidev驱动中有一个模块参数bufsiz可以设置每次传输的最大字节数默认值通常是一个内存页大小比如4096字节当需要传输大于缓存区大小的数据时需要多次传输。②程序源码字符串回环#includestdio.h#includestdlib.h#includestdint.h#includestring.h#includefcntl.h#includeunistd.h#includesys/ioctl.h#includelinux/spi/spidev.h#defineSPI_DEV_PATH/dev/spidev0.0intfd;staticunsignedmodeSPI_MODE_0;staticuint8_tbits8;staticuint32_tspeed1000000;// 设置SPI速度为1MHzstaticuint16_tdelay;voidtransfer(intfd,uint8_tconst*tx,uint8_t*rx,size_tlen){intret;structspi_ioc_transfertr{.tx_buf(unsignedlong)tx,.rx_buf(unsignedlong)rx,.lenlen,.delay_usecsdelay,.speed_hzspeed,.bits_per_wordbits,.cs_change0,// 设置为1以在每次传输前切换片选这里不切换片选};retioctl(fd,SPI_IOC_MESSAGE(1),tr);if(ret1){perror(SPI transfer failed);}}voidspi_init(void){intret;// 打开 SPI 设备fdopen(SPI_DEV_PATH,O_RDWR);if(fd0){perror(Cant open SPI device);exit(1);}// 设置 SPI 工作模式retioctl(fd,SPI_IOC_WR_MODE,mode);if(ret-1){perror(Cant set SPI mode);exit(1);}// 设置位数retioctl(fd,SPI_IOC_WR_BITS_PER_WORD,bits);if(ret-1){perror(Cant set bits per word);exit(1);}// 设置SPI速度retioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,speed);if(ret-1){perror(Cant set max speed);exit(1);}// 打印设置printf(SPI mode: 0x%x\n,mode);printf(Bits per word: %d\n,bits);printf(Max speed: %d Hz\n,speed);}intmain(intargc,char*argv[]){if(argc!2){printf(Usage: %s string_to_send\n,argv[0]);return1;}char*tx_bufferargv[1];// 获取要发送的字符串作为命令行参数// 初始化SPI接口spi_init();// 设置要接收数据的缓冲区unsignedcharrx_buffer[strlen(tx_buffer)1];// 执行SPI数据传输transfer(fd,tx_buffer,rx_buffer,strlen(tx_buffer));// 打印发送和接收的数据printf(Sent: %s\n,tx_buffer);printf(Received: %s\n,rx_buffer);// 关闭SPI设备close(fd);return0;}③程序源码文件回环#includestdio.h#includestdlib.h#includestdint.h#includestring.h#includefcntl.h#includeunistd.h#includesys/ioctl.h#includelinux/spi/spidev.h#includesys/stat.h#defineSPI_DEV_PATH/dev/spidev0.0#defineCHUNK_SIZE4096// 4KB 块大小适合大多数SPI控制器#defineFILE_SIZE(8*1024*1024)// 8MBintfd;staticunsignedmodeSPI_MODE_0;staticuint8_tbits8;staticuint32_tspeed12000000;staticuint16_tdelay;// SPI 传输函数voidtransfer(intfd,uint8_tconst*tx,uint8_t*rx,size_tlen){intret;structspi_ioc_transfertr{.tx_buf(unsignedlong)tx,.rx_buf(unsignedlong)rx,.lenlen,.delay_usecsdelay,.speed_hzspeed,.bits_per_wordbits,.cs_change0,};retioctl(fd,SPI_IOC_MESSAGE(1),tr);if(ret1){perror(SPI transfer failed);}}// SPI 初始化voidspi_init(void){intret;// 打开 SPI 设备fdopen(SPI_DEV_PATH,O_RDWR);if(fd0){perror(Cant open SPI device);exit(1);}// 设置 SPI 工作模式retioctl(fd,SPI_IOC_WR_MODE,mode);if(ret-1){perror(Cant set SPI mode);exit(1);}// 设置位数retioctl(fd,SPI_IOC_WR_BITS_PER_WORD,bits);if(ret-1){perror(Cant set bits per word);exit(1);}// 设置SPI速度retioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,speed);if(ret-1){perror(Cant set max speed);exit(1);}// 打印设置printf(SPI mode: 0x%x\n,mode);printf(Bits per word: %d\n,bits);printf(Max speed: %d Hz\n,speed);}// 检查文件大小off_tget_file_size(constchar*filename){structstatst;if(stat(filename,st)0){returnst.st_size;}perror(Cannot get file size);return-1;}// 传输文件并回环存储inttransfer_file(constchar*input_file,constchar*output_file){FILE*in_fp,*out_fp;uint8_t*tx_buffer,*rx_buffer;size_ttotal_bytes0;size_tbytes_read,chunk_size;// 打开输入文件in_fpfopen(input_file,rb);if(!in_fp){perror(Cannot open input file);return-1;}// 打开输出文件out_fpfopen(output_file,wb);if(!out_fp){perror(Cannot open output file);fclose(in_fp);return-1;}// 分配缓冲区tx_buffermalloc(CHUNK_SIZE);rx_buffermalloc(CHUNK_SIZE);if(!tx_buffer||!rx_buffer){perror(Memory allocation failed);fclose(in_fp);fclose(out_fp);return-1;}printf(Starting file transfer...\n);printf(Input file: %s\n,input_file);printf(Output file: %s\n,output_file);printf(Chunk size: %d bytes\n,CHUNK_SIZE);// 分块传输文件while((bytes_readfread(tx_buffer,1,CHUNK_SIZE,in_fp))0){// 执行 SPI 传输transfer(fd,tx_buffer,rx_buffer,bytes_read);// 将接收到的数据写入输出文件fwrite(rx_buffer,1,bytes_read,out_fp);total_bytesbytes_read;// 显示进度if(total_bytes%(1024*1024)0){printf(Transferred: %zu/%d MB (%.1f%%)\n,total_bytes/(1024*1024),FILE_SIZE/(1024*1024),(double)total_bytes/FILE_SIZE*100);}// 如果达到 8MB停止传输if(total_bytesFILE_SIZE){break;}}printf(Transfer completed: %zu bytes\n,total_bytes);// 清理资源free(tx_buffer);free(rx_buffer);fclose(in_fp);fclose(out_fp);returntotal_bytes;}// 验证文件内容是否相同intverify_files(constchar*file1,constchar*file2){FILE*fp1,*fp2;uint8_tbuf1[CHUNK_SIZE],buf2[CHUNK_SIZE];size_tbytes_read1,bytes_read2;size_ttotal_bytes0;intdifferences0;fp1fopen(file1,rb);fp2fopen(file2,rb);if(!fp1||!fp2){perror(Cannot open files for verification);if(fp1)fclose(fp1);if(fp2)fclose(fp2);return-1;}printf(Verifying files...\n);do{bytes_read1fread(buf1,1,CHUNK_SIZE,fp1);bytes_read2fread(buf2,1,CHUNK_SIZE,fp2);if(bytes_read1!bytes_read2){printf(File size mismatch!\n);differences;break;}for(size_ti0;ibytes_read1;i){if(buf1[i]!buf2[i]){if(differences10){// 只显示前10个差异printf(Difference at offset %zu: 0x%02X ! 0x%02X\n,total_bytesi,buf1[i],buf2[i]);}differences;}}total_bytesbytes_read1;}while(bytes_read10bytes_read20);fclose(fp1);fclose(fp2);if(differences0){printf(Files are identical! Verification passed.\n);}else{printf(Found %d differences in %zu bytes.\n,differences,total_bytes);}returndifferences;}intmain(intargc,char*argv[]){if(argc!3){printf(Usage: %s input_bin_file output_bin_file\n,argv[0]);printf(Example: %s input_8mb.bin output_8mb.bin\n,argv[0]);return1;}constchar*input_fileargv[1];constchar*output_fileargv[2];// 检查输入文件大小off_tfile_sizeget_file_size(input_file);if(file_size!FILE_SIZE){printf(Warning: Input file size is %ld bytes, expected %d bytes\n,file_size,FILE_SIZE);printf(Continue anyway? (y/n): );charresponsegetchar();if(response!yresponse!Y){return1;}}// 初始化SPI接口spi_init();// 传输文件size_ttransferredtransfer_file(input_file,output_file);if(transferred0){printf(File transfer successful!\n);// 验证文件verify_files(input_file,output_file);}else{printf(File transfer failed!\n);}// 关闭SPI设备close(fd);return0;}4验证用杜邦线把MISO和MOSI短接测试结果如下

相关文章:

【RK3588开发】SPI回环

SPI回环 (1)内核SPI子系统使能 修改内核配置需要先加载默认配置,然后图形界面修改后需保存配置在以下目录下勾选图中的选项: **>**Device Drivers —> ​ ->[*] SPI support —>至少勾选以下选项: Rockchi…...

降AI率软件数据安全测评:嘎嘎降不留存vs拿你论文训练AI!

降AI率软件数据安全测评:嘎嘎降不留存vs拿你论文训练AI! 一个月后导师消息:「你论文跟去年某高校论文相似度异常」 我硕士毕业季预算紧,搜降 AI 工具时格外注意「免费」「不限字数」这种关键词。找到一家工具——免费额度大、价…...

深度解析Deep3D:专业级实时2D转3D视频转换技术实战指南

深度解析Deep3D:专业级实时2D转3D视频转换技术实战指南 【免费下载链接】Deep3D Real-Time end-to-end 2D-to-3D Video Conversion, based on deep learning. 项目地址: https://gitcode.com/gh_mirrors/dee/Deep3D Deep3D是一款基于深度学习的开源2D转3D视频…...

HBM高带宽内存:从立体堆叠到2.5D封装的性能革命

1. 从平面到立体:HBM如何重塑内存性能天花板在半导体行业里,我们常把“摩尔定律”挂在嘴边,仿佛性能提升的唯一路径就是晶体管越做越小。但大约十年前,当工艺微缩的红利开始放缓,功耗墙和信号完整性问题日益严峻时&…...

CodePush-Server安全配置最佳实践:保护你的热更新服务

CodePush-Server安全配置最佳实践:保护你的热更新服务 【免费下载链接】code-push-server CodePush service is hot update services which adapter react-native-code-push and cordova-plugin-code-push - 热更新 项目地址: https://gitcode.com/gh_mirrors/co/…...

一滴血预警眼底病变!NFL 全程评估糖尿病视网膜病变

核心结论:本研究通过眼内液与血浆多组学联合分析,证实神经丝轻链(NFL)是可通过血浆微创检测、覆盖糖尿病视网膜病变全病程的保守生物标志物,能有效预测发病及糖尿病血管并发症风险。一、研究概况该研究发表于糖尿病领域…...

工业物联网实战:连接老旧设备与数据孤岛的三步走策略

1. 工业物联网的“孤岛”困境与连接之道在工业自动化领域干了十几年,我亲眼见证了从最初的继电器逻辑控制,到PLC、DCS,再到如今炙手可热的工业物联网(IIoT)的整个演进过程。一个最深刻的感受是:技术浪潮总是…...

Flipper Zero红外遥控革新:XRemote应用实现物理按键直控与智能学习

1. 项目概述:Flipper Zero上的高级红外遥控应用如果你和我一样,是个喜欢折腾各种智能硬件和复古设备的玩家,那你大概率听说过或者已经拥有了一台Flipper Zero。这个小巧的设备因其强大的射频和红外功能,被大家戏称为“赛博海豚”。…...

高性能零依赖Vue3跑马灯组件:企业级动态内容展示解决方案

高性能零依赖Vue3跑马灯组件:企业级动态内容展示解决方案 【免费下载链接】vue3-marquee A simple marquee component with ZERO dependencies for Vue 3. 项目地址: https://gitcode.com/gh_mirrors/vu/vue3-marquee Vue3-Marquee是一个专为Vue 3设计的零依…...

终极指南:如何永久免费使用Cursor Pro AI编程神器

终极指南:如何永久免费使用Cursor Pro AI编程神器 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your trial r…...

Win2D文本渲染:从基础格式到高级排版的全方位教程

Win2D文本渲染:从基础格式到高级排版的全方位教程 【免费下载链接】Win2D Win2D is an easy-to-use Windows Runtime API for immediate mode 2D graphics rendering with GPU acceleration. It is available to C#, C and VB developers writing apps for the Wind…...

Box64:让你的ARM设备也能畅玩x86_64游戏的魔法引擎

Box64:让你的ARM设备也能畅玩x86_64游戏的魔法引擎 【免费下载链接】box64 Box64 - Linux Userspace x86_64 Emulator with a twist, targeted at ARM64, RV64 and LoongArch Linux devices 项目地址: https://gitcode.com/gh_mirrors/bo/box64 还在为树莓派…...

如何用Sticky便签应用提升Linux桌面工作效率的5个秘诀

如何用Sticky便签应用提升Linux桌面工作效率的5个秘诀 【免费下载链接】sticky A sticky notes app for the linux desktop 项目地址: https://gitcode.com/gh_mirrors/stic/sticky 你是否厌倦了在多个窗口间切换查找笔记?是否经常忘记重要的待办事项&#x…...

手势传感器技术:原理、实现与应用解析

1. 手势传感器技术解析:从原理到实现手势传感器本质上是一种基于光学原理的交互设备,其核心技术在于利用红外光的发射与接收来捕捉用户手势动作。与传统的电容式触摸技术不同,手势传感器通过主动发射红外光并测量反射信号的变化,实…...

怎么挑靠谱降AI率工具?2026高性价比工具盘点,降AI超高效

学生党本来就没多少预算,3万字的硕士论文拿去做降AI处理,市面上收费从36元到240元不等,差价能翻好几倍。怎么用最少的钱把AI率降到学校要求的安全线,是不少毕业生眼下最关心的问题。 本文从价格、免费权益、售后保障三个核心维度…...

AgentKernel:构建模块化智能体系统的核心引擎设计

1. 项目概述:从“AgentKernel”看智能体开发范式的演进最近在GitHub上看到一个名为“AgentKernel”的项目,作者是vijaygopalbalasa。这个标题本身就很有意思,它没有直接叫“AgentFramework”或者“AgentPlatform”,而是选择了“Ke…...

程序员转智能体开发,到底有没有门槛?这篇给你最真实的答案

文章目录前言一、为什么所有人都在说“智能体开发零门槛”?1. 开源框架把难度降到了地板上2. 大模型的能力已经足够强大3. 海量的教程和社区资源二、智能体开发的真实门槛,到底卡在哪里?1. 认知门槛:你以为智能体是“大模型插件”…...

终极指南:如何快速掌握Clean Code PHP编码规范提升团队协作效率

终极指南:如何快速掌握Clean Code PHP编码规范提升团队协作效率 【免费下载链接】clean-code-php :bathtub: Clean Code concepts adapted for PHP 项目地址: https://gitcode.com/gh_mirrors/cl/clean-code-php 在PHP开发中,编写清晰、可维护的代…...

云原生存储优化:优化云原生环境的存储性能

云原生存储优化:优化云原生环境的存储性能 一、云原生存储优化概述 1.1 云原生存储优化的定义 云原生存储优化是指通过优化存储架构、配置和使用方式,提高云原生环境中存储的性能、可靠性和成本效益的过程。 1.2 云原生存储优化的价值 性能提升&#xff…...

为什么给 Claude Code 加上 CLAUDE.md 后,它就像换了一个脑子?

我是张大鹏,有十多年 AI 人工智能项目的开发经验,带过不少项目。说实话,最难的不是写代码,是让 AI 真正理解你想要什么。最近给项目加了一份 CLAUDE.md,效果立竿见影——Claude Code 从"莽撞乱撞"变成了&quo…...

别再裸奔了!手把手教你给Nacos 2.x加上用户密码和权限隔离(附Spring Boot配置)

Nacos 2.x安全加固实战:从零构建企业级权限体系 在微服务架构快速迭代的初期,许多团队为了开发效率往往选择"裸奔"模式运行Nacos——不开启任何鉴权机制。这种看似便捷的做法实则暗藏巨大风险:配置信息泄露、服务被恶意注销、敏感数…...

对比自行维护多个API密钥Taotoken的密钥管理带来了哪些便利

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比自行维护多个API密钥,Taotoken的密钥管理带来了哪些便利 在构建基于大模型的应用时,开发者常常需要接入…...

AwaDB:纯Python实现的轻量级本地向量数据库实践指南

1. 项目概述:当向量数据库遇上本地化与轻量化最近在折腾一些AI应用的原型,特别是RAG(检索增强生成)和智能问答系统,发现向量数据库的选择是个绕不开的话题。市面上有Pinecone、Weaviate这样的云服务,也有Mi…...

惠普OMEN游戏本终极性能优化指南:OmenSuperHub深度解析与实战应用

惠普OMEN游戏本终极性能优化指南:OmenSuperHub深度解析与实战应用 【免费下载链接】OmenSuperHub 使用 WMI BIOS控制性能和风扇速度,自动解除DB功耗限制。 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub OmenSuperHub是一款专为惠普…...

如何用MIKE IO快速上手水文数据分析:Python数据处理终极指南

如何用MIKE IO快速上手水文数据分析:Python数据处理终极指南 【免费下载链接】mikeio Read, write and manipulate dfs0, dfs1, dfs2, dfs3, dfsu and mesh files. 项目地址: https://gitcode.com/gh_mirrors/mi/mikeio MIKE IO是一个功能强大的Python开源库…...

PyODBC:如何用Python一站式连接所有主流数据库?

PyODBC:如何用Python一站式连接所有主流数据库? 【免费下载链接】pyodbc Python ODBC bridge 项目地址: https://gitcode.com/gh_mirrors/py/pyodbc 你是否遇到过这样的困境:公司项目需要连接SQL Server,个人项目要用MySQL…...

Windows XP图标主题:5分钟让你的现代Linux桌面重获经典魅力

Windows XP图标主题:5分钟让你的现代Linux桌面重获经典魅力 【免费下载链接】Windows-XP Remake of classic YlmfOS theme with some mods for icons to scale right 项目地址: https://gitcode.com/gh_mirrors/win/Windows-XP 还在怀念那个经典的开始按钮和…...

终极指南:3分钟学会用Video-subtitle-extractor高效提取视频硬字幕

终极指南:3分钟学会用Video-subtitle-extractor高效提取视频硬字幕 【免费下载链接】video-subtitle-extractor 视频硬字幕提取,生成srt文件。无需申请第三方API,本地实现文本识别。基于深度学习的视频字幕提取框架,包含字幕区域检…...

李跳跳真实好友5.0内测版发布,悄然找出删除你的微信好友[Android]

李跳跳真实好友是一款能够帮你找出删除你、拉黑你的微信好友的安卓应用,还可以为这部分微信好友添加备注,让你一眼识别删除你的和拉黑你的微信好友。注意:需要无障碍权限,进行模拟手机操作。李跳跳以跳过开屏广告著称,…...

Laravel Permission自动化测试终极指南:权限功能的完整验证方案 [特殊字符]

Laravel Permission自动化测试终极指南:权限功能的完整验证方案 🚀 【免费下载链接】laravel-permission Associate users with roles and permissions 项目地址: https://gitcode.com/gh_mirrors/la/laravel-permission 在Laravel应用开发中&…...