广告

【博客大赛】【小梅哥FPGA】Cyclone V SoC 中为HPS添加SPI控制器并使用 ... ... ... ...

2018-5-9 22:37 1412 2 3 分类: FPGA/CPLD 文集: FPGA深入学习

    关于如何在Cyclone V SoC FPGA系统中为HPS添加一个SPI外设,这个实验我已经进行了有相当长的一段时间了,但直到今日方才有所突破,顺利的完成了SPI控制器的添加,驱动加载和基本测试。主要是因为自己对Linux方面知之甚少。

  这里先简要介绍自己的操作过程,然后说明自己遇到的问题,再记录自己解决问题的方法。

  在一个现成的Qsys系统中,例如友晶的DE1-SoC开发板的DE1_SOC_Linux_FB工程,打开Qsys,在Qsys系统中添加一个SPI外设,设定想要的SCLK时钟频率,例如这里设置为2M,实际上得到的应该是1.92M。将其salve端口连接到h2f_lw_axi_master上。导出相应的管脚,添加到Quartus的顶层文件中。


 

  这里需要将SPI的四个信号作为顶层管脚导出。实际使用时我并未分配实际的管脚,因为这仅仅算是我盲目探索过程,所以没有做完整的系统。但是测试时候是需要验证的,怎么办呢,这里我使用Signaltap直接抓取这几个引脚的信号,通过查看引脚的波形就能大致判断是否能正确的使用该SPI核了。例如我最终抓取到的测试波形如下图所示。当然了,这是后话,成功之后才能看到这个波形的,之前一直是不识别SPI设备,也就无法编程控制了。

  添加好SPI控制器之后需要全编译Quartus工程,并生成dts和dtb文件,dts文件是设备树,是用来供Linux读取硬件信息并对应加载设备驱动的,dtb文件是dts编译之后的二进制格式。这里我直接在SOCEDS command shell中将路径切换到工程目录下,输入make dts来生成dts文件,然后输入make dtb命令来生成dtb文件。

  生成dts的时候很顺利,没有遇到什么困难,但是在生成dtb的时候,遇到了如下报错:

  提示dts文件中有错误,pll_stream这个节点不存在。这个IP我知道,是生成一个时钟供FrameReader读取数据的,其并没有连接到HPS的总线上,也不需要受HPS控制,因此这个地方即使有错误也不会影响系统正常的运行。因此,参考提示信息说的方法,使用该-f参数来强制输出dtb文件。命令为:dtc -I dts -fo soc_system.dtb soc_system.dts。这样就能够正确的生成dtb文件了。

  生成dtb文件后,将其重命名为socfpga.dtb,并拷贝到开发板的启动SD卡中。

  然后将工程编译得到的sof文件转换得到rbf文件,命名为soc_system.rbf,也拷贝到开发板的启动SD卡中。这个rbf文件就是包含了有spi控制器的soc系统的FPGA部分的配置数据。该数据会在HPS启动的时候配置到FPGA中。

  以上只是完成了第一步,接下来,要想Linux系统能够自动的加载SPI驱动,需要配置Linux内核以使能该SPI控制器的驱动编译。

 

  使能之后,保存配置并编译得到内核镜像文件zImage文件。将zImage同样拷贝到开发板的启动SD卡中。

  这样,从理论上来说,为HPS添加SPI控制器和驱动支持的工作就算是完成了,接下来只需要将SD卡插入SOC开发板中,上电启动,芯片就会自动引导加载,并运行Linux操作系统,通过dtb读取到支持的SPI控制器,并识别到HPS总线上挂载的altera SPI控制器,为其注册驱动。然后当Linux系统启动完成后,就可以在/dev下看到spi设备了。

  但是实际上,当我按照这个流程操作之后,确实在系统启动的打印信息中看到了SPI控制器已经被识别,如下所示:

 

  但是在Linux的/dev路径下,却死活找不到SPI设备。网友帮忙分析说是设备确实已经识别了,但是可能dts中缺少一些描述信息,没能匹配上驱动信息,因此没有成功的加载驱动,创建设备。

  正当自己想破脑袋也不知道怎么办时,网友发过来一个连接,是一个博主的博客,为表尊重,这里附上其博文链接。https://blog.csdn.net/u013625961/article/details/56282731

  在这个博文里,有这样一段话:

以下为博客原文:

修改device tree的描述

spi_0: spi@0x100000100 {

    compatible = "altr,spi-16.1", "altr,spi-1.0";

    reg = <0x00000001 0x00000100 0x00000020>;

    interrupt-parent = <&hps_0_arm_gic_0>;

    interrupts = <0 43 4>;

    clocks = <&clk_0>;

    #address-cells = <1>;   /* embeddedsw.dts.params.#address-cells type NUMBER */

    #size-cells = <0>;  /* embeddedsw.dts.params.#size-cells type NUMBER */

    bus-num = <0>;  /* embeddedsw.dts.params.bus-num type NUMBER */

    num-chipselect = <1>;   /* embeddedsw.dts.params.num-chipselect type NUMBER */

    status = "okay";    /* embeddedsw.dts.params.status type STRING */

    spidev0: spidev@0 {

        compatible = "rohm,dh2228fv";   /* appended from boardinfo */

        reg = <0>;  /* appended from boardinfo */

        spi-max-frequency = <1000000>;  /* appended from boardinfo */

    }; //end spidev@0 (spidev1)

}; //end spi@0x100000100 (spi_0)

其中#address-cells = <1>;#size-cells = <0>; 两行必须用。

spi-max-frequency = <1000000>; 这个信息在设备注册时必须使用,否则会导致注册不成功。1000000 clock frequency要符合。

博客原文结束。

  意思是需要我们手动修改dts文件的内容,既然要手动修改,我就对自动生成的dts文件的内容和这个修改后的内容的差别产生了兴趣,于是打开自动生成的dts文件中的内容进行对比,对比如下所示:

 

  左侧的是博主的修改后的内容,而右侧的是SoC EDS软件自动生成的dts文件,可以看到,自动生成的内容里缺少了很多信息。

  既然这样,就先按照博主的说明,将这部分原本没有的内容手动添加进自动生成的dts文件的相应位置,然后使用该dts重新编译得到dtb文件,并替换掉SD卡中的dtb文件。然后重新启动开发板。

  只是在添加这部分内容的时候,同样也遇到了一点小插曲,我最开始是直接将这部分内容复制粘贴到我的dts文件中的。然后编译时会报如下错误:

 

ERROR (duplicate_label): Duplicate label 'spidev0' on /sopc@0/spi@0xfff00000/spidev@0 and /sopc@0/bridge@0xc0000000/spi@0x1000100e0/spidev@0

  意思是说有两个spidev@0设备,冲突了。好吧,那是哪里冲突了呢?在dts文件中尝试以spidev@0作为关键词搜索,发现文件中有两个地方涉及到了spidev@0,第一处是我刚刚添加的地方,第二处在HPS中,是HPS中的硬核SPI控制器。如下图所示:

 

  既然这样,那就自己手动将SPI_0下面的spidev0节点修改巍峨spidev1,保存后再次执行编译dtb操作,就能够成功的生成dtb文件了,将新的dtb文件拷贝到sd卡中替换之前的dtb文件。然后重启开发板,当系统启动之后,在/dev路径下就能看到一个名为spidev32766.0的设备了,编写一个简单的C语言测试程序,对该设备执行简单的读写测试,程序源码如下所示:


  然后拷贝到系统中执行,通过signaltap抓取SPI信号线上的波形,确实能够看到标准的SPI传输过程。

 

  至此,终于完成了SPI控制器的添加和使用,困扰我一个多月的问题总算是解决了。(PS:我这一个月可不是因为这个问题卡住了别的啥事都不干哈,只是因为遇到困难,每天事情又太多,就暂时搁置了。)


附:今天看到前两天写的一篇博文被网友评论了,对方应该是个专家,所以指出了我文章中存在的很多问题,说的很有道理,一瞬间感觉自己挺“白”的,挺打击积极性的,虽然话说的很难听,不过还是很感谢他,让我意识到了自己的很多不足,由于他提出的问题确实值得深思,所以我暂时将文章删除了,待日后好好学习论证之后,补充完善了再发吧。虽然写了两三年博客,遇到过各种评论,很多评论也挺打击积极性的,不过心态还是要好,坚持写作,不断的提升自己。


广告

文章评论 1条评论)

登录后参与讨论

大河马DUT 2018-5-9 23:32

小梅哥666
相关推荐阅读
小梅哥 2018-05-27 22:03
【博客大赛】【小梅哥FPGA】闹心的gcc-linaro-arm-linux-gnueabihf编译器——Floating ...
  今天在继续编写示波器(just for fun)工程,该工程的波形显示和处理界面是在Linux系统上编写程序实现的。应用程序的编写是使用的17.1版本的Quartus软件配套的DS-5软...
小梅哥 2018-05-04 11:49
【博客大赛】【小梅哥FPGA】Altera SOC更改Qsys后重新生成hps_0.h文件 ...
在Altera SoC的开发中,Qsys系统和Linux应用程序之间通过一个名为hps_0.h的文件交互硬件信息,例如总线上添加了哪些外设,每个外设相对于HPS外部总线的偏移地址,每个外设所占的地址空...
小梅哥 2018-05-04 11:44
【博客大赛】【小梅哥FPGA】Quartus II中使用脚本转换sof到rbf文件 ... ...
        rbf文件作为Altera的FPGA一种常见的配置数据格式,常用于使用其他主控主动配置FPGA时使用,例如PS模式。在Cyclone V SoC...
小梅哥 2018-05-04 11:36
【博客大赛】【小梅哥FPGA】使用DS-5编写和调试SoC的Linux应用程序 ...
对于Intel Cyclone V SoC FPGA用户,如果仅仅开发应用程序,也可以在 Windows 环境下完成。Intel针对其自家的SoC FPGA芯片提供了定制的DS-5软件,该软件为A...
小梅哥 2018-05-03 22:11
【博客大赛】使用MATLAB一键制作mif文件
        这里讲解实现一个16384(2^14)点的14位正弦波数据mif格式文件的生成,使用此文件,我们便可以在FPGA上基于直接数字合成(DDS)原理...
我要评论
1
2
广告
关闭 热点推荐上一条 /2 下一条