
在调试常规程序时,几乎可以在任何地方设置大量的断点。 las 在控制器上执行程序时,该规则不适用。 如果存在形成时间图的部分,则停靠点将破坏一切。 低频和高频通过不是同一回事。 边界条件是开发商的祸害。 或者,例如,USB总线。 在NIOS II中,我没有使用它,但是在STM32上却很糟糕。 我想看到一些东西,当您停下来时,您会超时。 通常,尽管存在高级JTAG调试,但通常情况下,在时间紧迫的区域中程序的行为仍然被掩盖。 至少在执行后,很高兴看到程序经过了什么链,哪个分支起作用了,哪个分支没有起作用!
了解例外的历史甚至更重要。 在NIOS II上,我没有这样做,但是在ARM内核中的Cyclone V SoC上完全做到了。 调试时,一切正常,如果从ROM启动程序,则会出现异常。 很明显,他们是如何进入的,而情况的发展却不是这样。 跟踪也会破坏所有的掩盖。
该系列中的先前文章:
- 为Redd中安装的FPGA开发最简单的“固件”,并以内存测试为例进行调试
- 为Redd中安装的FPGA开发最简单的“固件”。 第2部分。程序代码
- 开发自己的内核以嵌入基于FPGA的处理器系统
- 以访问FPGA的示例为中央处理器Redd开发程序
- 在Redd FPGA中以流协议为例进行CPU和处理器通信示例的首次实验
引言
习惯上要严肃地写教育文章,冷静而公正地陈述材料。 但是,这并不总是可行的。 现在,根据计划,应该有一篇关于Redd复合系统中综合处理器的优化的文章,我们需要讨论使用缓存的功能。 接下来是有关访问总线时的延迟的文章。 通常,所有这些都可以在示波器上显示。 我已经在有关DMA的文章(“
DMA:神话与现实 ”)中做到了这一点。 但是我想展示使用处理器本身的一切,我对FPGA Cyclone V SoC中的ARM内核进行了此类检查。 非常方便(尽管结果尚未发布)。 因此,我决定处理JTAG块中固有的跟踪机制。 遗憾的是,到目前为止,我还没有能够免费下载可显示的内容,显示了执行该命令或执行该命令的拍子数,但是总有一些素材可以用来询问程序如何达到这样的效果。 好吧,此外,尽管风雨如磐的夜晚的记忆仍然让我记忆犹新,但我还是会以一种相当感性的方式将它们扔掉。 因此,今天将有许多回忆录和一些有用的理论。
硬体
因此,经常在调试微控制器程序时,希望知道它所经过的路径,并且必须全速通过。 对于NIOS II,此机制可用,并包含在处理器核心属性的此选项卡上的以下位置中:

跟踪类型设置要存储的信息的类型。 您什么也不能保存(这将节省芯片的内存),只能保存命令的历史记录(大多数情况下就足够了),或者保存命令和数据的历史记录。 值得注意的是,文档指出,在最后一种模式下,保存信息在某种程度上是困难的,同时可以覆盖命令的历史记录,并消耗更多的内存。 因此,仅在确实需要时才使用此模式。
“跟踪存储”参数设置将跟踪保存到的内存类型。 该文档说,标准开发环境不支持外部存储器。 因此,最好只选择内部。

好吧,Onchip跟踪帧大小设置缓冲区的大小。 缓冲区越大,可以在其中放置的事件越多,可以考虑的历史就越多。 但是,满足其他需求的晶体的存储量将更少。

无需启用该复选框即可创建单独的JTAG端口。 让所有的东西都在一辆普通的出租车上。
软件支援
好啊 因此,我们设置了处理器核心,下一步呢? 哦! 然后侦探故事开始。 如果以上附图应被解释为行动指南,则随后将出现显示混乱和堵嘴的插图。 许多文档说,要使用跟踪,您应该使用第三方昂贵的程序,甚至是特殊的JTAG设备。 但是在某些文件中,您可以专职学习。
Eclipse实验
太好了 让我们看看Eclipse。 提醒您,我使用Quartus Prime 17.1开发环境。 好吧,它发生了。 我们启动程序进行调试,然后转到菜单项,该菜单项允许您打开各种窗口:

在这里,我们选择“调试”->“跟踪控制”窗口:

我们得到了一个假人:

但是调试会话已启动。 此外,菜单项“开始跟踪”和“停止跟踪”甚至出现在菜单中(在打开此窗口之前,它们没有显示)。 但是它们被阻止了。 而且我无法激活它们。

我以不同的要求填补了Google的徒劳。 在旧的文档中,这些项目被描述为效果很好,但是在现代的文档中,根本没有提及它们。 没有人在论坛上提及他们。 也许评论中的某人会告诉您一些事情?
最新版本的Eclipse的问题
好啊 最新版本的开发环境如何? 也许那里一切正常? y! 这是单独章节的主题。 第四和第五旋风的最新版本是18.1.1。 也就是说,您必须首先下载版本18.1,然后安装更新18.1.1。 如果有人认为我有太多的空闲时间,并且为了每件事都重新安排了软件,那么一切都很好。 主要检查是关于缓存问题。 它们比较严重,我想在新版本中进行检查,我只是在这里不写它们。
因此,我下载了它。 已安装。 首先,在WIN7下启动了版本18.1,但是18.1.1找不到DLL。 好啊 我发现我需要从Visual Studio 2015下载Redist。我安装了它。 它开始运行。 用处理器系统创建了一个项目。 他甚至准备好了。 我要去Eclipse,使用BSP创建一个基于它的程序,就像我们已经做过很多次一样……我得到了这种东西...

该项目将不会进行。 如果退出并输入,它将仅部分打开。

看到文件夹关闭了吗? 你去。 怎么了 哦! 三个文件具有:

这些是保护的奇妙属性:

因此,无法打开或更改它们。如果您授予更多权限,则将打开该项目,但文件并未完全创建,因此将无法收集它们。 尝试授予权限,直到Eclipse关闭,然后再保存项目。 结果是一样的。
迅速老化的Windows 7是否应归咎于? 难怪我没有图书馆! 我将新的Quartus放在WIN10上,创建项目的结果完全相同! 我有一个朋友。 由于工作地点的原因,他有时会遇到国内制造商的产品。 他表达了关于自己和亲戚的一系列想法。 好吧,关于“谁在制造这个”的事实。 您知道,看着Intel软件的乐趣,我开始认为它与原产国相去甚远...实际上,在Alter的情况下并非如此...发生了任何事情,但我不记得了。
我刚出去 我将项目复制到具有FAT32文件系统的USB闪存驱动器。 没有安全属性。 我从中打开项目,进入Eclipse并创建了代码。 没有安全属性-没问题。 然后,我将其复制回硬盘驱动器,然后……当然,我在生成BSP时遇到问题。 因为* .bsp文件包含许多相对路径和一个绝对路径。 拔出闪存驱动器是很好的。 否则,我不会注意到BSP落在它上面(因为这是该项目的发源地),并且该项目收集在硬盘驱动器上。 这是此类路径(已更正)的示例:

好吧,好……所有东西都生成,组装了……它的工作原理与版本17.1完全相同……对于新环境中的SoC控制器,您还必须每次在编程器中都重新创建JTAG链。 在版本17.1中,只需执行一次并保存即可。 好吧好吧...
Altera Monitor及其问题
网络以一种或另一种方式搜索“开始跟踪”和“停止跟踪”一词,使我找到了有趣的文档。 他们今天描述了一个有趣的程序,称为
Altera Monitor的各种版本(旧文件中的名称有所不同)。 找到她相对容易。 您需要为您的开发环境版本下载“
大学计划”软件包。 注意许可证限制。 但是,由于我们现在正在学习,因此我们不惧怕。 但是对于商业工作,那里的一切都很糟糕。 此处的详细信息:
www.intel.com/content/www/us/en/programmable/support/training/university/materials-software.html下载,放置...当前版本附带一个文档(因为散布在Internet上的版本差异很大)。 我什至尝试为我的DE0-Nano-SoC面包板运行一个示例。 他正在工作。 但是,当我尝试创建项目时,它没有用。 * .sof文件被加载到FPGA中,过一会儿,将显示一条消息:

在指定的窗口中只有信息。 如果您尝试再次下载:那么,文本将仅显示在该窗口中:
无法查询JTAG实例ID。
请确保已使用正确的.sof文件配置了FPGA。这是什么麻烦? 我在Google上搜索。 找到了几个存在相同问题的论坛。 一次,一位英特尔员工询问作者在JTAG的工作频率,并建议设置一个标准频率。 尽管到那时我已经知道这已经不是频率问题了:公司示例行之有效,如何设置它? 作者在一个论坛上写道,它已经过去了。 他不明白如何。 他说,如果您按照说明小心地做所有事情,那么一切都会起作用。 图片的其余部分是相同的。 那个人问。 他们没有回答他。 六个月或一年后,有人写道他有同样的情况,是否有解决方案? 和沉默aaaaaaaa ...
经验丰富的解决方案尝试
好啊 可能是什么原因? 最初,我决定环顾一个可行的示例。 什么样的神秘JTAG ID? 这可能是由于存在有效的System ID系统吗?

加到自己身上,没有帮助。 也许应该怪罪所有其他外围设备都连接到的JTAG到Avalon桥?

添加-没有帮助。 我尝试了更多的假设,但我意识到您可以永远猜测。 悲痛的是,我什至问了Yandex,Bing甚至百度。 他们都比Google知道的少。 很明显,我们必须处理反编译才能从程序本身中提取所需的内容。 检查用什么语言编写程序。 事实证明,在Java中。 字节码存储在Altera_Monitor_Program.jar文件中。 好吧,这很奇怪。 除了我根本不了解这个Java之外。 在Java Script上,有一个案例涉及物联网,但我没有遇到真正的Java。 但是我们的地方并没有消失!
JAVA字节码分析发现问题
如何打开字节码? Google在Habré上发表了一篇文章,其中指出您需要使用JD-GUI。 在github上找到它,下载。 由于JD-GUI具有出色的交互式导航功能,因此我很快就确定了问题区域。 我在10分钟内将帖子留在了网站上。 本节调用第三方程序,然后分析其响应。 调用看起来像这样:
systemConsoleCommand[index] = "system-console"; systemConsoleCommand[var24++] = "--script=" + Globals.gHost.getMonitorProgramRootDir("bin/jtag_instance_check.tcl", true); systemConsoleCommand[var24++] = cable; systemConsoleCommand[var24++] = Globals.gProject.system.sofFilename; try { Process sysConsoleProc = NiosIIShell.executeCommand(systemConsoleCommand).start(); BufferedReader gdbIn = new BufferedReader(new InputStreamReader(sysConsoleProc.getInputStream()));
好吧,进一步-分析我们尚未考虑的答案。
通过以下代码,我尝试打开NIOS II控制台:

我去了sof文件所在的目录并驱动了命令行:
系统控制台--script = jtag_instance_check.tcl USB-0 test.sof但是,为此,我不得不将文件C:\ intelFPGALite \ 17.1 \ University_Program \ Monitor_Program \ bin \ jtag_instance_check.tcl复制到sof所在的同一位置,以免受到路径的影响。 最后,我得到了一个不错的答复:
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH jtag_uart_0(INSTANCE_ID:0)
TYPE_NAME altera_nios2_gen2.data_master FULL_HPATH nios2_gen2_0(INSTANCE_ID:0)
一切似乎都很美...
JAVA字节码跟踪
如果案件今天发生,则此部分将不存在。 但是昨天发生了。 我对Java的理解仍然很差。 解析文本时在那里写的内容对我来说是一片黑暗的森林。 没错,两年来,我的孩子参加了1个苏联加盟商的奥林匹克编程课程(证书和讲义为1个苏联人)。 这些课程是疯狂的钱。 他们只是用Java在那教他们。 因此,他也不理解代码中的内容(出于好奇,我将发布代码稍低一些,而不是现在)。 总的来说,人们一直认为该是时候了。 我知道不好的部分,我看到那里收到了行,并且程序不喜欢它们。 那又怎样
这个孩子给我找到了一篇非常棒的文章
www.crowdstrike.com/blog/native-java-bytecode-debugging-without-source-code它讨论了一个非常有用的Eclipse插件,它允许您使用JAR,并在其中设置断点。 在哪里下载,我在这里找到:
marketplace.eclipse.org/content/bytecode-visualizer/help我下载了Eclipse,下载了用于脱机安装的插件,苦恼了一半……我开始安装-没有足够的库。 我开始阅读。 事实证明,该插件有三个版本。 在Eslipse 4.5(火星),4.4(Luna)和4.3(我不记得这个名字)下。 好吧,一切都很简单。 我们转到Eclipse网站,我们看到一个下载Mars for Java版本的链接……而且……已经死了。 没关系! 大约有十二面镜子!..和它们的所有链接都死了。 我们尝试使用Luna for Java,到x64的链接已经死了,到x86的链接中只有一个活着。正如我的一位朋友所说:“痔疮,它很全面。” 总体而言,Google经历了一段艰难的时期,但在一些非官方服务器上发现了Mars版本的64位Java程序集。 我下载了半个小时,但下载了它。
实现了一个插件,创建了一个项目……恐怖! 在这里,跟踪不是在源代码级别,而是在la汇编程序级别。 简而言之,跟踪解码的字节码。 但是实际上,没关系! 毕竟,您始终可以检查在另一个窗口中打开的反编译源,此外,该插件显示了很好的注释……事实证明,断点不能在任何地方设置,而只能在函数入口设置。 但是我无法停止! 那里没有很多东西,您需要从入口步行到问题区域。
让我提醒您,处理后的行如下所示:
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH jtag_uart_0(INSTANCE_ID:0)
TYPE_NAME altera_nios2_gen2.data_master FULL_HPATH nios2_gen2_0(INSTANCE_ID:0)这是Java代码:
if (str.contains("(INSTANCE_ID:")) { Pattern getInstance = Pattern.compile("\\(INSTANCE_ID:(\\d+)\\)"); Matcher idMatcher = getInstance.matcher(str); if (idMatcher.find()) { String foundstr = idMatcher.group(1); instance = Integer.parseInt(foundstr); }
完全隔离实例ID。 这是代码:
Pattern getHPath = Pattern.compile("FULL_HPATH (.+?)\\|(.+?) \\("); Matcher hpathMatcher = getHPath.matcher(str); if (hpathMatcher.find()) { hpath = hpathMatcher.group(2).replace("|", "."); }
hpath变量不填充。 今天我已经知道该正则表达式:
"FULL_HPATH (.+?)\\|(.+?) \\("
需要两个单词,并用竖线分隔。 好吧,那只不过是接完线之后的情况。 我昨天不知道 更有趣的是另一个。 这个孩子用Java学习了两年的工作,没有学习正则表达式! 不,很明显,它们不是被教给语言的,而是被教给通过语言进行的奥林匹克竞赛的,但是据我所知,Java中的正则表达式是按顺序排列的。 他们拿了这么多钱,从著名的公司那里拿了证书,但是他们没有教重要的事情。但是我离题了。
隧道尽头的光
垂直线是多少? 我们接受有效的项目,给它相同的团队,并得到以下答案:
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH计算机系统:The_System | JTAG_UART(INSTANCE_ID:0)
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH计算机系统:The_System | JTAG_UART_2nd_Core(INSTANCE_ID:1)
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH计算机系统:The_System | JTAG_UART_for_ARM_0(INSTANCE_ID:2)
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH计算机系统:The_System | JTAG_UART_for_ARM_1(INSTANCE_ID:3)
TYPE_NAME altera_nios2_gen2.data_master FULL_HPATH计算机系统:The_System | Nios2(INSTANCE_ID:0)
TYPE_NAME altera_nios2_gen2.data_master FULL_HPATH计算机系统:The_System | Nios2_2nd_Core(INSTANCE_ID:1)什么是Computer_System:The_System? 这里的一切都很简单。 在本系列文章中,我将提倡一种高级概念,其中计算机系统位于层次结构的顶层。
此示例具有此Verilog层: module DE0_Nano_SoC_Computer ( //////////////////////////////////// // FPGA Pins //////////////////////////////////// // Clock pins input CLOCK_50, input CLOCK2_50, input CLOCK3_50, // ADC output ADC_CONVST, output ADC_SCLK, output ADC_SDI, input ADC_SDO, // ARDUINO inout [15:0] ARDUINO_IO, inout ARDUINO_RESET_N, // GPIO inout [35:0] GPIO_0, inout [35:0] GPIO_1, // KEY input [1:0] KEY, // LED output [7:0] LED, // SW input [3:0] SW, //////////////////////////////////// // HPS Pins //////////////////////////////////// // DDR3 SDRAM output [14:0] HPS_DDR3_ADDR, output [2:0] HPS_DDR3_BA, output HPS_DDR3_CAS_N, output HPS_DDR3_CKE, output HPS_DDR3_CK_N, output HPS_DDR3_CK_P, output HPS_DDR3_CS_N, output [3:0] HPS_DDR3_DM, inout [31:0] HPS_DDR3_DQ, inout [3:0] HPS_DDR3_DQS_N, inout [3:0] HPS_DDR3_DQS_P, output HPS_DDR3_ODT, output HPS_DDR3_RAS_N, output HPS_DDR3_RESET_N, input HPS_DDR3_RZQ, output HPS_DDR3_WE_N, // Ethernet output HPS_ENET_GTX_CLK, inout HPS_ENET_INT_N, output HPS_ENET_MDC, inout HPS_ENET_MDIO, input HPS_ENET_RX_CLK, input [3:0] HPS_ENET_RX_DATA, input HPS_ENET_RX_DV, output [3:0] HPS_ENET_TX_DATA, output HPS_ENET_TX_EN, // Accelerometer inout HPS_GSENSOR_INT, // I2C inout HPS_I2C0_SCLK, inout HPS_I2C0_SDAT, inout HPS_I2C1_SCLK, inout HPS_I2C1_SDAT, // Pushbutton inout HPS_KEY, // LED inout HPS_LED, // LTC inout HPS_LTC_GPIO, // SD Card output HPS_SD_CLK, inout HPS_SD_CMD, inout [3:0] HPS_SD_DATA, // SPI output HPS_SPIM_CLK, input HPS_SPIM_MISO, output HPS_SPIM_MOSI, inout HPS_SPIM_SS, // UART input HPS_UART_RX, output HPS_UART_TX, // USB inout HPS_CONV_USB_N, input HPS_USB_CLKOUT, inout [7:0] HPS_USB_DATA, input HPS_USB_DIR, input HPS_USB_NXT, output HPS_USB_STP ); //======================================================= // REG/WIRE declarations //======================================================= wire hps_fpga_reset_n; //======================================================= // Structural coding //======================================================= Computer_System The_System ( //////////////////////////////////// // FPGA Side //////////////////////////////////// // Global signals .system_pll_ref_clk_clk (CLOCK_50), .system_pll_ref_reset_reset (1'b0), // ADC .adc_sclk (ADC_SCLK), .adc_cs_n (ADC_CONVST), .adc_dout (ADC_SDO), .adc_din (ADC_SDI), // Arduino GPIO .arduino_gpio_export (ARDUINO_IO), // Arduino Reset_n .arduino_reset_n_export (ARDUINO_RESET_N), // Slider Switches .slider_switches_export (SW), // Pushbuttons .pushbuttons_export (~KEY), // Expansion JP1 .expansion_jp1_export ({GPIO_0[35:19], GPIO_0[17], GPIO_0[15:3], GPIO_0[1]}), // Expansion JP7 .expansion_jp7_export ({GPIO_1[35:19], GPIO_1[17], GPIO_1[15:3], GPIO_1[1]}), // LEDs .leds_export (LED), //////////////////////////////////// // HPS Side //////////////////////////////////// // DDR3 SDRAM .memory_mem_a (HPS_DDR3_ADDR), .memory_mem_ba (HPS_DDR3_BA), .memory_mem_ck (HPS_DDR3_CK_P), .memory_mem_ck_n (HPS_DDR3_CK_N), .memory_mem_cke (HPS_DDR3_CKE), .memory_mem_cs_n (HPS_DDR3_CS_N), .memory_mem_ras_n (HPS_DDR3_RAS_N), .memory_mem_cas_n (HPS_DDR3_CAS_N), .memory_mem_we_n (HPS_DDR3_WE_N), .memory_mem_reset_n (HPS_DDR3_RESET_N), .memory_mem_dq (HPS_DDR3_DQ), .memory_mem_dqs (HPS_DDR3_DQS_P), .memory_mem_dqs_n (HPS_DDR3_DQS_N), .memory_mem_odt (HPS_DDR3_ODT), .memory_mem_dm (HPS_DDR3_DM), .memory_oct_rzqin (HPS_DDR3_RZQ), // Accelerometer .hps_io_hps_io_gpio_inst_GPIO61 (HPS_GSENSOR_INT), // Ethernet .hps_io_hps_io_gpio_inst_GPIO35 (HPS_ENET_INT_N), .hps_io_hps_io_emac1_inst_TX_CLK (HPS_ENET_GTX_CLK), .hps_io_hps_io_emac1_inst_TXD0 (HPS_ENET_TX_DATA[0]), .hps_io_hps_io_emac1_inst_TXD1 (HPS_ENET_TX_DATA[1]), .hps_io_hps_io_emac1_inst_TXD2 (HPS_ENET_TX_DATA[2]), .hps_io_hps_io_emac1_inst_TXD3 (HPS_ENET_TX_DATA[3]), .hps_io_hps_io_emac1_inst_RXD0 (HPS_ENET_RX_DATA[0]), .hps_io_hps_io_emac1_inst_MDIO (HPS_ENET_MDIO), .hps_io_hps_io_emac1_inst_MDC (HPS_ENET_MDC), .hps_io_hps_io_emac1_inst_RX_CTL (HPS_ENET_RX_DV), .hps_io_hps_io_emac1_inst_TX_CTL (HPS_ENET_TX_EN), .hps_io_hps_io_emac1_inst_RX_CLK (HPS_ENET_RX_CLK), .hps_io_hps_io_emac1_inst_RXD1 (HPS_ENET_RX_DATA[1]), .hps_io_hps_io_emac1_inst_RXD2 (HPS_ENET_RX_DATA[2]), .hps_io_hps_io_emac1_inst_RXD3 (HPS_ENET_RX_DATA[3]), // I2C .hps_io_hps_io_i2c0_inst_SDA (HPS_I2C0_SDAT), .hps_io_hps_io_i2c0_inst_SCL (HPS_I2C0_SCLK), .hps_io_hps_io_i2c1_inst_SDA (HPS_I2C1_SDAT), .hps_io_hps_io_i2c1_inst_SCL (HPS_I2C1_SCLK), // Pushbutton .hps_io_hps_io_gpio_inst_GPIO54 (HPS_KEY), // LED .hps_io_hps_io_gpio_inst_GPIO53 (HPS_LED), // LTC .hps_io_hps_io_gpio_inst_GPIO40 (HPS_LTC_GPIO), // SD Card .hps_io_hps_io_sdio_inst_CMD (HPS_SD_CMD), .hps_io_hps_io_sdio_inst_D0 (HPS_SD_DATA[0]), .hps_io_hps_io_sdio_inst_D1 (HPS_SD_DATA[1]), .hps_io_hps_io_sdio_inst_CLK (HPS_SD_CLK), .hps_io_hps_io_sdio_inst_D2 (HPS_SD_DATA[2]), .hps_io_hps_io_sdio_inst_D3 (HPS_SD_DATA[3]), // SPI .hps_io_hps_io_spim1_inst_CLK (HPS_SPIM_CLK), .hps_io_hps_io_spim1_inst_MOSI (HPS_SPIM_MOSI), .hps_io_hps_io_spim1_inst_MISO (HPS_SPIM_MISO), .hps_io_hps_io_spim1_inst_SS0 (HPS_SPIM_SS), // UART .hps_io_hps_io_uart0_inst_RX (HPS_UART_RX), .hps_io_hps_io_uart0_inst_TX (HPS_UART_TX), // USB .hps_io_hps_io_gpio_inst_GPIO09 (HPS_CONV_USB_N), .hps_io_hps_io_usb1_inst_D0 (HPS_USB_DATA[0]), .hps_io_hps_io_usb1_inst_D1 (HPS_USB_DATA[1]), .hps_io_hps_io_usb1_inst_D2 (HPS_USB_DATA[2]), .hps_io_hps_io_usb1_inst_D3 (HPS_USB_DATA[3]), .hps_io_hps_io_usb1_inst_D4 (HPS_USB_DATA[4]), .hps_io_hps_io_usb1_inst_D5 (HPS_USB_DATA[5]), .hps_io_hps_io_usb1_inst_D6 (HPS_USB_DATA[6]), .hps_io_hps_io_usb1_inst_D7 (HPS_USB_DATA[7]), .hps_io_hps_io_usb1_inst_CLK (HPS_USB_CLKOUT), .hps_io_hps_io_usb1_inst_STP (HPS_USB_STP), .hps_io_hps_io_usb1_inst_DIR (HPS_USB_DIR), .hps_io_hps_io_usb1_inst_NXT (HPS_USB_NXT) ); endmodule
我专门介绍了它,以强调在这种情况下必须编写多少完全不必要的代码。 而且,如果添加或删除支脚,则也必须编辑此代码。 其实,线

相同的文字: ... Computer_System The_System ( //////////////////////////////////// // FPGA Side //////////////////////////////////// // Global signals .system_pll_ref_clk_clk (CLOCK_50), ...
并给这个前缀。 作者认为,层次结构应该是这样的,只有这样,而没有其他。 无法将处理器系统更深地卸下,也无法搬运。
我们不应该等待大自然的仁慈,接受它-我们的任务!
我们是否真的纯粹为了解决这个问题而做了这样的工作? 正如我的一个朋友喜欢说的那样:“不必要的工作比醉酒更糟”,而创建这样一个层次是不必要工作的典型案例。 因此,我们将尝试规避此限制。 记住,当调用第三方JAVA程序时,代码替换了一些tcl-script,我是否也将其复制到了sof文件旁边的目录中? 这是我们的救赎! 是他告诉系统控制台要采取什么操作,是他格式化响应。 格式如下:

相同的文字: # PRINT OUT INSTANCE ID INFO FOR EVERYTHING: set i 0 foreach path [lsort -command compare_node_number [get_service_paths bytestream]] { # If this path corresponds to a JTAG UART, incr i if {[string match *$cable_name* $path ] && [string match *jtag_uart* [marker_get_type $path] ]} { puts "[marker_get_info $path] (INSTANCE_ID:$i)" incr i } } set i 0 foreach path [lsort -command compare_node_number [get_service_paths processor]] { # If this path corresponds to a NiosII, incr i if {[string match *$cable_name* $path ] && [string match *nios2* [marker_get_type $path] ]} { puts "[marker_get_info $path] (INSTANCE_ID:$i)" incr i } }
第一块格式化有关JTAG_UART块的信息,第二块格式化关于处理器内核的信息。 现在,如果在这里,我们在输出流中添加垂直线! 我的同事对此节进行了如下纠正:
# PRINT OUT INSTANCE ID INFO FOR EVERYTHING: set i 0 foreach path [lsort -command compare_node_number [get_service_paths bytestream]] { # If this path corresponds to a JTAG UART, incr i if {[string match *$cable_name* $path ] && [string match *jtag_uart* [marker_get_type $path] ]} { set info [marker_get_info $path] if {[string first "|" $info] == -1} { set info [string map {"FULL_HPATH " "FULL_HPATH a:b|"} $info] } puts "$info (INSTANCE_ID:$i)" incr i } } set i 0 foreach path [lsort -command compare_node_number [get_service_paths processor]] { # If this path corresponds to a NiosII, incr i if {[string match *$cable_name* $path ] && [string match *nios2* [marker_get_type $path] ]} { set info [marker_get_info $path] if {[string first "|" $info] == -1} { set info [string map {"FULL_HPATH " "FULL_HPATH a:b|"} $info] } puts "$info (INSTANCE_ID:$i)" incr i } }
现在,如果没有破折号,将添加它们。 最后,该程序不仅可以在糟糕的环境中工作,而且可以在最佳编写的处理器系统中工作!
在Altera Monitor中设置项目
乌夫 仅此而已。 气刨,越野和草率的终结(尽管大约是越野-这是不准确的)。 现在,文章中的图纸再次反映了工作说明! 我们有一个针对FPGA的项目,以及一个在Eclipse中构建和运行的程序。 现在启动Altera Monitor并创建一个项目。

我们用项目创建一个目录(我将其与FPGA项目分开放置)并给出项目名称。 同时选择处理器架构

我选择的系统是“自定义系统”。 您必须指定我的* .sof和* .sopcinfo文件。 我在工作目录中选择它们。 我们的系统不需要预加载器。

选择带有设备驱动程序支持的程序类型,然后将构建BSP库:

到目前为止,只有一个工作文件(它是在Eclipse中创建的)。 在这里我添加它:

在最后一个窗口中,我什么都不会更改:

我们同意下载sof文件:

如果仅安装了软件,则切换到源代码模式。 然后它将已经打开(我将向您显示菜单在打开所有内容后的外观,其中还会包含一个项目)。

我有最简单的C程序:
#include "sys/alt_stdio.h" int main() { alt_putstr("Hello from Nios II!\n"); volatile int i=0; i += 1; i += 2; i += 3; i += 4; i += 5; i += 6; i += 7; i += 8; i += 9; i += 10; i += 11; i += 12; /* Event loop never exits. */ while (1); return 0; }
我正在尝试收集它:

我收到一个错误:
c:/intelfpga/17.1/nios2eds/bin/gnu/h-x86_64-mingw32/bin /../ lib / gcc / nios2-elf / 5.3.0 /../../../../ .. /H-x86_64-mingw32/nios2-elf/bin/ld.exe:区域“代码”溢出了15888个字节这是因为我没有将SDRAM添加到系统中,而是将其限制在内部FPGA存储器中。 但是,为什么一切都适合Eclipse,却不适合呢? 因为我在那里选择带后缀Small的BSP,但是在这里我自动成为常规软件包。 因此,打开文件:C:\ Work \ Play2 \ BSP \ settings.bsp
然后,我们开始进行手动调整。


重建BSP:

再一次,我们收集项目。 这次成功了。 现在加载它:

最后,真实的痕迹
您没有忘记我为什么要做这一切? 我这样做是为了进行跟踪。 必须激活它。 为此,请转到“跟踪”选项卡,然后在上下文菜单中选择“启用跟踪”:

我将在Disassembly选项卡的main()函数的末尾放置一个断点(RISC汇编程序在将Java代码转换为可怕的堆栈汇编程序之后的效果如何!)
这是主要功能的开始:

向下滚动并在此处放置一个断点:

我们开始,等待停止,然后转到“跟踪”选项卡。
总的来说,一切都不是很好。 最初,显然存在某种期望(我们在JTAG中有一个结论,所以这是合法的):

最后-其他代码...但是我看不到主要功能代码! 到此为止:

我什至不知道该说些什么。 但是无论如何,如果您放置一个断点而不是两个断点(在主函数的开头和结尾),那么从第一个到第二个运行之后,图像将很不错:

简要结论
因此,我们发现很有可能找出特定站点的工作方式。 因此,公开了本文的主题(“ ...处理器如何成为这种生活”)。 更加有趣的是,那些必须解决问题才能获得结果的人们都是如何生活的呢? 非常不幸的是,到目前为止,我还无法确定特定团队完成了多少项测试。 从文档片段中可以明显看出这在技术上是可行的,但是尚不清楚哪种软件可以做到这一点。 有一种观点认为,在分析tcl脚本时必须阅读的文档“
使用系统控制台进行分析和调试设计”将对我们有所帮助。 它有一个有趣的平板电脑
表10-15:跟踪系统命令 ,但就我个人而言,我没有时间对此事进行详细研究。 但是也许对某人来说如此重要,以至于他实现了一切。 这些命令包含在tcl脚本中。
好吧,在下面的文章中,必须使用示波器以老式方式进行测量。