×

为ZynqberryZero编写嵌入式C应用程序

消耗积分:2 | 格式:zip | 大小:0.69 MB | 2022-11-07

张华

分享资料个

描述

继续介绍 ZynqberryZero FPGA 开发板,我认为使用在 ZynqberryZero 的 Zynq-7000 SoC 的 ARM 核心处理器上运行的简单嵌入式 C 应用程序来跟进基本硬件设计是很重要的。

虽然可以将比特流闪存到包含在可编程逻辑中运行的纯 HDL 设计的 ZynqberryZero 上,但我个人认为在任何配备 SoC (如 Zynq 或ZynqMP 系列芯片。

(就上下文而言,我在这里将 SoC 或片上系统定义为任何在其可编程逻辑中内置物理处理器的 FPGA。并且提到的所有特定部件/芯片系列都是 Xilinx,但一般概念适用于任何制造商。 )

除了为什么不使用它的明显原因之外,还有几个原因表明您应该在 Zynq 芯片中内置的物理 ARM 核心处理器上运行某些东西:

1.成本

2. 功耗

pYYBAGNoeS-AAqJWAAEDvkLDqJM249.png
其可编程逻辑中内置的 ARM 内核的 Zynq 框图。
 

Zynq FPGA 比其纯可编程逻辑同类产品(如 Artix 或 Kintex 芯片)消耗更多功率和成本。因此,使用 Zynq 而不直接在 ARM 内核上运行嵌入式应用程序(就像我将在这个项目中做的那样)或嵌入式 Linux 或 RTOS 等操作系统真的没有意义。

在我上一篇关于 ZynqberryZero 的项目文章中,我介绍了如何在 Vivado 中设置基础硬件设计对于那些不熟悉的人,Vitis 是 Vivado 的 Xilinx 芯片的合作伙伴 IDE,用于开发在 FPGA 硬件中的任何处理器上运行的软件(无论是 Zynq 的物理 ARM 内核还是在MicroBlaze 等可编程逻辑)。这个 Vivado 项目和在该项目的最后步骤中导出的最终硬件包是我开始构建这个 Vitis 项目的基础。有两种启动 Vitis 的方法:

1. 从 Vivado 中选择工具>启动 Vitis

poYBAGNoeTKAY_QbAACXcnnrNQY746.png
 

2. 从 Ubuntu 的命令行:

~$ source //2019.2/settings64.sh
~$ vitis

Vitis 的启动屏幕将询问工作区目录,因为这是一个新项目,单击浏览然后导航到工作区所在的所需目录。我个人喜欢使用 Vitis 项目的硬件设计所来自的 Vivado 项目的顶层文件夹,并在该目录中创建一个名为vitis_​​workspace的文件夹:

poYBAGNoeTWAclf4AABemxYbjTg227.png
 

创建vitis_​​workspace目录后,导航到该目录并单击“确定”。这将返回到 Vitis 启动屏幕,并确认所选的工作区路径。

 
pYYBAGNoeTeAdavAAABB3nqaukA391.png
 
1 / 2
 

点击 Launch 后,Vitis 将加载到一个新的空白工作区:

pYYBAGNoeTuANT0HAADdhLcs1zE992.png
 

通过从空白工作区页面中选择创建平台项目来创建一个新的平台项目。

 
 
 
pYYBAGNoeUCAKmdfAACLlSgwn0w320.png
 
1 / 4
 

请注意,创建平台项目时它已过期,因为它尚未编译。在继续从嵌入式 C 应用程序创建应用程序项目之前,使用Ctrl+B构建平台项目。

编译平台项目后,通过单击新建图标并选择应用程序项目来创建一个新的应用程序项目...

poYBAGNh-USAUfB6AACQhH8EVyI065.png
 

为项目指定所需的名称并保留默认选项以使用它创建新的系统项目。当您单击应用程序项目的设置窗口时,请务必选择由前面步骤中完成的平台项目创建的自定义平台、运行应用程序的 ARM 中的目标处理器内核、所需的编程语言以及适当的应用程序模板。

 
 
 
pYYBAGNoeUWAa9GEAACUBsnBjfY979.png
 
1 / 4提供所需的应用程序名称并为系统项目选择新建。
 

我正在用 C 语言编写这个应用程序,我选择了 Hello World 应用程序模板。

pYYBAGNoeUiAJ9XxAALwzwUb0Hw069.png
 

现在已经创建了应用程序项目,是时候真正开始编写一些代码了。我想做的不仅仅是通过 UART 串​​行终端简单地打印出“Hello World”,但不需要添加任何额外的硬件。所以我决定使用来自 UART 的简单字符回显。

我的嵌入式 C 应用程序首先为 Zynq 的内置 UART 设置控制寄存器,并通过将适当的位掩码写入控制寄存器来启用 UART 的发送和接收缓冲区。

然后在看到 ASCII 字符进行转义时退出的 while 循环中,轮询控制寄存器位以查看接收缓冲区的 FIFO 中是否有任何内容。如果有,它会读入该字符,将其复制到发送缓冲区,然后将其发送回 UART 串​​行控制台。

pYYBAGNoeU2Ab7i8AAEsm31x-xs504.png
 

编写 C 代码并保存文件后,通过在 Explorer 窗口中右键单击应用程序项目并选择Build Project来构建应用程序项目。

poYBAGNoeVCANKqhAADhfMqBmxc413.png
 

使用 Micro-USB 电缆将 ZynqberryZero 插入您的 PC。JTAG/UART USB 端口是最靠近板角的端口:

接下来,将比特流编程到 FPGA 上。再次,右键单击 Explorer 窗口中的应用程序项目并选择Program FPGA由于我们从应用项目中选择了 Program FPGA,因此弹出的窗口中的所有字段都会自动填充为适当的值,因此您只需单击Program即可。

 
 
 
poYBAGNoeVaAYZmFAADIYG-q_5s636.png
 
1 / 2
 

FPGA 成功编程后,启动应用程序的调试运行。右键单击 Explorer 窗口中的应用程序项目,然后选择Debug As > Launch on Hardware (Single Application Debug)。Vitis 会自动将整个窗口切换到 Debug 视图,并在 main 函数的第一行设置断点。

 
 
 
poYBAGNoeVqAAbs1AAFI5jHRD5o881.png
 
1 / 2
 

要将字符发送到 Zynqberry 的 UART 并看到它们回显,需要将串行终端应用程序连接到小板创建的串行端口。您可以使用任何您喜欢的串行终端,但在 Vitis 中有一个内置终端,我喜欢使用它来保持简单。如果它尚未在 Vitis 的 Debug 视图的底部窗口中打开一个选项卡,您可以通过选择Window > Show View打开它,然后搜索/选择Vitis Serial Terminal

连接到波特率为 115200(标准 Zynq UART 波特)的串行终端。

poYBAGNoeV2AFlufAAHKw2MGvvU090.png
 

当您在串行终端中键入字符以进行处理时,单步执行代码 (F6) 或让它运行 (F8)。

pYYBAGNoeWGAR-G9AAQJi4oSU8U074.png
 

正如您将看到的,每个字符都从接收缓冲区中提取并回显。本项目教程用于演示为裸机嵌入式应用程序创建 Vitis 项目的整个过程以及如何对其进行调试。由于将比特流永久闪存到 FPGA 上更依赖于每个特定的 FPGA 开发板,我将把它保存到另一个教程中。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'为ZynqberryZero编写嵌入式C应用程序',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);