【ZYNQ实战】利用AXI Quad SPI快速打通Linux至PL端SPI从设备
关注、星标嵌入式客栈,精彩及时送达
[导读] 前面写过篇介绍ZYNQ基本情况的文章,今天来肝一篇实战文章介绍AXI quad SPI 使用方法,如果你正使用ZYNQ的这个IP,希望对你有所帮助。
初识AXI quad SPI
自《PG153 AXI Quad SPI v3.2》
支持:
Legacy Mode
standard mode: 准SPI通常就称SPI,它是一种串行外设接口规范,有4根通信脚:SCK (时钟), CS(片选), MOSI(主出从入), MISO(主入从出)。
Dual/Quad SPI Mode:
在标准模式下,支持高达32个从站,这是非常灵活的指标。本文对于手册中的详细技术细节不做过多阐述,有兴趣的自行深入阅读研究。
该SPI IP能干神马呢?
完成如下这样一个应用场景:
所需要实现的需求用例为:
本文实现用例描述
利用AXI quad SPI 实现SPI外设控制器
实现SPI外设控制器驱动
实现多SPI从设备挂载在SPI总线
实现用户空间访问多从SPI物理从设备
从软件分层的视角来看,上述的需求需要实现下面的访问层级:
为什么要研究这个呢?实际用ZYNQ芯片做产品时,很有可能外部有多个SPI从设备芯片需要利用Linux访问,你或许会说ZYNQ的PS端不是自带了两个SPI控制器吗?但有时候项目中这两个SPI对应的引脚可能用做其他用途了,而一个复杂的项目中又不得不使用多个SPI从设备芯片时,本文所讨论的话题就能很好的解决这样的需求场景了。通过本文,你会发现,原来ZYNQ的SPI IP是如此灵活好用!
本文目的实战描述,如何一步一步从PL端设计:
block design
约束
综合
导出
乃至PS端:
SPI驱动配置
设备树修改
系统编译部署
设备驱动测试
按照这个流程,那么第一步需要设计PL端与PS端的配置,且看:
AXI Quad SPI 之配置
从IP catalog中按下图从ip库中添加如下IP:
ZYNQ7 processing System
AXI interconnect
AXI Quad SPI(可根据需要添加多个)
Processing System Reset(添加ZYNQ7 processing System 点自动连线会自动添加,当然也可以手动添加)
Concat
Block设计图
使能ZYNQ7 processing System的时钟PL Fabric clocks,用以驱动PL端的IP:
PL Fabric clocks设置
使能M AXI GP0接口如下:
双击AXI interconnect,设置2主1从:
双击axi_quad_spi_0设置如下,设置4个从设备(最多可支持32个从设备,PS端内置的SPI控制器1个最多支持3个从设备,从这一点可看出该IP的灵活性)
同样将axi_quad_spi_1设置为2个从设备接口。
然后按照前面的连线图,将各块连接好,做过硬件的盆友会比较适应,这就像画原理图一样,就将各IP建立了逻辑连接关系了。除此之外,对于一个ZYNQ的板子而言,你还需要做如下的PS端设置:
DDR RAM设置,根据自身的板子的内存芯片以及内存大小进行设置
Peripheral IO外设设置,比如SD卡,UART,QUAD SPI Flash,erthernet等
clock时钟系统设置,根据板子的情况进行设置CPU、DDR时钟频率、IO时钟等
......
至于这些怎么配置,比较常见这里就不赘述了。
对于AXI quad SPI外设还有一个很重要的配置,就是其地址范围:
该地址最终将导出到设备树描述文件,用于SPI控制器驱动访问,从而让SPI控制器驱动得以与该IP通过AXI总线进行通信。
导出硬件文件
点击open elaborated design ,然后打开io ports进行管脚分配,这需要根据各自的硬件实际情况进行设置,比如我是这样设置的:
电平标准
是否上拉
驱动能力
.....
然后点击Run synthesis进行综合,成功之后点击生成bit stream。再点击export hardware,得到.hdf文件,这个文件用于构建内核。
将得到的硬件描述hdf文件以及bitstream文件拷贝至内核编译文件夹下:
配置编译内核
运行命令读取硬件描述文件:
petalinux-config --get-hw-description ../base.sdk
注:这里将hdf文件以及.bit文件放置在petalinux编译路径的上级目录的base.sdk,根据习惯可自行设置,只有上述命令传入的路径正确即可。
等待一段时间后,可得到一个配置界面,用于配置内核源、u-boot源、Image 等配置。
petalinux-config
根据实际情况配置好后,退出配置并保存配置。使用过的会比较熟悉,这里不赘述了。
配置设备树
编辑用户设备树文件,用户设备树文件在下面路径中:
./project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
配置设备树如下:
/include/ "system-conf.dtsi"
/ {};&axi_quad_spi_0 {status = "okay";clock-names = "axi_clk", "axi4_clk", "spi_clk";clocks = <&clkc 15>, <&clkc 15>, <&clkc 15>; spi0_dev_0@0 {compatible = "spidev";reg = <0>;spi-max-frequency = <500000>;#address-cells = <1>;#size-cells = <1>;};spi0_dev_1@1 {compatible = "spidev";reg = <1>;spi-max-frequency = <500000>;#address-cells = <1>;#size-cells = <1>;};spi0_dev_2@2 {compatible = "spidev";reg = <2>;spi-max-frequency = <500000>;#address-cells = <1>;#size-cells = <1>;};spi0_dev_3@3 {compatible = "spidev";reg = <3>;spi-max-frequency = <500000>;#address-cells = <1>;#size-cells = <1>;};
}; &axi_quad_spi_1 {status = "okay";clock-names = "axi_clk", "axi4_clk", "spi_clk";clocks = <&clkc 15>, <&clkc 15>, <&clkc 15>; spi1_dev_0@0 {compatible = "spidev";reg = <0>;spi-max-frequency = <500000>;#address-cells = <1>;#size-cells = <1>;};spi1_dev_1@1 {compatible = "spidev";reg = <1>;spi-max-frequency = <500000>;#address-cells = <1>;#size-cells = <1>;};
};
这里直接使用内置spidev兼容从设备驱动,当然如果需要自己定义一个SPI设备驱动也是非常容易的,但是对于大部分普通的SPI从芯片而言直接使用spidev设备驱动即可,只需要在读写时按照芯片手册协议进行访问即可。
配置内核
运行下面命令进行内核配置:
petalinux-config -c kernel
内核配置
对于本应用而言,需要配置SPI驱动:
Device Drivers --->+-SPI support--->
配置如下:
SPI控制器及设备驱动配置
这里调试中遇到一个奇怪的问题,CONFIG_SUSPEND需要禁止,否则控制器驱动加载不成功,目前还没有深入研究为什么不成功,猜想可能是主控制器驱动关于SUSPEND功能还不支持或者有bug,如果有哪位大神知道怎么解决请求留言指点。
Power management options --->Suspend to RAM and standby
功能管理配置
退出并保存配置,然后运行下面命令编译系统:
petalinux-build
等待编译成功后,运行下面命令将bitstream文件包进BOOT.bin中。
petalipackage --boot --fsbl ./images/linux/zynq_fsbl.elf --fpga ../base.sdk/design_1_wrapper.bit --u-boot --force
将得到下面的输出信息,表示操作成功:
INFO: File in BOOT BIN: "/home/zynq/ALINX/spi_ip/ax_peta/images/linux/zynq_fsbl.elf"
INFO: File in BOOT BIN: "/home/zynq/ALINX/spi_ip/base.sdk/design_1_wrapper.bit"
INFO: File in BOOT BIN: "/home/zynq/ALINX/spi_ip/ax_peta/images/linux/u-boot.elf"
INFO: Generating zynq binary package BOOT.BIN...
INFO: Binary is ready.
WARNING: Unable to access the TFTPBOOT folder /tftpboot!!!
WARNING: Skip file copy to TFTPBOOT folder!!!
注:/home/zynq/ALINX/spi_ip/ax_peta 是本文工程的目录
测试SPI从设备
编写驱动测试程序,代码如下:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>int main(int argc, char **argv)
{int fd;int len;unsigned char buf[10];unsigned char tmp;/* 验证输入参数个数 */if(3 != argc){printf("none para\n");return -1;}/* 打开输入的设备文件, 获取文件句柄 */fd = open(argv[1], O_RDWR);if(fd < 0){/* 打开文件失败 */printf("Can't open file %s\r\n", argv[1]);return -1;}int i = 0;int j = 0;len =strlen(argv[2]);for(i=0;i<len;i++){if(argv[2][i]>='0' && argv[2][i]<='9'){tmp = argv[2][i] - '0';}else if(argv[2][i]>='a' && argv[2][i]<='f'){tmp = argv[2][i] - 'a'+10;}else if(argv[2][i]>='A' && argv[2][i]<='F'){tmp = argv[2][i] - 'A'+10;}else{printf("Invalid input parameters \r\n");return -1;}if(i%2==0)buf[j] = tmp<<4;else{buf[j] += tmp;j++;}}len = j;printf("Test wr:");for(i=0;i<len;i++)printf(" %x",buf[i]);write(fd, &buf[0], len);printf("\n");/* 操作结束后关闭文件 */close(fd);return 0;
}
编译:
arm-linux-gnueabihf-gcc test.c -o test
将编译所得的BOOT.BIN以及image.ub文件拷贝至制作好的SD的BOOT区,test文件拷贝至/home下。然后插上SD卡上电运行电路板:
登录控制台后,运行ls /dev查看spidev设备是否加载成功:
spidev设备挂载情况
可见spedev1.0、spidev1.1以及spidev2.0--spidev2.3加载成功,与预期一样。
然后运行测试程序:
root@ax_peta:/run/media/mmcblk0p2/home#./test /dev/spidev1.0 78aa
Test wr: 78 aa
用示波器或者逻辑分析仪观察对应引脚,将出现正确的SPI通信波形。
总结一下
至此,就基本实现了从PS端Linux用户空间访问PL端的SPI从设备了。当然实际项目中还有很多细节需要进一步研究:
CPOL/CPHA 组合四种模式设置
SPI通信速率设置
从设备应用协议程序编写
AXI Quad SPI FIFO特性的深入应用
AXI Quad SPI 其他模式及细节研究等
对于这些更细节的内容,相信在将基本框架搭建成功后,只要深入细致研究都不会有太大的难度。从本文可看出,ZYNQ之所以如此灵活好用,是其厂家或者第三方提供了大量成熟可供使用的IP以及配套的驱动程序。如有兴趣尝试用来开发项目,相信你会很快喜欢上这个体系的芯片,真的可以做到片上即可实现系统这一目标!
—END—
往期精彩推荐,点击即可阅读
▲Linux驱动相关专辑
▲手把手教信号处理专辑
▲单片机相关专辑
【ZYNQ实战】利用AXI Quad SPI快速打通Linux至PL端SPI从设备相关推荐
- AXI quad SPI没有输出
AXI quad SPI没有输出(已解决) 在使用ZYNQ的AXI quad SPI时遇到以下问题: 使用loopback可以成功,但是使用示波器测量引脚却没有输出. 问题描述: 最近在用ZYNQ的A ...
- [爬虫实战]利用python快速爬取NCBI中参考基因组assembly的相关信息
1.问题导向 最近在做某个课题的时候,按老师的要求需要从NCBI中批量下载不同物种的参考基因组,同时收集相应参考基因组的一些组装信息,基因组非常多,导致工作量巨大,一个一个手动收集的话,既费时又费力, ...
- AXI Quad SPI读写Flash做远程升级
未经允许,本文禁止转载 目录 简介 AXI Quad SPI IP设置 寄存器说明 AXI Quad SPI支持的通用命令 读flash id 读flash 数据 擦除扇区 写flash 数据 注意事 ...
- 理解AXI Quad Serial Peripheral Interface(SPI) IP核
reference : PG153-AXI Quad SPI v3.2 LogiCORE IP Product Guide.pdf 在使用MicroBlaze过程中,调用了此IP,所以有必须仔细学 ...
- MPB:林科院袁志林组-利用acdSf3/acdSr4引物快速鉴定产ACC脱氨酶细菌
为进一步提高<微生物组实验手册>稿件质量,本项目新增大众评审环节.文章在通过同行评审后,采用公众号推送方式分享全文,任何人均可在线提交修改意见.公众号格式显示略有问题,建议电脑端点击文末阅 ...
- python 爬虫系统_实战干货:从零快速搭建自己的爬虫系统
近期由于工作原因,需要一些数据来辅助业务决策,又无法通过外部合作获取,所以使用到了爬虫抓取相关的数据后,进行分析统计.在这个过程中,也看到很多同学爬虫相关的文章,对基础知识和所用到的技术分析得很到位, ...
- zynq开发系列5:通过AXI GPIO的中断实现PL端按键控制PS端LED(SDK开发详解)
axi_gpio是PL端gpio(FPGA资源搭建的软核),ps7_gpio是ps端gpio(硬核).打开Documentation的示例Examples,可知第二个是关于中断的示例.导入示例impo ...
- 如何快速打通CRM系统和ERP系统,实现业务流程自动化流转
如何快速打通CRM系统和ERP系统,实现业务流程自动化流转 CRM系统和ERP系统是许多人都熟悉的软件系统,可以说有CRM系统和ERP系统才有一个企业的正常运转.那么为什么要打通跟如何快速打通CRM系 ...
- arduino控制小车转向_利用XECU和激光雷达快速搭建入门级的自动驾驶小车
利用XECU和激光雷达快速搭建入门级的自动驾驶小车 1 简介 如果关注过我们之前的推文和视频演示,相信大家对我们的XECU应该已经很熟悉了.那么今天就向大家介绍一下,如何利用我们的XECU和激光雷达快 ...
最新文章
- python-回调函数和递归函数
- MyEclipse Derby数据库服务器使用方法
- 代码变油画,精细到毛发,这个前端小姐姐只用HTML+CSS,让美术设计也惊叹丨GitHub热榜...
- 西安python培训班多少钱-西安中公python培训班靠谱吗
- 功夫熊孟军贤:如何拿到10万种子用户,创业的经验分享
- Intel Realsense D435 pyrealsense2 get_option_description() rs.option中获取参数描述
- ITOO高校云平台V3.1--项目总结(一)
- axios某一接口失败后不调用_axios 源码系列之如何取消请求
- C语言字符篇(五)内存函数
- C语言 · 输出日历
- MyBatis通过反射建立一个对象的过程。
- java和python有什么区别_Python与Java、C、Ruby、PHP等编程语言有什么区别?
- excel文件修复工具_Excel文件打开后出错,部分内容丢失的修复技巧
- Excel -- 行列数据移动(移动复制)
- App测试流程及测试点(个人整理版)-转
- 解决达梦数据库如何查找表字段名。
- 快速破解专业操盘手核心机密(全套)
- C语言——整型整除,浮点数整除
- Microsoft Windows CE 编程的十点忠告
- 【Matlab】极点配置控制(PPC)