以下是我试图在嵌入式Linux系统上运行的一些示例测试代码:
#include <iostream>
int main(int argc, char *argv[])
{
char c = 'A';
int i = 7;
std::cout << "Hello World from C++" << std::endl;
std::cout << "c=" << c << std::endl;
std::cout << "i=" << i << std::endl;
}
嵌入式系统是Microblaze,它是在Xilinx FPGA上运行的32位RISC软核处理器。请不要因为你的许多标准Linux知识仍然适用而被推迟。处理器配置为带有MMU的LSB,我正在使用的Linux版本(由Xilinx提供的PetaLinux)期望相同。我正在使用提供的GNU编译器; Microblaze似乎在GCC得到官方支持。
我遇到的问题是,当stdlib需要与整数进行交互时,会出现段错误。这是输出:
Hello World from C++
c=A
Segmentation fault
请注意,char处理得很好。这段代码的C等价物也可以正常工作:
#include <stdio.h>
int main(int argc, char *argv[])
{
char c = 'A';
int i = 7;
printf("Hello World from C\n");
printf("c=%c\n", c);
printf("i=%i\n", i);
return 0;
}
...
Hello World from C
c=A
i=7
这使我怀疑共享库libstdc++.so.6.0.20
存在问题。该库是由Xilinx提供的,所以它应该是正确的。该库的file
输出为:
libstdc++.so.6.0.20: ELF 32-bit LSB shared object, Xilinx MicroBlaze 32-bit RISC, version 1 (SYSV), dynamically linked, not stripped
我的二进制文件的file
输出是:
cpptest: ELF 32-bit LSB executable, Xilinx MicroBlaze 32-bit RISC, version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 2.6.32, stripped
我也尝试使用-static
标志静态链接我的二进制文件,但结果是一样的。
以下是我正在使用的最相关的编译器和链接器设置,但我尝试更改这些设置但无济于事。
CC=microblazeel-xilinx-linux-gnu-gcc
CXX=microblazeel-xilinx-linux-gnu-g++
CFLAGS= -O2 -fmessage-length=0 -fno-common -fno-builtin -Wall -feliminate-unused-debug-types
CPPFLAGS?=
CXXFLAGS= -O2 -fmessage-length=0 -fno-common -fno-builtin -Wall -feliminate-unused-debug-types
LDFLAGS=-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed
To compile:
@$(CCACHE) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o "$@"
To link:
@$(CXX) $(RELOBJECTS) $(LDFLAGS) $(EXT_LIBS) -o $(RELBINARY)
请注意,microblazeel
是指微生物编译器的小端版本。
我非常想调试这个或者至少看一下coredump,但是当segfault发生时似乎没有产生coredump,而且Microblaze Linux版本中没有gdb
可执行文件。也许我错过了什么?
感谢您花时间阅读本文。有什么想法吗?
答案 0 :(得分:1)
经过一些研究后我可以看到,vivado
是硬件开发IDE [因为它们提供试用期 - 所以它是硬件开发,他们总是想要收费]。
如果您正在使用Xilinx的标准SDK 主板,则应预先配置所有内容。否则,硬件设计师会生成一个带有Microblaze的硬件设计。
由此,您可能必须使用petalinux生成兼容的新引导,内核等图像。
你可能需要从源代码重建libstdc++
,但我会这样做作为最后的手段。例如,在gdb
工作并获得测试结果之前,请不要理会它。
以下是一些petalinux PDF文件:
http://www.xilinx.com/support/documentation/sw_manuals/petalinux2013_10/ug977-petalinux-getting-started.pdf
http://www.xilinx.com/support/documentation/sw_manuals/petalinux2013_10/ug981-petalinux-application-development-debug.pdf
开发指南显示了如何调用gdb(例如):
在目标系统上:
gdbserver host:1534 /bin/myapp
关于开发系统:
petalinux-utils --gdb myapp
后跟target remote 192.168.0.10:1534
我已经使用注释对Makefile进行了一些编辑。我已经评论了一些非必要的选项。请注意,我正在使用+=
运算符逐渐构建CFLAGS/CXXFLAGS
这里的基本思想是以最小的“标准”偏差进行构建。仅添加经过验证的基本选项构建和测试。逐个添加选项[每次重建和测试],直到找到导致问题的选项。
但是,我确实怀疑-fno-common
是问题的根源。另外,在较小程度上,我对-Wl,--as-needed
有点怀疑
这些选项应该有效吗?当然,但xilinx / microblaze不是没有x86 ......
我添加了两个命令行make变量:
DEBUG
- 使用gdb生成调试
VERBOSE
- 显示有关构建过程的所有内容
例如,尝试make <whatever> DEBUG=1 VERBOSE=1
CC = microblazeel-xilinx-linux-gnu-gcc
CXX = microblazeel-xilinx-linux-gnu-g++
CPPFLAGS ?=
CMFLAGS += -Wall -Werror
CMFLAGS += -fmessage-length=0
# compile for gdb session
# NOTES:
# (1) -gdwarf-2 may or may not be the the right option for microblaze
# (2) based on doc for -feliminate-unused-debug* petalinux/microblaze may want
# stabs format
ifdef DEBUG
CMFLAGS += -gdwarf-2
CMFLAGS += -O0
# compile for normal build
#else
CMFLAGS += -O2
CMFLAGS += -feliminate-unused-debug-types
endif
# NOTE: I used to use "@" on commands, but now I leave it off -- debug or not
# sure it's "ugly" but you can get used to it pretty quickly--YMMV
ifndef VERBOSE
Q :=
else
###Q := @
Q :=
endif
# let compiler/linker tell you _everything_:
# (1) configure options when tool was built
# (2) library search paths
# (3) linker scripts being used
ifdef VERBOSE
CMFLAGS += -v
LDFLAGS += -Wl,--verbose=2
endif
CMFLAGS += -fno-builtin
# NOTE: I'd _really_ leave this off as it may confuse c++ std as "<<" calls
# _M_insert (which is in the library, which is almost certainly _not_ using
# -fno-common)
###CMFLAGS += -fno-common
# NOTE: I'm also suspicious of this a little bit because the c++ lib may have
# some "weak" symbols that the c library doesn't
###LDFLAGS += -Wl,--as-needed
# NOTE: this seems harmless enough, but you can comment it out to see if it
# helps
LDFLAGS += -Wl,--hash-style=gnu
# NOTE: an optimization only
ifndef DEBUG
LDFLAGS += -Wl,-O1
endif
CFLAGS += $(CMFLAGS)
CXXFLAGS += $(CMFLAGS)
# NOTES:
# (1) leave this off for now -- doesn't save _that_ much and adds complexity
# to the build
# (2) IMO, I _never_ use it and I erase/uninstall it on any system I
# administrate (or just ensure the build doesn't use it by removing it
# from $PATH)--YMMV
###XCCACHE = $(CCACHE)
# to compile
$(Q)$(XCCACHE) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o "$@"
# to link
$(Q)$(CXX) $(RELOBJECTS) $(LDFLAGS) $(EXT_LIBS) -o $(RELBINARY)