报价
HOME
报价
正文内容
zynq nand flash 启动 Linux系统开发之Petaliunx的QSPI Flash启动的设计流程
发布时间 : 2024-11-24
作者 : 小编
访问数量 : 23
扫码分享至微信

Linux系统开发之Petaliunx的QSPI Flash启动的设计流程

1、创建Vivado硬件平台

①在Windows系统下使用Vivado生成项目工程,生成.SDK后缀的文件

②创建了一个名为petalinux的目录,并在petalinux目录下创建了hdf目录用于存放这个sdk文件夹,将sdk文件夹拷贝到用户节目路下的petalinux/hdf目录

2、设置Petalinux环境变量

指令:source /opt/pkg/petalinux/2018.3/settings.sh

或者 指令: sptl (echo "alias sptl='source $PETALINUX/settings.sh'" >> ~/.bashrc)

//输入sptl就可以设置Petalinux的环境变量

3、创建petalinux工程

指令:petalinux-create -t project --template zynq -n ZYNQ_QSPI_FLASH

创建一个名为“ZYNQ_QSPI_FLASH”的Petalinux工程,

template参数表明创建的petalinux工程使用的平台模板,

此处的zynq表明使用的是zynq平台模板的petalinux工程,用于zynq-7000系列的芯片。

name参数(此处简写为“-n”)后接的是petalinux工程名,如此处的“ZYNQ_QSPI_FLASH”。

4、配置petalinux工程

4.1 petealinux-config

指令:cd ZYNQ_QSPI_FLASH /进入到petalinux工程目录下

指令:petalinux-config --get-hw-description ../hdf/Navigator_7020.sdk/ //导入hdf文件

4.2 Linux Components Selection

括号里的“*”表示为已使能配置。

第一项是程序固化实验中的fsbl.elf文件。

第二项是自动更新ps_init。

第三项是配置u-boot的来源。

第四项是linux-kernel的来源。

4.3 Auto Config Settings

Auto Config Settings指的是:选择是否使能fsbl、Devicetree、Kernel和u-boot的自动配置

4.4 Subsystem AUTO Hardware Settings

根据hdf文件的信息自动配置的各个外设,基本上为默认设置。

“Serial Settings”配置项用于配置开发板的调试串口和串口波特率等参数。

4.5 Advanced bootable images storage Settings

配置启动引导镜像和内核镜像的存储媒介

Advanced bootable images storage Settings——boot image settings——image storage media——primary flash

Flash Settings

设置Flash分区中的容量大小,一般保持默认即可

5、配置Linux内核

指令:petalinux-config -c kernel

6、配置Linux根文件系统

指令:petalinux-config -c rootfs

7、配置设备树文件

//使用vi命令打开system-user.dtsi文件,如下所示:

指令:vi project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi

8、编译Petalinux工程

指令:petalinux-build

//该命令将生成设备树DTB文件、fsbl文件、U-Boot文件,Linux内核和根文件系统映像。

编译完成后,生成的映像将位于工程的images目录下

9、制作BOOT.BIN启动文件

petalinux-package --boot命令生成可引导映像,该映像可直接与Zynq系列设备(包括Zynq-7000和Zynq UltraScale + MPSoC)或基于MicroBlaze的FPGA设计一起使用。对于Zynq系列设备,可引导格式为BOOT.BIN,可以从SD卡引导。对于基于MicroBlaze的设计,默认格式为MCS PROM文件,适用于通过Vivado或其他PROM编程器进行编程

ZYNQ的启动文件BOOT.BIN一般包含fsbl文件、bitstream文件和uboot文件。

使用下面命令可生成BOOT.BIN文件:

指令:petalinux-package --boot --fsbl --fpga --u-boot --force

petalinux-package命令将PetaLinux项目打包为适合部署的格式,

其中“petalinux-package --boot”命令生成可引导映像

选项“--fsbl”用于指定fsbl镜像文件所在位置,后面接收文件对应的路径信息,

如果不指定文件位置,默认对应的是images/linux/zynq_fsbl.elf;

选项“--fpga”用于指定bitstream文件所在位置,后面接该文件对应的路径信息,

默认对应的是images/linux/system.bit;

选项“--u-boot”用于指定U-Boot镜像所在位置,后面接该文件所在路径信息,

默认为images/linux/u-boot.elf。

10、vidado的SDK软件下载至flash

「正点原子FPGA连载」第十一章QSPI Flash读写测试

1)摘自【正点原子】领航者 ZYNQ 之嵌入式开发指南

2)实验平台:正点原子领航者ZYNQ开发板3)平台购买地址:https://item.taobao.com/item.htm?&id=6061601087614)全套实验源码+手册+视频下载:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html5)对正点原子FPGA感兴趣的同学可以加群讨论:8767449006)关注正点原子公众号,获取最新资料

第十一章QSPI Flash读写测试实验

Quad-SPI Flash控制器是PS内部输入/输出外设(IOP)的一部分,用来访问多位串行Flash存储器件,适合于使用较少的引脚数目达到较高数据带宽的应用场景。本章我们将通过QSPI Flash控制器,来完成对QSPI Flash的读写操作。本章包括以下几个部分:1111.1简介11.2实验任务11.3硬件设计11.4软件设计11.5下载验证11.1简介ZYNQ中的QSPI Flash控制器可以工作在三种模式下:I/O模式、线性地址模式,以及传统SPI模式。在I/O模式中,软件负责实现Flash器件的通信协议。软件需要将Flash命令和数据写到控制器中的TXD寄存器中,然后将接收到的数据从RXD寄存器中读出。而线性地址模式则使用一组器件操作来减小软件从Flash中读取数据的开销。线性模式使用硬件来实现来自AXI接口的命令到Flash指令的转换。对用户来说,在线性模式下读QSPI Flash就像读取ROM一样简单。但是该模式只支持读操作,不支持写操作。传统模式下的QSPI Flash控制器就像一个普通的SPI控制器,这个模式用的相对较少。QSPI Flash控制器的系统框图如下所示:

图 11.1.1 QSPI系统框图

从图 11.1.1中可以看到,QSPI Flash控制器通过MIO与外部Flash器件连接,支持三种模式:单个从器件模式、双从器件并行模式和双从器件堆模式。通过使用双从器件模式可以扩展QSPI Flash的存储容量。在使用单个器件的时候,直接存储访问Flash器件的地址映射FC00_0000到FCFF_FFFF(16MB)。在使用双器件模式时,地址空间可以扩展为FC00_0000至FDFF_FFFF(32MB)。另外,在上图中可以看到控制器左侧有两种类型的接口:AXI接口和APB接口。其中AXI接口用于线性地址模式,而APB接口用于I/O模式。QSPI Flash控制器的模块示意图如图 11.1.2所示。从中我们可以清晰的看出QSPI Flash控制器两种模式的差异。由于线性地址模式不支持写操作,因此本次实验重点介绍I/O模式。在I/O模式下,软件需要把命令和数据转化成QSPI Flash协议下的指令,转换之后的指令将被写入Tx FIFO。然后发送逻辑将Tx FIFO中的内容按照QSPI接口规范进行并串转换,最后通过MIO将转换后的数据送到Flash存储器中。在发送逻辑将Tx FIFO中的数据发送出去的同时,接收逻辑会采样所发送的串行数据,进行串并转换后存储到Rx FIFO里面。如果执行的是读操作,在发送读指令和读地址之后,MIO会在发送逻辑的控制下由输出模式切换成输入模式,从Flash中读出的数据将被存储丰Rx FIFO中。由于Rx FIFO中会同时接收由软件发出的指令,因此我们需要对Rx FIFO中的原始数据进行过滤,从而得到从Flash中读出的有效数据。

图 11.1.2 QSPI Flash控制器功能框图

11.2实验任务本章的实验任务是使用QSPI Flash控制器,先后对领航者核心板上的QSPI Flash进行写、读操作。通过对比读出的数据是否等于写入的数据,从而验证读写操作是否正确。11.3硬件设计根据实验任务我们可以画出本次实验的系统框图,如下图所示:

图 11.3.1 系统框图

从图 11.3.1中可以看出,本次实验是在“Hello Wold”实验的基础上增加了一个QSPI Flash控制器。我们将通过该控制器对QSPI Flash进行读写操作,并通过串口打印读写数据对比之后的结果。首先创建Vivado工程,工程名为“qspi_rw_test”,然后创建Block Design设计(system.bd)并添加ZYNQ7 Processing System模块。接下来按照《“Hello World”实验》中的步骤对ZYNQ PS模块进行配置,配置完成 后我们要添加本次实验所使用的QSPI Flash控制器模块。如下图所示:

图 11.3.2 QSPI配置界面

如图 11.3.2所示,在左侧导航栏中选择“Peripheral I/O Pins”,然后在右侧勾选“Quad SPI Flash”,并选择“Single SS 4bit IO”模式。“Single SS 4bit IO”指的是单个从器件模式,其中“SS”为“Slave Select”的缩写。看以看出,该模式下控制器使用了MIO1至MIO6共6个引脚。最后点击右下角的“OK”,本次实验ZYNQ处理系统就配置完成了。接下来在Diagram窗口中选择自动连接PS模块端口,连接完成后模块如下图所示:

图 11.3.3 ZYNQ7模块

到这里我们的Block Design就设计完成了,在Diagram窗口空白处右击,然后选择“Validate Design”验证设计。验证完成后弹出对话框提示“Validation Successful”表明设计无误,点击“OK”确认。最后按快捷键“Ctrl + S”保存设计。接下来在Source窗口中右键点击Block Design设计文件“system.bd”,然后依次执行“Generate Output Products”和“Create HDL Wrapper”。然后在菜单栏中选择 File > Export > Export hardware导出硬件,最后在菜单栏选择File > Launch SDK,启动SDK软件。11.4软件设计在SDK软件中新建一个BSP工程和一个空的应用工程,应用工程名为“qspi_Flash_test”。然后为应用工程新建一个源文件“main.c”,我们在新建的main.c文件中输入本次实验的代码。代码的主体部分如下所示:

1 #include "xparameters.h" /* SDK generated parameters */2 #include "xqspips.h" /* QSPI device driver */3 #include "xil_printf.h"4 5 #define QSPI_DEVICE_ID XPAR_XQSPIPS_0_DEVICE_ID6 7 //发送到Flash器件的指令8 #define WRITE_STATUS_CMD 0x019 #define WRITE_CMD 0x0210 #define READ_CMD 0x0311 #define WRITE_DISABLE_CMD 0x0412 #define READ_STATUS_CMD 0x0513 #define WRITE_ENABLE_CMD 0x0614 #define FAST_READ_CMD 0x0B15 #define DUAL_READ_CMD 0x3B16 #define QUAD_READ_CMD 0x6B17 #define BULK_ERASE_CMD 0xC718 #define SEC_ERASE_CMD 0xD819 #define READ_ID 0x9F20 21 //Flash BUFFER中各数据的偏移量22 #define COMMAND_OFFSET 0 // Flash instruction23 #define ADDRESS_1_OFFSET 1 // MSB byte of address to read or write24 #define ADDRESS_2_OFFSET 2 // Middle byte of address to read or write25 #define ADDRESS_3_OFFSET 3 // LSB byte of address to read or write26 #define DATA_OFFSET 4 // Start of Data for Read/Write27 #define DUMMY_OFFSET 4 // Dummy byte offset for reads28 29 #define DUMMY_SIZE 1 // Number of dummy bytes for reads30 #define RD_ID_SIZE 4 // Read ID command + 3 bytes ID response31 #define BULK_ERASE_SIZE 1 // Bulk Erase command size32 #define SEC_ERASE_SIZE 4 // Sector Erase command + Sector address33 34 #define OVERHEAD_SIZE 4 // control information: command and address35 36 #define SECTOR_SIZE 0x1000037 #define NUM_SECTORS 0x10038 #define NUM_PAGES 0x1000039 #define PAGE_SIZE 25640 41 /* Number of Flash pages to be written.*/42 #define PAGE_COUNT 1643 44 /* Flash address to which data is to be written.*/45 #define TEST_ADDRESS 0x0005500046 #define UNIQUE_VALUE 0x0547 48 #define MAX_DATA (PAGE_COUNT * PAGE_SIZE)49 50 void FlashErase(XQspiPs *QspiPtr, u32 Address, u32 ByteCount);51 void FlashWrite(XQspiPs *QspiPtr, u32 Address, u32 ByteCount, u8 Command);52 void FlashRead(XQspiPs *QspiPtr, u32 Address, u32 ByteCount, u8 Command);53 int FlashReadID(void);54 void FlashQuadEnable(XQspiPs *QspiPtr);55 int QspiFlashPolledExample(XQspiPs *QspiInstancePtr, u16 QspiDeviceId);56 57 static XQspiPs QspiInstance;58 59 int Test = 5;60 61 u8 ReadBuffer[MAX_DATA + DATA_OFFSET + DUMMY_SIZE];62 u8 WriteBuffer[PAGE_SIZE + DATA_OFFSET];63 64 int main(void)65 {66 int Status;67 68 xil_printf("QSPI Flash Polled Example Test \r\n");69 70 /* Run the Qspi Interrupt example.*/71 Status = QspiFlashPolledExample(&QspiInstance, QSPI_DEVICE_ID);72 if (Status != XST_SUCCESS) {73 xil_printf("QSPI Flash Polled Example Test Failed\r\n");74 return XST_FAILURE;75 }76 77 xil_printf("Successfully ran QSPI Flash Polled Example Test\r\n");78 return XST_SUCCESS;79 }

首先,本次实验的C程序是在官方提供的示例程序“xqspips_Flash_polled_example.c”的基础上修改得到的,该示例程序演示了如何使用轮询模式对QSPI Flash进行读写操作。在程序的开头,我们定义了一系列的参数,包括Flash器件的指令、Flash BUFFER中各数据段的偏移量、Flash器件PAGE、SECTOR的数目和大小等信息。这些信息针对不同型号的Flash器件有所不同,需要通过查看器件的数据手册得到。接下来在程序第50至55行声明了六个函数,这些函数是前面我们提到的示例程序中所提供的。我们对其中最后一个函数QspiFlashPolledExample(XQspiPs *QspiInstancePtr, u16 QspiDeviceId)进行修改,从而简化读写测试过程。而其他的函数如擦除FlashErase( )、写操作FlashWrite( )、读操作FlashRead( )等,我们可以将其当作库函数来使用。程序的主函数特别简单,就是通过调用修改之后的示例函数QspiFlashPolledExample( )来对Flash进行读写测试,并打印最终的测试结果。下面是该示例函数的代码:

81 int QspiFlashPolledExample(XQspiPs *QspiInstancePtr, u16 QspiDeviceId)82 {83 int Status;84 u8 *BufferPtr;85 u8 UniqueValue;86 int Count;87 int Page;88 XQspiPs_Config *QspiConfig;89 90 //初始化QSPI驱动91 QspiConfig = XQspiPs_LookupConfig(QspiDeviceId);92 XQspiPs_CfgInitialize(QspiInstancePtr, QspiConfig, QspiConfig->BaseAddress);93 //初始化读写BUFFER94 for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE;95 Count++, UniqueValue++) {96 WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue + Test);97 }98 memset(ReadBuffer, 0x00, sizeof(ReadBuffer));99 100 //设置手动启动和手动片选模式101 XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_MANUAL_START_OPTION |102 XQSPIPS_FORCE_SSELECT_OPTION |103 XQSPIPS_HOLD_B_DRIVE_OPTION);104 //设置QSPI时钟的分频系数105 XQspiPs_SetClkPrescaler(QspiInstancePtr, XQSPIPS_CLK_PRESCALE_8);106 //片选信号置为有效107 XQspiPs_SetSlaveSelect(QspiInstancePtr);108 //读Flash ID109 FlashReadID();110 //使能Flash Quad模式111 FlashQuadEnable(QspiInstancePtr);112 //擦除Flash113 FlashErase(QspiInstancePtr, TEST_ADDRESS, MAX_DATA);114 //向Flash中写入数据115 for (Page = 0; Page < PAGE_COUNT; Page++) {116 FlashWrite(QspiInstancePtr, (Page * PAGE_SIZE) + TEST_ADDRESS,117 PAGE_SIZE, WRITE_CMD);118 }119 //使用QUAD模式从Flash中读出数据120 FlashRead(QspiInstancePtr, TEST_ADDRESS, MAX_DATA, QUAD_READ_CMD);121 122 //对比写入Flash与从Flash中读出的数据123 BufferPtr = &ReadBuffer[DATA_OFFSET + DUMMY_SIZE];124 for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;125 Count++, UniqueValue++) {126 if (BufferPtr[Count] != (u8)(UniqueValue + Test)) {127 return XST_FAILURE;128 }129 }130 131 return XST_SUCCESS;132 }在示例函数中,首先对QSPI Flash控制器驱动进行初始化。然后对读写BUFFER进行初始化,初始化完成后WriteBuffer中为需要写入Flash的测试数据;而ReadBuffer则全部清零,准备用于接收从Flash中读回的数据,进而与WriteBuffer中的数据进行对比。接下来,通过调用xqspips.h头文件中的库函数来对QSPI Flash控制器进行配置。将其配置成手动启动和手动片选模式,并将片选信号置为有效状态。QSPI Flash控制器在I/O模式下,有两种流控(Flow Control)方法:手动模式和自动模式。手动模式下,将由用户来控制数据传输的开始。而在手动模式下,又分为“手动片选”和“自动片选”,它们指的是片选信号的控制权。自动片选所传输的数据量受限于Tx FIFO的深度,而手动片选更适合批量数据的传输。片选信号置为有效状态意味着Flash传输序列的开始。在程序的108至120行,我们调用示例程序“xqspips_Flash_polled_example.c”所提供的函数,来执行一系列Flash操作,包括读Flash ID、使能Flash Quad模式、擦除Flash等。其中最核心的是通过FlashWrite( )函数向Flash指定地址写入测试数据,然后通过FlashRead( )函数将数据从该地址读出,放至读BUFFER中。最后,在程序的122至129行,通过对比写BUFFER与读BUFFER中的数据是否一致,从而判断Flash读写测试实验是否成功。程序的剩余部分是前面所声明的一系列操作Flash的函数的实现,因为我们将其当作库函数直接调用,因此代码就不再贴出来了。大家有兴趣的话也可以研究一下,这些函数是如何将读写指令和数据转换成QSPI Flash所要求的命令格式的。实际上,这些函数的功能也都是通过调用xqspips.h头文件中的库函数XQspiPs_PolledTransfer( )来实现的。11.5下载验证首先我们将下载器与领航者底板上的JTAG接口连接,下载器另外一端与电脑连接。然后使用Mini USB连接线将开发板左侧的USB_UART接口与电脑连接,用于串口通信。最后连接开发板的电源,并打开电源开关。在SDK软件下方的SDK Terminal窗口中点击右上角的加号设置并连接串口。然后下载本次实验软件程序,下载完成后,在下方的SDK Terminal中可以看到应用程序打印的信息如下图所示:

图 11.5.1 串口打印结果

从图 11.5.1中可以看出,本次实验所实现的QSPI Flash读写测试功能,在领航者ZYNQ开发板上面下载验证成功。

相关问答

zynq n or flash 管脚固定的吗?

Zynq芯片的norflash管脚不是固定的,可以根据具体的应用需求进行配置。Zynq芯片具有多种外设接口,包括SPI、SDIO、EMIO等,这些接口可以用来连接norflash存储...

zc702参数?

回答如下:对于XilinxZynq-7000系列的开发板ZC702,以下是一些常见的参数:-SoC芯片:XilinxZynq-7000系列-处理器:ARMCortex-A9双核处理器-...

 达斯科波波夫  无国界 
王经理: 180-0000-0000(微信同号)
10086@qq.com
北京海淀区西三旗街道国际大厦08A座
©2024  上海羊羽卓进出口贸易有限公司  版权所有.All Rights Reserved.  |  程序由Z-BlogPHP强力驱动
网站首页
电话咨询
微信号

QQ

在线咨询真诚为您提供专业解答服务

热线

188-0000-0000
专属服务热线

微信

二维码扫一扫微信交流
顶部