2014-07-12 日志

本文介绍了Java中的异常处理机制,包括编译期异常与运行期异常的区别,以及如何通过try...catch...finally...等方式处理异常。同时,文章还详细讲解了File类的使用方法,包括创建、删除、重命名文件或文件夹等功能。
1:异常(理解)
(1)程序出现了不正常的情况。
(2)异常的体系结构
Throwalbe
|--Error 严重的问题,一般我们解决不了。我们只能尽可能的避免。
|--Exception
|--非RuntimeException 是我们需要处理的。两种方案。
|--RuntimeException 是必须修正代码的。


举例:
班长去旅游。骑自行车。


Error:山路塌陷。
非RuntimeException:
出门的时候看看轮胎是否有气。
RuntimeException:
有好路你不好好走,你偏好往是石子上走。
(3)JVM的默认处理方案:
一旦出现了异常,就立马在这里停止下来。
并且,把异常的类名,错误原因,及错误位置等信息输出在控制台。
(4)异常的处理方案:
A:自己处理
基本格式:try...catch...finally...
变形格式:
try...catch...
try...catch...catch...
try...catch(异常1 | 异常2 | 异常3 变量) JDK7的新特性
try...catch...finally...
try...catch...catch...finally...
try...finally...
B:抛出处理
在方法声明上用throws声明一下。
这其实是告诉调用者,你注意了,我有问题。
问题:
a:非RuntimeException 必须处理
b:RuntimeException 不搭理他


注意:
能自己做的,就不麻烦别人。
我讲课为了方便,用抛出。


最后:
如果你感觉不太会,一定要记住,看到调用方法的时候,
出现了问题,在排除其他的原因的情况下,你把鼠标放到
前面看看是不是throws和添加try...catch。
如果是,说明该异常是一个编译时期异常。
你只需要点击鼠标即可。
(5)面试题:编译时期异常和运行时期异常的区别
A:编译时期异常 是必须处理的。
B:运行时期异常 是可以不用处理的。
(6)finally的用法及面试题。
A:finally是异常处理的一部分。里面的代码永远会执行。
特殊情况:在执行到finally之前退出了jvm。
B:finally,final和finalize的区别?
C:在catch里面有return的情况下,finally里面的代码还执行吗?
 如果执行,请问在return前还是后。
D:扩展一个面试题。
(7)自定义异常
java虽然提供了很多异常,但是,它并不能满足我们所有的需求,
所以,我们在开发的过程中需要自己写异常。
而自己定义的类要想成为一个异常类,必须继承自Exception或者RuntimeException。


2:File(理解)
(1)因为在IO流中,我们最常见的功能就是上传或者下载文件。
  为了更方便的对文件进行操作,java就提供了一个类File供我们使用。
(2)File类构造方法:
A:File file = new File("d:\\a.txt");
B:File file = new File("d:\\","a.txt");
C:File file = new File("d:\\");
 File file2 = new File(file,"a.txt");


以上三种表达的意思一致。
(3)File的功能概述
A:创建功能
创建文件:createNewFile()
创建文件夹:mkdir(),mkdirs()


相对路径:不以盘符开始,针对项目路径而言。
绝对路径:以以盘符开始
B:删除功能
删除文件或者文件夹:delete()


注意:
a:不能删除一个带内容的目录
b:java中的删除不走回收站
C:重命名功能
renameTo():
同路径:改名
不同路径:剪切+改名
D:判断功能
是否是文件:isFile()
是否是文件夹:isDirectory()
E:获取功能
绝对路径:getAbsolutePath()
相对路径:getPath()
名称:getName()
大小:length()
最后一次修改时间:lastModified()
F:高级获取功能
获取指定目录下的所有文件或者文件夹的名称数组:list()
获取指定目录下的所有文件或者文件夹的File数组:listFiles()


文件名称过滤器:
FilenameFilter
(4)案例:
输出指定目录下指定后缀名结尾的文件名称。
A:先获取,再判断。
B:先判断,再获取。(文件名称过滤器的使用)
File file = new File("d:\\");


String[] strArray = file.list(new FilenameFilter(){
public boolean accept(File dir,String name) {
return new File(dir,name).isFile() && name.endsWith(".java");
}
});


for(String str : strArray) {
System.out.println(str);
}

3:递归(理解)
(1)方法定义中调用方法本身的现象。
(2)注意事项:
A:递归一定要有出口,否则死递归。
B:递归的次数不能过多,否则内存溢出。
C:构造方法不能递归调用。
(3)案例:

递归求阶乘。




应该是面包的问题,到了学校就拉肚。全天跑了3趟厕所。


吃完晚饭这教室热闹的很,后面的在唱歌,右边的在看视频,前面的在打游戏。尼玛,直接请假回了。

回去的路上去回龙观体育公园看了看,好多小孩在轮滑。问了下原来周六周日8点开门。嗯,明天来玩。






#------------------------------------------------------------------------------- # GigE Vision Reference Design Firmware #------------------------------------------------------------------------------- # Software environment : Xilinx Vitis 2022.2 # Hardware platform : MVDK + Enclustra Mercury ZX5 # Target SoC : XC7Z015 # Embedded CPU : ARM Cortex-A9 #------------------------------------------------------------------------------- # Complementary Makefile to perform tasks not covered by the Xilinx Vitis GUI. # # Particular targets... # scripts : update auxiliary TCL scripts # lib : build the GigE static library # eeprom : generate EEPROM binary image # Top-level targets... # all : build everything # s2i : prepare scripts and library for customer # # The scripts, lib, boot, and s2i targets are nonfunctional for end customers # due to missing source code of the scripts, library, and bootloader. Customer # gets prebuilt object files in the ./lib directory and up to date scripts # in the ./etc directory instead. #------------------------------------------------------------------------------- # 0.1 | 2014-07-16 | JP | Initial release # 0.2 | 2014-08-01 | JP | Fixed incompatibility with Vivado 2014.2 under # | | | Windows operating systems # 0.3 | 2014-10-07 | MAS | Cleanup for Zynq design flow (no bootloader, # | | | bitstream/application.bin file creation) # 0.4 | 2016-12-02 | JP | Upgraded to Vivado/SDK 2016.2 # 0.5 | 2019-03-20 | JP | Updated to current tools # 0.6 | 2021-11-30 | SS | Update to Vivado 2020.2/Vitis # 0.7 | 2025-02-11 | NF | Update to Vivado 2022.2/Vitis #------------------------------------------------------------------------------- #---- Project specific settings ------------------------------------------------ # Vitis workspace projects VITIS_PRJ_APP = xgvrd VITIS_CFG_APP = Release VITIS_EXPORT = xgvrd_platform/export/xgvrd_platform VITIS_EXPORT_SW = $(VITIS_EXPORT)/sw/xgvrd_platform VITIS_EXPORT_HW = $(VITIS_EXPORT)/hw # EEPROM image generator options EE_OPTIONS = -m 3C:39:E7:71:02:86 -c 6 -i 169.254.100.100 -n 255.255.0.0 -g 169.254.100.1 -p 3956 -e 999999 -a FEC00000 # Configuration flash memory map OFFSET_BIT = 0x00400000 OFFSET_APP = 0x00800000 OFFSET_XML = 0x00C00000 # Serial communication device SERIAL = /dev/ttyUSB0 #---- Project files and directories -------------------------------------------- # Base names of the input/output files LIB_NAME = gige APP_NAME = application EE_NAME = eeprom XML_NAME = xgvrd-tpg HW_NAME = xgvrd BIF_NAME = bootimage # Project directories HW_PATH = $(wildcard ../*.runs/impl_1) FW_PATH = . OUT_PATH = $(FW_PATH)/bin LIB_PATH = $(FW_PATH)/lib ETC_PATH = $(FW_PATH)/etc # Full input/output file names LIB_FILE = $(LIB_PATH)/lib$(LIB_NAME).a APP_BIN_FILE = $(OUT_PATH)/$(APP_NAME).bin EE_BIN_FILE = $(OUT_PATH)/$(EE_NAME).bin EE_C_FILE = $(FW_PATH)/$(VITIS_PRJ_APP)/src/$(EE_NAME).c XML_FILE = $(ETC_PATH)/$(XML_NAME).xml HW_BIT = $(HW_PATH)/$(HW_NAME).bit BIN_FILE = $(OUT_PATH)/$(BIF_NAME).bin BOOTIMAGE = $(ETC_PATH)/$(BIF_NAME).bif # Vitis workspace paths and files BSP_PATH = $(FW_PATH)/$(VITIS_EXPORT_SW)/domain_0 APP_PATH = $(FW_PATH)/$(VITIS_PRJ_APP) APP_OUT = $(APP_PATH)/$(VITIS_CFG_APP) APP_FILE = $(APP_OUT)/$(VITIS_PRJ_APP).elf APP_SRC := $(wildcard $(APP_PATH)/src/*.c) APP_HDR := $(wildcard $(APP_PATH)/src/*.h) FSBL_FILE = $(FW_PATH)/$(VITIS_EXPORT_SW)/boot/fsbl.elf XSA_FILE = $(FW_PATH)/$(VITIS_EXPORT_HW)/$(HW_NAME).xsa #---- Private GigE files and directories --------------------------------------- FW_PREFIX = ./fw # TCL scripts SCRIPTS_PATH = $(FW_PREFIX)/scripts/tcl # GigE library source files LIB_SRC := $(wildcard $(FW_PREFIX)/libgige/src/*.c) LIB_HDR := $(wildcard $(FW_PREFIX)/libgige/src/*.h) LIB_OBJ := $(addsuffix .o,$(basename $(notdir $(wildcard $(FW_PREFIX)/libgige/src/*.c)))) LIB_PUB := $(FW_PREFIX)/libgige/src/gige.h #---- Toolchain setup ---------------------------------------------------------- # CPU tools AR = arm-none-eabi-ar CC = arm-none-eabi-gcc SIZE = arm-none-eabi-size OC = arm-none-eabi-objcopy # Compiler options CC_OPT_LIB = -O2 CC_FLAGS = -Wall -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -nostartfiles CC_INCLUDES = -I$(BSP_PATH)/bspinclude/include # Linker options LNK_LIBPATH = -L$(BSP_PATH)/bsplib/lib -L$(LIB_PATH) LNK_FLAGS = -l$(LIB_NAME) # Object copy options OC_FLAGS = -v -I elf32-littlearm -O binary OC_REMOVE = -R .vectors.reset -R .vectors.sw_exception -R .vectors.interrupt -R .vectors.hw_exception # Correct command line tools for GNUWin environment XILINX_VITIS_DIR := $(subst \,/,$(XILINX_VITIS)) ifneq (,$(wildcard $(XILINX_VITIS_DIR)/gnuwin/.)) MKDIR := $(XILINX_VITIS_DIR)/gnuwin/bin/mkdir ECHO := $(XILINX_VITIS_DIR)/gnuwin/bin/echo RM := $(XILINX_VITIS_DIR)/gnuwin/bin/rm DATE := $(shell $(XILINX_VITIS_DIR)/gnuwin/bin/date +%Y%m%d) else MKDIR := mkdir ECHO := echo RM := rm DATE := $(shell date +%Y%m%d) endif # Correct NULL file ifeq ($(SHELL),$(filter $(SHELL),sh.exe command.com)) NULL := nul else NULL := /dev/null endif # Tcl interpreter and scripts TCLSH := $(shell which tclsh 2>$(NULL)) XTCLSH := $(shell which xtclsh 2>$(NULL)) VIVADO := $(shell which vivado 2>$(NULL)) ifdef TCLSH TCL := tclsh TCLARGS := else ifdef XTCLSH TCL := xtclsh TCLARGS := else ifdef VIVADO TCL := vivado -mode batch -nojournal -nolog -notrace -source TCLARGS := -tclargs else TCL := TCLARGS := endif endif endif CKSUM = cksum.tcl EEPROM = eeprom.tcl BITBIN = bit2bin.tcl #---- Compilation targets ------------------------------------------------------ # Aliases all: scripts lib eeprom bin s2i: scripts lib scripts: $(ETC_PATH)/$(CKSUM) $(ETC_PATH)/$(EEPROM) $(ETC_PATH)/$(BITBIN) lib: $(LIB_FILE) # delete "$(EE_C_FILE)" if EEPROM emulation is not needed #eeprom: $(EE_BIN_FILE) $(EE_C_FILE) eeprom: $(EE_BIN_FILE) app: $(APP_FILE) bin: $(BIN_FILE) # Update TCL scripts $(ETC_PATH)/$(CKSUM): $(wildcard $(SCRIPTS_PATH)/$(CKSUM)) ifeq ($(wildcard $(SCRIPTS_PATH)/$(CKSUM)),) @$(ECHO) @$(ECHO) The TCL script is not available! @$(ECHO) Please use the $(ETC_PATH)/$(CKSUM) script delivered by S2I! @$(ECHO) else @cp -fv $(SCRIPTS_PATH)/$(CKSUM) $(ETC_PATH)/$(CKSUM) endif $(ETC_PATH)/$(EEPROM): $(wildcard $(SCRIPTS_PATH)/$(EEPROM)) ifeq ($(wildcard $(SCRIPTS_PATH)/$(EEPROM)),) @$(ECHO) @$(ECHO) The TCL script is not available! @$(ECHO) Please use the $(ETC_PATH)/$(EEPROM) script delivered by S2I! @$(ECHO) else @cp -fv $(SCRIPTS_PATH)/$(EEPROM) $(ETC_PATH)/$(EEPROM) endif $(ETC_PATH)/$(BITBIN): $(wildcard $(SCRIPTS_PATH)/$(BITBIN)) ifeq ($(wildcard $(SCRIPTS_PATH)/$(BITBIN)),) @$(ECHO) @$(ECHO) The TCL script is not available! @$(ECHO) Please use the $(ETC_PATH)/$(BITBIN) script delivered by S2I! @$(ECHO) else @cp -fv $(SCRIPTS_PATH)/$(BITBIN) $(ETC_PATH)/$(BITBIN) endif # Actual targets $(LIB_FILE): $(LIB_SRC) $(LIB_HDR) ifeq ($(LIB_SRC),) @$(ECHO) @$(ECHO) Building the GigE library is not available to end customers! @$(ECHO) Please use the prebuilt $(LIB_FILE) delivered by S2I! @$(ECHO) else @$(MKDIR) -p $(LIB_PATH) @$(RM) -f $(LIB_OBJ) $(CC) $(CC_OPT_LIB) $(CC_FLAGS) $(CC_INCLUDES) -c $(LIB_SRC) $(AR) rcs $(LIB_FILE) $(LIB_OBJ) @$(RM) -f $(LIB_OBJ) @$(ECHO) $(SIZE) -t $(LIB_FILE) @$(ECHO) @cp $(LIB_PUB) $(FW_PATH)/$(VITIS_PRJ_APP)/src/ endif $(EE_BIN_FILE): $(XML_FILE) $(ETC_PATH)/$(CKSUM) $(ETC_PATH)/$(EEPROM) ifndef TCL $(error Tcl interpreter not found) endif @$(TCL) $(ETC_PATH)/$(EEPROM) $(TCLARGS) $(EE_OPTIONS) -x $(XML_FILE) -o $(EE_BIN_FILE) @$(TCL) $(ETC_PATH)/$(CKSUM) $(TCLARGS) -x $(EE_BIN_FILE) $(EE_C_FILE): $(XML_FILE) $(ETC_PATH)/$(EEPROM) ifndef TCL $(error Tcl interpreter not found) endif @$(TCL) $(ETC_PATH)/$(EEPROM) $(TCLARGS) $(EE_OPTIONS) -t -x $(XML_FILE) -o $(EE_C_FILE) $(APP_FILE): $(LIB_FILE) $(APP_SRC) $(APP_HDR) make -C $(APP_OUT) all $(APP_BIN_FILE): $(APP_FILE) $(ETC_PATH)/$(CKSUM) @$(OC) $(OC_FLAGS) $(OC_REMOVE) $(APP_FILE) $(APP_BIN_FILE) @chmod -x $(APP_BIN_FILE) ifdef TCL @$(TCL) $(ETC_PATH)/$(CKSUM) $(TCLARGS) -x $(APP_BIN_FILE) endif $(BIN_FILE): $(HW_BIT) $(APP_FILE) $(FSBL_FILE) $(XML_FILE) @$(ECHO) "//arch = zynq; split = false; format = BIN" > $(BOOTIMAGE) @$(ECHO) "the_ROM_image:" >> $(BOOTIMAGE) @$(ECHO) "{" >> $(BOOTIMAGE) @$(ECHO) " [bootloader]$(FSBL_FILE)" >> $(BOOTIMAGE) @$(ECHO) " [offset = $(OFFSET_BIT)]$(HW_BIT)" >> $(BOOTIMAGE) @$(ECHO) " [offset = $(OFFSET_APP)]$(APP_FILE)" >> $(BOOTIMAGE) @$(ECHO) " [offset = $(OFFSET_XML)]$(XML_FILE)" >> $(BOOTIMAGE) @$(ECHO) "}" >> $(BOOTIMAGE) bootgen -image $(BOOTIMAGE) -arch zynq -o $(BIN_FILE) -w on # @$(RM) -f $(BOOT_NAME).bif #---- Device programming targets ----------------------------------------------- prog: $(HW_BIT) @$(ECHO) "connect" > xsdb_prog.tcl @$(ECHO) "targets 2" >> xsdb_prog.tcl @$(ECHO) "rst" >> xsdb_prog.tcl @$(ECHO) "fpga $(HW_BIT)" >> xsdb_prog.tcl @$(ECHO) "exit" >> xsdb_prog.tcl xsdb xsdb_prog.tcl # @$(RM) -f xsdb_prog.tcl # @$(RM) -f ps7_init.* ps7_init_gpl.* run: $(APP_FILE) @$(ECHO) "connect" > xsdb_run.tcl @$(ECHO) "targets 2" >> xsdb_run.tcl # @$(ECHO) "loadhw $(HW_NAME).xsa" >> xsdb_run.tcl @$(ECHO) "source xgvrd_platform/hw/ps7_init.tcl" >> xsdb_run.tcl @$(ECHO) "ps7_init" >> xsdb_run.tcl @$(ECHO) "ps7_post_config" >> xsdb_run.tcl @$(ECHO) "dow $(APP_FILE)" >> xsdb_run.tcl @$(ECHO) "con" >> xsdb_run.tcl @$(ECHO) "exit" >> xsdb_run.tcl xsdb xsdb_run.tcl # @$(RM) -f xsdb_run.tcl # @$(RM) -f ps7_init.* ps7_init_gpl.* prog_flash: $(BIN_FILE) $(FSBL_FILE) program_flash -f $(BIN_FILE) -offset 0 -flash_type qspi_single -verify -fsbl $(FSBL_FILE) #---- Cleanup ------------------------------------------------------------------ clean: ifneq ($(LIB_SRC),) @$(RM) -fv $(LIB_FILE) endif @$(RM) -fv $(APP_BIN_FILE) @$(RM) -fv $(EE_BIN_FILE) @$(RM) -fv $(BIN_FILE) ifneq ($(wildcard $(SCRIPTS_PATH)/$(CKSUM)),) @$(RM) -fv $(ETC_PATH)/$(CKSUM) endif ifneq ($(wildcard $(SCRIPTS_PATH)/$(EEPROM)),) @$(RM) -fv $(ETC_PATH)/$(EEPROM) endif ifneq ($(wildcard $(SCRIPTS_PATH)/$(BITBIN)),) @$(RM) -fv $(ETC_PATH)/$(BITBIN) endif 以上是makefile内容,请说明在makefile中如何修改?
最新发布
10-30
<think>我们之前遇到了Bootgen警告:分区范围重叠。这些警告表明在生成的启动镜像(BOOT.BIN)中,某些分区在内存地址上存在重叠,这可能导致启动失败或运行时错误。现在我们需要修改Makefile来修复这个问题。 根本原因: 在BIF(Boot Image Format)文件中,我们定义了多个分区的加载地址(offset)和大小(size)。当两个分区的内存区域有重叠时,就会产生警告。 解决方案: 1. 检查每个分区的加载地址和文件大小,确保它们没有重叠。 2. 在BIF文件中为每个分区显式指定偏移地址(offset)和保留大小(size或reserve),并确保它们不重叠。 3. 或者,我们可以让Bootgen自动分配地址(不指定offset),但需要确保之前的分区有足够的大小保留。 在当前的Makefile中,我们生成了一个BIF文件(./etc/bootimage.bif),然后使用bootgen工具生成BOOT.BIN。我们需要修改这个BIF文件的内容,调整分区的偏移地址以避免重叠。 由于Makefile中通常通过脚本生成BIF文件,我们需要: - 修改生成BIF文件的脚本(可能是TCL脚本或Makefile中的规则) - 或者直接修改BIF文件模板(如果存在) 假设我们的Makefile中有一个规则生成BIF文件,内容可能类似于: ``` ./etc/bootimage.bif: echo "the_checksum_option: none" > $@ echo "image : {" >> $@ echo " [bootloader] $(FSBL_ELF)" >> $@ echo " $(BITSTREAM_BIT)" >> $@ echo " $(APPLICATION_ELF)" >> $@ echo " $(XML_FILE)" >> $@ echo "}" >> $@ ``` 我们需要调整每个分区的偏移地址。例如,我们可以为每个分区指定offset,并确保每个分区的结束地址(offset + size)小于下一个分区的offset。 注意:FSBL(第一级引导加载程序)通常位于固定的起始地址(对于Zynq,通常是0x0),而后续分区则需要根据前一个分区的大小进行偏移。 具体步骤: 1. 确定FSBL的加载地址(一般是0x0)和大小(通过查看FSBL.elf文件的大小,并考虑对齐)。 2. 计算FSBL之后的分区偏移。例如,FSBL大小为0x10000(64KB),则下一个分区可以从0x10000开始。 3. 为每个分区指定offset,并加上足够的安全边界(例如对齐到4KB边界)。 在BIF文件中,我们可以这样指定: ``` image : { [bootloader, destination_cpu=a53-0] fsbl.elf [offset=0x10000] xgvrd.bit [offset=0x300000] xgvrd.elf [offset=0x800000] xgvrd-tpg.xml } ``` 但是,请注意,我们也可以使用`reserve`参数来保留比实际文件更大的空间,以避免后续分区与当前分区重叠(如果后续分区地址设置不当)。 如何确定偏移量? - 可以使用`bootgen`的`-log`选项生成详细日志,查看每个分区的实际大小和地址分配。 - 或者,使用`objdump`或`readelf`等工具查看ELF文件的大小。 由于比特流文件(.bit)和XML文件是二进制文件,我们可以直接使用`ls -l`获取文件大小,并向上对齐(例如4KB对齐)。 修改Makefile的建议: 1. 修改生成BIF文件的规则,为每个分区显式指定偏移量(offset),并确保这些偏移量是递增的,且每个分区的结束地址(offset+文件大小,并向上对齐)小于下一个分区的偏移量。 2. 或者,如果不想手动计算,可以让Bootgen自动分配地址(去掉offset),但需要确保每个分区有足够的保留空间(使用`reserve`参数),这样Bootgen会自动安排地址而不重叠。 自动分配示例(不指定offset,但指定reserve): ``` image : { [bootloader, destination_cpu=a53-0] fsbl.elf [reserve=0x100000] xgvrd.bit [reserve=0x200000] xgvrd.elf [reserve=0x10000] xgvrd-tpg.xml } ``` 然而,自动分配可能不适用于所有情况(比如某些分区需要固定地址)。因此,通常我们更倾向于手动指定偏移地址。 如何修改Makefile: 假设Makefile中生成BIF文件的部分如下(伪代码): ```makefile BIF_FILE = ./etc/bootimage.bif $(BIF_FILE): @echo "image: {" > $@ @echo " [bootloader] $(FSBL_PATH)" >> $@ @echo " $(BITSTREAM_PATH)" >> $@ @echo " $(APP_ELF_PATH)" >> $@ @echo " $(XML_PATH)" >> $@ @echo "}" >> $@ ``` 修改为(手动指定偏移): ```makefile $(BIF_FILE): @echo "image: {" > $@ @echo " [bootloader, destination_cpu=a53-0] $(FSBL_PATH)" >> $@ @echo " [offset=0x10000] $(BITSTREAM_PATH)" >> $@ @echo " [offset=0x300000] $(APP_ELF_PATH)" >> $@ @echo " [offset=0x800000] $(XML_PATH)" >> $@ @echo "}" >> $@ ``` 注意:偏移地址的具体数值需要根据实际情况调整。我们需要知道每个分区的大小,并确保它们不重叠。 如何获取分区大小并自动计算偏移? 如果希望动态计算,可以在Makefile中添加计算步骤,例如: ```makefile # 计算FSBL的大小并向上对齐到4KB(0x1000) FSBL_SIZE = $(shell wc -c $(FSBL_PATH) | awk '{print $$1}') FSBL_ALIGNED_SIZE = $(shell echo $$(( (($(FSBL_SIZE)+4095)/4096)*4096 ))) # 然后定义偏移量 BITSTREAM_OFFSET = 0x$(shell printf "%x" $$(($(FSBL_ALIGNED_SIZE)))) # 然后BITSTREAM的偏移就是FSBL_ALIGNED_SIZE,接着计算BITSTREAM的结束地址(同样对齐),以此类推 ``` 但是,这样的Makefile会变得复杂。通常,我们根据经验设置一个足够大的偏移,只要确保大于前一个分区的最大可能大小即可。 推荐方案: 由于分区地址通常是固定的(特别是在生产系统中),我们可以根据硬件设计时确定的内存布局来设置固定的偏移地址。例如: - FSBL: 0x0 - Bitstream: 0x100000 (1MB偏移,通常足够存放FSBL,因为FSBL一般只有几百KB) - 应用程序: 0x300000 (3MB偏移,因为比特流可能较大,比如2MB,所以3MB可以避免重叠) - XML文件: 0x800000 (8MB偏移) 这些值需要根据实际文件大小调整。我们可以先编译一次,查看文件大小,然后设置合适的偏移。 修复警告后,重新运行`make`,观察是否还有重叠警告。 另外,注意警告中提到的具体分区: ``` [WARNING]: Partition fsbl.elf.0 range is overlapped with partition xgvrd.bit.0 memory range [WARNING]: Partition fsbl.elf.0 range is overlapped with partition xgvrd-tpg.xml.0 memory range [WARNING]: Partition xgvrd.bit.0 range is overlapped with partition xgvrd.elf.0 memory range [WARNING]: Partition xgvrd.bit.0 range is overlapped with partition xgvrd-tpg.xml.0 memory range ``` 这表明: - fsbl.elf与xgvrd.bit和xgvrd-tpg.xml重叠 - xgvrd.bit与xgvrd.elf和xgvrd-tpg.xml重叠 因此,我们需要增加fsbl.elf之后的分区偏移(例如xgvrd.bit的偏移),以及xgvrd.bit之后的分区偏移(例如xgvrd.elf和xgvrd-tpg.xml的偏移)。 假设当前BIF文件中没有指定offset,那么Bootgen会按顺序放置,但可能是因为某些分区实际需要的大小比预想的要大,导致重叠。所以,我们手动指定offset并拉开间隔。 修改后的BIF文件示例: ``` image : { [bootloader] fsbl.elf [offset=0x100000] xgvrd.bit [offset=0x400000] xgvrd.elf [offset=0x800000] xgvrd-tpg.xml } ``` 这里,我们设置: - 比特流从1MB(0x100000)开始,预留3MB的空间(0x100000到0x400000-1),因为比特流文件可能很大。 - 应用程序从4MB(0x400000)开始,预留4MB的空间(0x400000到0x800000-1)。 - XML文件从8MB(0x800000)开始。 这样,分区之间就有足够的间隙。 注意:这些地址需要根据实际项目的内存映射进行调整。确保整个启动镜像的地址范围不会超出板载RAM(OCM或DDR)的范围。 最后,修改Makefile中生成BIF文件的部分,使用我们设定的偏移地址。 修改后,重新运行`make`,警告应该消失。 如果问题仍然存在,请检查每个分区的实际大小,并调整偏移地址直至没有重叠。 相关问题: 1. 如何确定Zynq UltraScale+ MPSoC的启动镜像各分区的默认地址? 2. 在BIF文件中如何使用自动地址分配避免重叠? 3. 如何通过Bootgen日志分析分区地址映射? 4. 分区重叠会导致什么具体的运行时错误? </think>### 解决Bootgen分区范围重叠警告的Makefile修改方案 在Xilinx Vitis 2022.2中,分区重叠警告是由于Boot Image File (BIF)中定义的内存区域存在交叉导致的。以下是针对Makefile的修改方案: #### 1. 修改BIF文件生成规则 在Makefile中找到生成`bootimage.bif`的规则,显式指定每个分区的偏移地址和大小: ```makefile # 修改后生成BIF的规则 ./etc/bootimage.bif: @echo "image : {" > $@ @echo " [bootloader, destination_cpu=a53-0] fsbl.elf" >> $@ @echo " [offset=0x100000, load=0x100000] xgvrd.bit" >> $@ @echo " [offset=0x400000, load=0x400000] xgvrd.elf" >> $@ @echo " [offset=0x800000] xgvrd-tpg.xml" >> $@ @echo "}" >> $@ ``` **关键参数说明**: - `offset`:分区在BOOT.BIN中的存储位置 - `load`:分区加载到内存的地址 - 分区大小关系应满足:$offset_{n} \geq offset_{n-1} + size_{n-1}$ - 典型地址分配(根据文件大小调整): - FSBL: 0x0-0xFFFFF (1MB) - Bitstream: 0x100000-0x3FFFFF (3MB) - ELF应用: 0x400000-0x7FFFFF (4MB) - XML配置: 0x800000开始 #### 2. 添加分区大小验证 在Makefile中加入自动检查脚本,预防尺寸溢出: ```makefile # 分区大小验证步骤 check_partitions: @fsbl_size=$$(stat -c%s ./bin/fsbl.elf); \ bit_size=$$(stat -c%s ./bin/xgvrd.bit); \ if [ $$((0x100000)) -lt $$fsbl_size ]; then \ echo "错误: FSBL尺寸超出分配空间"; exit 1; \ fi; \ if [ $$((0x300000)) -lt $$bit_size ]; then \ echo "错误: 比特流尺寸超出分配空间"; exit 1; \ fi ``` #### 3. 修改bootgen命令 在生成BOOT.BIN时添加日志分析选项: ```makefile # 修改bootgen命令 ./bin/bootimage.bin: ./etc/bootimage.bif bootgen -image $< -arch zynq -o $@ -w on -log ./log/bootgen.log @grep -A 20 "Partition Address" ./log/bootgen.log # 显示地址分配详情 ``` #### 4. 完整Makefile结构示例 ```makefile # 目录定义 BIN_DIR := ./bin ETC_DIR := ./etc LOG_DIR := ./log # 主目标 all: eeprom bootimage # 创建目录 $(BIN_DIR) $(LOG_DIR): mkdir -p $@ # EEPROM生成 eeprom: $(BIN_DIR) @echo "生成EEPROM镜像..." # 原始eeprom.tcl命令 # 分区尺寸验证 check_partitions: $(BIN_DIR) @# 添加上述尺寸检查脚本 # 生成BIF文件 $(ETC_DIR)/bootimage.bif: check_partitions @echo "生成BIF文件..." @# 添加上述BIF生成脚本 # 生成BOOT.BIN bootimage: $(ETC_DIR)/bootimage.bif $(LOG_DIR) @echo "生成启动镜像..." bootgen -image $< -arch zynq -o $(BIN_DIR)/bootimage.bin -w on -log $(LOG_DIR)/bootgen.log @grep "Partition Address" $(LOG_DIR)/bootgen.log clean: rm -rf $(BIN_DIR)/* $(ETC_DIR)/bootimage.bif $(LOG_DIR)/* ``` ### 验证步骤 1. 运行`make check_partitions`验证尺寸 2. 执行完整的`make`流程 3. 检查日志文件`./log/bootgen.log`: - 确认无`overlapped`警告 - 验证分区地址范围无交叉 - 检查实际加载地址符合预期 > 通过显式地址分配和尺寸验证,可彻底解决分区重叠问题[^1][^3]。建议使用$$address_{end} = address_{start} + \lceil \frac{size}{alignment} \rceil \times alignment$$公式计算安全边界。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值