第十章 MIZ702 ZYNQ制作UBOOT固化程序
10.0难度系数★☆☆☆☆☆☆
10.1是什么是固化
我们前几章将的程序都是通过JTAG先下载bit流文件,再下载elf文件,之后点击Run As来运行的程序。JTAG的方法是通过TCL脚本来初始化PS,然后用JTAG收发信息,可用于在线调试。但是这样只要一断电,程序就丢失了。还得全部重新来过。
本章介绍通过制作镜像文件,将镜像文件拷贝到SD卡,然后将拨码开关拨到SD启动,那么每次断电之后程序都会自动从SD启动,程序就别固化,而不会掉电丢失了。
10.2固化的流程
10.3固化准备
《第七章 ZYNQ GPIO使用之EMIO》中的实验其实就是一个最简单的“PS + PL”运用的体现。如果我们想固化这个程序,及为这个程序做一个镜像文件,制作改镜像需要哪些材料呢?
首先,想到的两个文件就是PL部分需要的bit文件,以及PS需要的elf文件。但是仅仅是这两个文件是远远不够的。我们还需要一段代码吧bit文件以及elf文件安置好。那么这段代码就是大名鼎鼎的FSBL.elf。
所以要制作这样一个镜像文件我们需要:FSBL.elf、bit、elf。
最后得到一个等式就是:BOOT.bin = FSBL.elf+该工程.bit+该工程.elf。该工程的bit文件和elf文件在我们的程序编译完之后都有了,关键是这个FSBL.elf这么那里找?不用担心,FSBL.elf文件xilinx找就为我们准备好了,我们可以利用SDK生成它。再次之前,我们先简单了解一下zynq的启动的过程。
10.4 zynq的从SD卡的启动的过程
和大多数arm启动过程一样,这个启动过程也分为3个阶段,这三个阶段分别称之为阶段0、阶段1和阶段2。
阶段 0:即传统的BootROM过程,zynq芯片里有个rom里面固化了一段不可修改的程序,只有zynq一上电,这段程序就会执行,它将对zynq的NAND、NOR、SD等基本外设控制器进行初始化。把SD卡这类易失的存储器件初始化好了之后,就会把其中的程序拷贝到zynq的OCM(On-chip memory),那么这个被拷贝到片上RAM执行的程序就是我们今天要制作的文件——BOOT.bin。
阶段 1:BOOT.bin加载到OCM上就开始执行了,之前说过BOOT.bin其实就是由FSBL.elf+该工程.bit+该工程.elf构成。而阶段1要做的就是:首先配置PS部分,PS完成初始化后,会去配置PL部分,最后还可以去加载阶段 2的代码。
阶段 2:这一阶段是可选的,主要是为了完成Linux系统启动过程。我们这次是还是裸奔,所以暂时不需要。
10.5 zynq启动模式位的选择
这里有个疑问,众所周知zynq具有多种启动方式:NOR, NAND, Quad-SPI, SD Card 以及JTAG 。zynq如何判断到底从哪里启动呢?事实上,当上电后,zynq 会根据模式管脚的设定选用boot的方式。而这个管脚的设定是通过MiZ702按键旁的拨码开。
SD卡启动模式选择拨码开关1-2-5-6 为ON 接到GND 3-4 为OFF 上拉到VCC
QSPI FLASH启动模式选择拨码开关1-2-3-5-6为ON 接到GND 4 为OFF 上拉到VCC
MiZ702模式选择通过拨码开关来实现,当拨码开关ON状态接通到GND 否则接通到3V3.
MiZ702通过拨码开关设置MIO的电平状态
我们的开发板MiZ702默认拨码的顺序,就是默认的SD卡启动,具体参看模式位应该如何选择:
· MIO[2]/Boot_Mode[3]设置JTAG模式
· MIO[5:3]/Boot_Mode[2:0] 选择Boot模式
· MIO[6]/Boot_Mode[4] 使能内部PLL
· MIO[8:7]/Vmode[1:0] 用于配置
10.6 BOOT.bin制作过程详解
Step1:双击打开SDK并为工作空间选择一个目录,后点击OK:
Step2:新建一个应用工程
Step3:填写工程名,点击Next
Step4:现在工程类型为Zynq FSBL
Step5:按下快捷键Ctrl + B编译工程就能得到我们梦寐以求的FSBL.elf。这个文件可以到我们刚刚设置的工作空间的Debug目录下找打,我这边具体目录是:D:\MiZ702\FSBL\FBLS\Debug。
Step6:我们将FSBL.elf连同《EMIO 使用详解》工程中的elf和bit文件拷贝到一个文件夹下备用。
Step7:单击SDK的工具栏处的Xilinx Tool->Creat Zynq Boot Image
Step8:依次添加FBLS.elf,design_1_wrapper.bit,以及emio.elf,请务必按顺序添加。
Step9:点击add,添加FSBL.elf
Step10:点击add,添加system_wrapper.bit
Step11:点击add,添加EMIOTest.elf文件
Step12:三个文件添加完毕之后,点击Creat Image生成BOOT.bin
在之前设定的文件夹下找到,BOOT.bin并且将其拷到SD卡中,再把SD卡插到MiZ702,打开电源,和上次工程出现的现象重现了,这次断电之后,程序也不会消失了~~
最后提醒下放大SD卡的bin文件,一定得叫BOOT.bin,不然不识别。
10.7 从Quad-SPI启动
Step1:设置配置模式
正确设置模块开关跳线,也就是把MIO5切换到OFF(上拉为H)其他全部切换到ON(短接到GND)
Step2:给开发板通电,同时连接串口到PC(不是必须的可以不连接)
Step3:选择Xilinx Tools > Program Flash
Step4:下载过程,需要几分钟时间
Step5:下载过程,输出的情况
Step6:下载完成后断电重启,就能看到从QSPI FLASH加载了
10.8 本章小结
本章详细讲解了SD卡下UBOOT的制作过程和如果编程QSPI FLASH。这样固化后程序就不容易丢失了。
第十一章 ZYNQ DDR3 PS读写操作方案
本编文章的目的主要用简明的方法在纯PS里对DDR3进行读写。
本文所使用的开发板是Miz702
PC 开发环境版本:Vivado 2015.4 Xilinx SDK 2015.4
11.0本章难度系数★☆☆☆☆☆☆
11.1 搭建硬件工程
Step1:新建一个名为为Miz702_sys的工程
Step2:选择RTL Project 勾选Do not specify source at this time
Step3:由于Miz702兼容zedboard 因此选择zedboard开发包
Step4:单击Finish
11.2使用IP Integrator创建硬件系统
Step1:单击Create Block Design
Step2:输入system
Step3:单击下图中添加IP按钮
Step4:搜素单词z选择ZYNQ7 Processing System,然后双击
Step5:添加进来了ZYNQ CPU IP,然后单击Run Block Automation
Step6:直接单击OK
Step7:在你点击了OK后,你会发现DDR以及FICED_IO自劢的延伸出来。
Step8:连线的作用就是把PS的时钟可以接入PL部分,当然这里我们暂时用不到PL部分的资源。在Block文件中,我们迚行连线,将鼠标放在引脚处,鼠标变成铅笔后迚行拖拽,连线如下图所示:
Step9:双击ZYNQ,使能UART1点击Run Connection Automation,按照如图所示配置后单击OK
Step10: 右击 system.bd, 单击Generate Output Products
Step11:支部操作会产生执行、仿真、综合的文件
Step12:右击system.bd 选择 Create HDL Wrapper 这步的作用是产生顶层的HDL文件
Step13:选择Leave Let Vivado manager wrapper and auto-update 然后单击OK
11.3导出SOC硬件到SDK
Step1:File->Export->Export Hardware
Step2:勾选Include bitstream 直接单击OK
Step3:File->Launch SDK加载到SDK
Step4:单击OK
11.4软件工程
新建一个PL_PS_INTC空的工程,并且添加main.c
DDR3的地址建好后,在mem_demo_bsp->ps7->cortexa9_0的路径下,打开xparameters_ps.h这个头文件,这个头文件是cortexA9可以直接控制的外设地址的宏定义。在里面可以找到DDR的地址,可以看到如下代码:
/* Canonical definitions for DDR MEMORY */ |
等会我们要使用这个地址,对DDR3进行读写操作,读写操作函数在mem_demo_bsp->ps7->cortexa9_0的路径下,打开xil_io.h这个头文件,这个头文件是cortexA9可以直接控制的内存映射或者映射到了地址空间的IO。在里面可以看到如下代码:
//从某个地址读数据
u8 Xil_In8(INTPTR Addr);
u16 Xil_In16(INTPTR Addr);
u32 Xil_In32(INTPTR Addr);
//向某个地址写数据。
void Xil_Out8(INTPTR Addr, u8 Value);
void Xil_Out16(INTPTR Addr, u16 Value);
void Xil_Out32(INTPTR Addr, u32 Value);
OK,有了这些就可以简单的对DDR进行续写操作了
14.3代码实现
/* * main.c * * Created on: 2016年4月4日 * Author: Administrator */ #include "stdio.h" #include "xparameters.h" #include "xparameters_ps.h" #include "xil_printf.h" #include "xil_io.h" #define DDR_BASEARDDR XPAR_DDR_MEM_BASEADDR + 0x10000000 int main() { int i; int rev; xil_printf("Hello World\n\r"); for(i=0; i<32; i++) { Xil_Out32(DDR_BASEARDDR+i*4,i); } for(i=0; i<32; i++) { rev = Xil_In32(DDR_BASEARDDR+i*4); xil_printf("the address at %x data is : %x \n\r" ,DDR_BASEARDDR+i*4, rev); } return 0; } |
11.5 测试结果
串口终端的结果如下:
Hello World
the address at 10000000 data is : 0
the address at 10000004 data is : 1
the address at 10000008 data is : 2
the address at 1000000C data is : 3
the address at 10000010 data is : 4
the address at 10000014 data is : 5
the address at 10000018 data is : 6
the address at 1000001C data is : 7
the address at 10000020 data is : 8
the address at 10000024 data is : 9
the address at 10000028 data is : A
the address at 1000002C data is : B
the address at 10000030 data is : C
the address at 10000034 data is : D
the address at 10000038 data is : E
the address at 1000003C data is : F
the address at 10000040 data is : 10
the address at 10000044 data is : 11
the address at 10000048 data is : 12
the address at 1000004C data is : 13
the address at 10000050 data is : 14
the address at 10000054 data is : 15
the address at 10000058 data is : 16
the address at 1000005C data is : 17
the address at 10000060 data is : 18
the address at 10000064 data is : 19
the address at 10000068 data is : 1A
the address at 1000006C data is : 1B
the address at 10000070 data is : 1C
the address at 10000074 data is : 1D
the address at 10000078 data is : 1E
the address at 1000007C data is : 1F
....................
11.4 本章小结
通过本章的学习,在仅仅使用PS可以对DDR3读写,这样在处理一些速度不快但是量很大的数据时很方便,当然这种方式每次读写都需要CPU干预,效率是比较低的,主要看需求吧。
官网论坛:www.osrc.cn
第十章 MIZ702 ZYNQ制作UBOOT固化程序的更多相关文章
- 第四章 MIZ701 ZYNQ制作UBOOT固化程序
4.0难度系数★☆☆☆☆☆☆ 4.1是什么是固化 我们前几章将的程序都是通过JTAG先下载bit流文件,再下载elf文件,之后点击Run As来运行的程序.JTAG的方法是通过TCL脚本来初始化P ...
- RK3568开发笔记(五):在虚拟机上使用SDK编译制作uboot、kernel和ubuntu镜像
前言 buildroot虽然灵活,但是基于实际情况,本身是侧重驱动和应用定制开发的只定制一次文件系统投入有点多,还不如直接ubunt自己交叉编译依赖库,做一些库的移植裁剪. 于是本篇就使用ubu ...
- 制作PHP安装程序的原理和步骤56
制作PHP安装程序的原理和步骤56 1.制作PHP安装程序的原理和步骤检查目录或文件的权限----修改或填加配置文件---检查配置文件正 确性---导入数据库----锁定或删除安装文件 原理: 其实P ...
- 使用InstallAnywhere7.1制作Java exe程序安装包
[转[使用InstallAnywhere7.1制作Java exe程序安装包 使用InstallAnywhere7.1制作Java exe程序安装包 对于已经完成的Java应用程序开发项目,从商业化角 ...
- 利用InstallShiled 10.5制作AE应用程序安装包
[转]利用InstallShiled 10.5制作AE应用程序安装包 作者:3SNEWS 社区ESRI(ArcGIS)版版主:zhaoxiang_whuhttp://www.3snews.net/bb ...
- 制作Java安装程序
这个工具利用 ANT 来制作在 Windows, MacOS X, Unix 平台上可执行的文件,比如 exe,zip,jar.ROXES ANT Tasks 基于 GPL 发布. http://ww ...
- C#制作自定义安装程序
(一),安装程序 以前用vs制作过安装程序,现在把步骤写出来,有帮助的大家一定要顶哦 第一步:建立工程 1.打开vs,新建项目->其他项目类型->安装和部署(這個子项下面有安装项目和Web ...
- 微信小程序在线制作 自己制作微信小程序
小程序是个什么东西?怎么自己制作微信小程序?微信小程序在线制作难吗?最近老是听这类问题,耳朵都长茧子了. 百牛信息技术bainiu.ltd整理发布于博客园 接下来作为一个技术人员的角度就为大家分析一下 ...
- C# 批处理制作静默安装程序包
使用批处理+WinRAR制作静默安装程序包 @echo 安装完窗口会自动关闭!!! @echo off start /wait Lync.exe /Install /Silent start /wai ...
随机推荐
- tomcat控制前台到后台的乱码问题
1.找到tomcat中的conf文件下的server.xml文件. 2.点击打开后找到 <Connector port="8080" protocol="HTTP ...
- JavaWeb_(Spring框架)Spring与JDBC
一.用Spring中的JdbcTemplate操作数据库 在MySQL中准备一个user表,表中增加一条假数据 用Spring中的JdbcTemplate操作数据库,在JdbcTemplate中实现增 ...
- vue后台_登录权限
登录权限控制包含着这么几个方面的含义: 1)不同的权限对应不同的路由 2)侧边栏需要根据不同的权限,异步生成 登录:使用用户名和密码,登录成功后返回用户的token(防止XSS攻击),将此token存 ...
- 调试NTDLL加载
1 随便切到一个进程 0: kd> !process 0 0 explorer.exePROCESS 8157e9a8 SessionId: 0 Cid: 06a4 Peb: 7ffde000 ...
- 2019balsn两道web和2019巅峰极客一道web记录
遇到3道有点意思的web,记录一下~ web1 题目地址:http://warmup.balsnctf.com/ 源码如下所示: <?php if (($secret = base64_deco ...
- Javascript中数组查重的方法总结大全
数组查重:简单点说,就是找出数组中重复的元素然后去除,最后得到一个没有重复元素的数组. // 方法一思路: 1.构建一个新的数组,用于存放结果. 2.for循环中每次从数组取出一个 ...
- C++ STL Heap算法
#include <iostream>#include <algorithm>#include <vector> using namespace std; int ...
- 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_6.RabbitMQ研究-入门程序-消费者
我们在consumer这个功能下进行代码的编写 首先是新建这个层级的包 创建入门程序的消费者 消费者也需要和mq建立通道.建立连接创建通道 在顶部都声明这个队列 下面写核心代码监听队列.basicCo ...
- 一百三十三:CMS系统之版块管理一
把模型创建到公共的models里面 class BoardModel(db.Model): __tablename__ = 'board' id = db.Column(db.Integer, pri ...
- 利用redis 分布式锁 解决集群环境下多次定时任务执行
定时任务: @Scheduled(cron= "0 39 3 * * *") public void getAllUnSignData(){ //检查任务锁,若其它节点的相同定时任 ...