在Sdx中使用xfOpenCV

接着上一篇 http://xilinx.eetrend.com/blog/2019/100043298.html 上一篇末尾在Sdx中使用xfOpenCV出了一些问题。我是ubuntu16.04,Sdx2018.2。

一、zcu102上跑xfOpenCV/example/dilation例子成功

按照https://www.cnblogs.com/tsfh/p/9186388.html 直接下载了

zcu102-rv-ss-2017-4.zip 我知道版本不对应,但我还是按照它后面的步骤做了下去,结果居然成功了?!按照xilinx-Sdx Libraried-xfOpenCV-add to project后就会有如下配置:

看我的配置如下:这是添加SYSROOT的环境变量,因为XILINX_SDK的环境变量之前就有所以不用管。


可以看到我没加载全部库,只加了这一些(像上一篇中在libjpeg时老是出问题,所以我想试试这里会不会出问题)结果居然成功了:看这个图片,而且也生成了sd_card文件夹,但图片没有在sd_card里面,因为我src文件夹下没有新建data放入图片,所以建议还是按照xfOpenCV/example文件夹下每个例子那样,将测试图片放入data文件夹,这样生成的sd_card中就会有图片。


因为我的Sdx是2018.2,所以可以看到我其实没有6.2.1文件夹,我的是7.2.1,与SYSROOT下的6.2.1竟然不冲突,难道是向下兼容?!所以才可以编译成功。我试了下将XILINX_SDK下的6.2.1改成我实际的7.2.1一样编译成功!!!我看了下/opt/Xilinx/zcu102_rv_ss/sw/sysroot/usr/lib下提供了所有需要的64位库,包括我上一篇末尾报错的那些库如libjpeg、gtk等。所以我之前选择zed7020时编译器就是32位,我虽然使用了xilinx提供的/opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib这些32位opencv库,但是像libjpeg和gtk等等没有提供啊,所以报错。zcu102_rv_ss的好处就是提供了所有库的64位版本。我想我现在跑zed7020就是缺32bit的库,并且是交叉编译的32bit库,如libjpeg!

二、zed7020跑dilation例子
我新建了一个xfOpenCV的工程选择zed7020跑dilation的例子,配置如下:因为上一篇中报错却N个库如libjpeg、libgtk等等,所以这里我先用自己下载的32位的jpeg库,结果可以看到依然是不行的,因为下载的这个不是交叉编译的!!!


将全部配置都改成了32位。接着我按照网上的自己交叉编译32bit的jpeg库,然后加入路径里重新build:

你看现在的报错里已经没有报libjpeg的错了!!!证明我说的是对的,跑32bit架构的板子是需要交叉编译后的32bit的库的。所以接下来办法1:我就将报错信息里的所有的库都交叉编译了一次并将路径都加进来就可以了!!!还有一个更高级的办:2:就是重新自己交叉编译一个opencv版本,即不用xilinx提供的交叉编译opencv版本太低了,比如重新交叉编译opencv3.4.1,在交叉编译时一定要选上上面报错信息中所有的库!!!这样就不用像办法1那样一个个搞了,opencv3.4.1交叉编译后的所有库都在opencv_world里,每个工程在settings里只加这一个库就好了。

看zed7020已经编译通过了,大概花费时间是二十分钟。我的settings是:


因为选的平台是zed7020是32位结构,所以我使用的是xilinx提供的32bit的编译器。只是没用它提供的32bit的opencv了,换成了交叉编译的opencv3.4.1!!!

看7035平台也一样通过了。这说明只要是32位架构都可以!一样配置!!

三、在zed7020或米联客7035平台上跑自己的小例子
于是我开始尝试建立自己的xfOpenCV小例子,无论选7020还是7035结果肯定都一样,这个上面已经证实。我其实就做了一个阈值化、膨胀、腐蚀。。。。。(此处表示做了N多尝试,换了N种写法,后来发现好像要与xfOpenCV结构一致,我写自己的例子就是一个头文件一个实现文件一个测试文件,发现这样不行。好像必须想例子那样5个文件?!)。。。。。与xfOpenCV/example/dilation结构差不多!编译过程没报错,但是为什么时间需要很长很长很长很长。。。从早上到现在此刻是下午3点,还在编译中........
Attempting to get a license: ap_sdsoc
Feature available: ap_sdsoc
INFO: [VPL 60-895] Target platform: /opt/Xilinx/SDx/2018.2/platforms/zynq7035/zynq7035.xpfm
INFO: [VPL 60-423] Target device: zynq7035
INFO: [VPL 60-1032] Extracting DSA to /home/jumper/FPGA_projects/sdsoc2018.2/myxfOpenCV/Release/_sds/p0/vivado/.local/dsa
INFO: [VPL 60-251] Hardware accelerator integration...
Creating Vivado project and starting FPGA synthesis.
[12:37:23] Finished 2nd of 6 tasks (FPGA linking synthesized kernels to platform). Elapsed time: 00h 12m 34s

[12:37:23] Starting logic optimization..
[12:40:25] Phase 1 Retarget
[12:41:00] Phase 2 Constant propagation
[12:41:15] Phase 3 Sweep
[12:41:40] Phase 4 BUFG optimization
[12:43:11] Phase 5 Shift Register Optimization
[12:43:56] Phase 6 Post Processing Netlist
[13:01:47] Finished 3rd of 6 tasks (FPGA logic optimization). Elapsed time: 00h 24m 23s

[13:01:47] Starting logic placement..
[13:04:03] Phase 1 Placer Initialization
[13:04:03] Phase 1.1 Placer Initialization Netlist Sorting
[13:06:19] Phase 1.2 IO Placement/ Clock Placement/ Build Placer Device

都已经到这一步了,我知道这基本上是没有问题了。只是需要等!!但是我在意的是只是增加2条语句,为什么差别这么大????!!!!我在谷歌和国内网站包括xilinx官网都没有看到别人用xfOpenCV写自己的小例子?!是不是这个原因,还是说我犯了xfOpenCV的哪些忌讳导致编译时间过长:

There are two fairly common reasons for synthesis taking too long (and 24 hours is way too long).

One has to do with RAM inference. If the code is attempting to describe a RAM using a large array, but the array cannot be mapped to block RAM or distributed RAM, then the tools will implement it with a huge number of flip-flops - often way more than the tool can accommodate. This will eventually fail, but only after chewing on it for many hours.

If you are inferring RAMs, you need to make sure that your code doesn't try and violate any of these requirements

  - block RAMs can only do synchronous reads

  - RAM contents (block or distributed) cannot be reset (they can be initialized in the bitstream but not reset afterwards)

  - RAMs can only be read and written a finite number of times in the same clock (generally either one or two)

Another common reason for synthesis taking too long is the unrolling of loops. FOR loops in RTL simulation, just mean iteration. But in synthesis, they mean the creating of multiple iterations of some gates. If the loops are big, you can end up with huge circuits, which, again, will cause synthesis too choke.

These are only two possible reasons

但是这些我都没有犯啊,我只是简简单单的增加一个阈值化和腐蚀而已。我想知道编译时间相差如此巨大的原因?!真的要等到天荒地老的感觉!!!

然而等了差不多一天,出来的却是:
===>The following messages were generated while processing /home/jumper/FPGA_projects/sdsoc2018.2/myxfOpenCV/Release/_sds/p0/vivado/prj/prj.runs/impl_1 :
ERROR: [VPL 30-640] Place Check : This design requires more F7 Muxes cells than are available in the target device. This design requires 553309 of such cell types but only 109300 compatible sites are available in the target device. Please analyze your synthesis results and constraints to ensure the design is mapped to Xilinx primitives as expected. If so, please consider targeting a larger device.
ERROR: [VPL 30-640] Place Check : This design requires more F8 Muxes cells than are available in the target device. This design requires 276585 of such cell types but only 54650 compatible sites are available in the target device. Please analyze your synthesis results and constraints to ensure the design is mapped to Xilinx primitives as expected. If so, please consider targeting a larger device.
ERROR: [VPL 30-640] Place Check : This design requires more Slice LUTs cells than are available in the target device. This design requires 1625950 of such cell types but only 171900 compatible sites are available in the target device. Please analyze your synthesis results and constraints to ensure the design is mapped to Xilinx primitives as expected. If so, please consider targeting a larger device. Please set tcl parameter "drc.disableLUTOverUtilError" to 1 to change this error to warning.
ERROR: [VPL 30-640] Place Check : This design requires more LUT as Logic cells than are available in the target device. This design requires 584522 of such cell types but only 171900 compatible sites are available in the target device. Please analyze your synthesis results and constraints to ensure the design is mapped to Xilinx primitives as expected. If so, please consider targeting a larger device. Please set tcl parameter "drc.disableLUTOverUtilError" to 1 to change this error to warning.
ERROR: [VPL 30-640] Place Check : This design requires more LUT as Memory cells than are available in the target device. This design requires 1041428 of such cell types but only 70400 compatible sites are available in the target device. Please analyze your synthesis results and constraints to ensure the design is mapped to Xilinx primitives as expected. If so, please consider targeting a larger device. Please set tcl parameter "drc.disableLUTOverUtilError" to 1 to change this error to warning.
ERROR: [VPL 30-640] Place Check : This design requires more LUT as Distributed RAM cells than are available in the target device. This design requires 1041244 of such cell types but only 70400 compatible sites are available in the target device. Please analyze your synthesis results and constraints to ensure the design is mapped to Xilinx primitives as expected. If so, please consider targeting a larger device. Please set tcl parameter "drc.disableLUTOverUtilError" to 1 to change this error to warning.
ERROR: [VPL 30-640] Place Check : This design requires more LUT6 cells than are available in the target device. This design requires 295337 of such cell types but only 218600 compatible sites are available in the target device. Please analyze your synthesis results and constraints to ensure the design is mapped to Xilinx primitives as expected. If so, please consider targeting a larger device.
ERROR: [VPL 30-640] Place Check : This design requires more MUXF7 cells than are available in the target device. This design requires 553309 of such cell types but only 109300 compatible sites are available in the target device. Please analyze your synthesis results and constraints to ensure the design is mapped to Xilinx primitives as expected. If so, please consider targeting a larger device.
ERROR: [VPL 30-640] Place Check : This design requires more MUXF8 cells than are available in the target device. This design requires 276585 of such cell types but only 54650 compatible sites are available in the target device. Please analyze your synthesis results and constraints to ensure the design is mapped to Xilinx primitives as expected. If so, please consider targeting a larger device.
ERROR: [VPL 30-640] Place Check : This design requires more RAMS64E cells than are available in the target device. This design requires 1036800 of such cell types but only 70400 compatible sites are available in the target device. Please analyze your synthesis results and constraints to ensure the design is mapped to Xilinx primitives as expected. If so, please consider targeting a larger device.
ERROR: [VPL 30-99] Placer failed with error: 'Implementation Feasibility check failed, Please see the previously displayed individual error or warning messages for more details.'
Please review all ERROR and WARNING messages during placement to understand the cause for failure.
ERROR: [VPL 17-69] Command failed: Placer could not place all instances
ERROR: [VPL 60-704] Integration error, problem implementing dynamic region, place_design ERROR
ERROR: [VPL 60-806] Failed to finish platform linker
ERROR: [SdsCompiler 83-5019] Exiting sds++ : Error when calling '/opt/Xilinx/SDx/2018.2/bin/vpl --iprepo /home/jumper/FPGA_projects/sdsoc2018.2/myxfOpenCV/Release/_sds/iprepo/repo --iprepo /opt/Xilinx/SDx/2018.2/data/ip/xilinx --platform /opt/Xilinx/SDx/2018.2/platforms/zynq7035/zynq7035.xpfm --temp_dir /home/jumper/FPGA_projects/sdsoc2018.2/myxfOpenCV/Release/_sds/p0 --output_dir /home/jumper/FPGA_projects/sdsoc2018.2/myxfOpenCV/Release/_sds/p0/vpl --input_file /home/jumper/FPGA_projects/sdsoc2018.2/myxfOpenCV/Release/_sds/p0/.xsd/top.bd.tcl --target hw --save_temps --kernels dilation_accel:adapter --webtalk_flag SDSoC --remote_ip_cache /home/jumper/FPGA_projects/sdsoc2018.2/ip_cache --xp "param:compiler.deleteDefaultReportConfigs=false" '
sds++ log file saved as /home/jumper/FPGA_projects/sdsoc2018.2/myxfOpenCV/Release/_sds/reports/sds.log
ERROR: [SdsCompiler 83-5004] Build failed

黎明前的黑暗么?逗我呢?怎么可能会资源不够?!哪怕只增加了一条语句,就报这个问题即使换成7020肯定也一样的问题:
ERROR: [VPL 8-5834] Design needs 4581 RAMB18 which is more than device capacity of 280
ERROR: [VPL 17-69] Command failed: Vivado Synthesis failed
ERROR: [VPL 60-704] Integration error, One or more synthesis runs failed during dynamic region dcp generation
ERROR: [VPL 60-806] Failed to finish platform linker

在快编译成功时报这个错?!为什么会这样?!。。。(此处表示又做了N多尝试以及每次尝试build后的等待)。。。。终于知道了:xf::Mat不能是局部变量!!!否则build会被挂起,从早上开始上班到下班加班一小时依旧是build中;或者报错说资源不够等现象都是因为这个原因!!!!!!所以我是作为参数传进去的!!!(这里又涉及到ap_memory问题折腾我N久)

另外要注意:read+write型的xf::Mat不能是SEQUENTIAL(FIFO)!!!!不支持!!!坑货

后来改正了这个就可以编译成功了!

虽然只是简简单单的阈值化---膨胀----腐蚀,但编译成功了,还是开心!因为之前哪怕只是加一句阈值化都会报N多各种各样的错误,解决一个又会来一个!

经过实验,终于找到正确的写法:看这个工程只有3个文件,即头文件、实现文件和测试文件!注意头文件摆放的位置,一定不要打乱,因为会无法编译,要么是build一个世纪,要么直接报错,而且是报很多不相关的错!!!

像我这样写是可以编译成功的!!!而且生成了我要的库文件!

我之前不知道头文件引用顺序会导致build出错,报了N多错:
Performing accelerator source linting for FindTarget
Performing pragma generation
INFO: [PragmaGen 83-3231] Successfully generated tcl script: /home/jumper/FPGA_projects/sdsoc2018.2/myxfOpenCV/Release/_sds/vhls/FindTarget.tcl
Moving function FindTarget to Programmable Logic
ERROR: [SdsCompiler 83-5019] Exiting sds++ : Error when calling '/opt/Xilinx/Vivado/2018.2/bin/vivado_hls /home/jumper/FPGA_projects/sdsoc2018.2/myxfOpenCV/Release/_sds/vhls/FindTarget_run.tcl -l FindTarget_vivado_hls.log'
sds++ log file saved as /home/jumper/FPGA_projects/sdsoc2018.2/myxfOpenCV/Release/_sds/reports/sds_XiangAnWO3.log
ERROR: [SdsCompiler 83-5004] Build failed
/Release/_sds/reports/sds_.log :In file included from /opt/Xilinx/Vivado/2018.2/lnx64/tools/clang/bin/../lib/clang/3.1/include/xmmintrin.h:31:
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/lib/gcc/arm-linux-gnueabihf/7.2.1/include/mmintrin.h:28:2: error: mmintrin.h included without enabling WMMX/WMMX2 instructions (e.g. -march=iwmmxt or -march=iwmmxt2)
#error mmintrin.h included without enabling WMMX/WMMX2 instructions (e.g. -march=iwmmxt or -march=iwmmxt2)

my solution a:
#define __SSE__
#define __SSE2__
#define __IWMMXT__

mmintrin.h:84:18: error: use of undeclared identifier '__builtin_arm_wpackhss'
return (__m64) __builtin_arm_wpackhss ((__v4hi)__m1, (__v4hi)__m2);
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/lib/gcc/arm-linux-gnueabihf/7.2.1/include/mmintrin.h:93:18: error: use of undeclared identifier '__builtin_arm_wpackwss'
return (__m64) __builtin_arm_wpackwss ((__v2si)__m1, (__v2si)__m2);

my solution b:
https://stackoverflow.com/questions/9144545/sse-instruction-set-not-enab...

看报的就是类似这种无意义的错,我有尝试去解决,但解决一个又来一个,无穷无尽!所以头文件引用一定要注意顺序!!!

血的教训!!!

此时此刻这个在Sdx中编译成功的例子是由以下3个文件组成:
#ifndef _XF_MYXF_ACCEL_H_
#define _XF_MYXF_ACCEL_H_

#include "hls_stream.h"
#include "ap_int.h"

#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_common.h"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_utility.h"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_dilation.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_erosion.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_threshold.hpp"

/* config width and height */
#define WIDTH 3840
#define HEIGHT 2160

#define RO 0 // Resource Optimized (8-pixel implementation)
#define NO 1 // Normal Operation (1-pixel implementation)

/* define the input and output types */
#if NO
#define NPC1 XF_NPPC1
#endif

#if RO
#define NPC1 XF_NPPC8
#endif

#define TYPE XF_8UC1
void myxffun(xf::Mat &_src,xf::Mat &threshimg,xf::Mat &dilateimg,xf::Mat &_dst);

#endif // _XF_DILATION_CONFIG_H_

#include "xf_myxf_accel.h"

#pragma SDS data zero_copy("threshimg.data"[0:HEIGHT*WIDTH], "dilateimg.data"[0:HEIGHT*WIDTH])
#pragma SDS data access_pattern("_src.data":SEQUENTIAL, "_dst.data":SEQUENTIAL)
#pragma SDS data copy("_src.data"[0:HEIGHT*WIDTH], "_dst.data"[0:HEIGHT*WIDTH])
#pragma SDS data mem_attribute("_src.data":NON_CACHEABLE|PHYSICAL_CONTIGUOUS)
#pragma SDS data mem_attribute("_dst.data":NON_CACHEABLE|PHYSICAL_CONTIGUOUS)
void myxffun(xf::Mat &_src,xf::Mat &threshimg,xf::Mat &dilateimg,xf::Mat &_dst)
{
xf::Threshold(_src,threshimg,30,255,0);
xf::dilate(threshimg,dilateimg);
xf::erode(dilateimg,_dst);
}

#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
//#include "sds_lib.h"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_sw_utils.h"

#include "xf_myxf_accel.h"

int main(int argc, char** argv)
{
cv::Mat in_img,in_img1,out_img,ocv_ref;
cv::Mat in_gray,in_gray1,diff;

// reading in the color image
in_gray = cv::imread("./data/im0.jpg", 0);

if (in_gray.data == NULL)
{
fprintf(stderr,"Cannot open image\n");
return 0;
}

static xf::Mat imgInput(in_gray.rows,in_gray.cols);
static xf::Mat imgOutput(in_gray.rows,in_gray.cols);
static xf::Mat threshimgtb(in_gray.rows,in_gray.cols);
static xf::Mat dilateimgtb(in_gray.rows,in_gray.cols);

#pragma SDS data copy(in_gray.data)
imgInput.copyTo(in_gray.data);

myxffun(imgInput,threshimgtb,dilateimgtb, imgOutput);

// Write output image
xf::imwrite("hls_out.jpg",imgOutput);

return 0;
}

四、xfOpenCV+HLS video function的混合例子
1,将hls video functions 写在一个functionA,xfopencv function写在functionB中,同一个accel.cpp

其中发现cv::Mat不能作为函数参数,opencv函数只能用在main.cpp中!所以我用hls::stream>替换了作为参数。然而还是报无意义的错:
/opt/Xilinx/Vivado/2018.2/include/hls/hls_video_imgproc.h:306:63: error: expected ',' or '>' in template-parameter-list
template
^
../src/xf_myxf_accel.h:16:16: note: expanded from macro 'HEIGHT'
#define HEIGHT 2160
^
/opt/Xilinx/Vivado/2018.2/include/hls/hls_video_imgproc.h:306:69: error: expected unqualified-id
template
^
/opt/Xilinx/Vivado/2018.2/include/hls/hls_video_imgproc.h:574:7: error: explicit specialization of non-template class 'filter_opr'

/opt/Xilinx/Vivado/2018.2/include/hls_opencv.h:264:13: error: no matching constructor for initialization of 'cv::Mat'

我看到论坛说如果是有一个cpp中两个函数有调用关系,则不能写在同一个cpp中。可是我没有调用关系啊?怎么也这样?!经过N次尝试,不会再在hls video function调用的地方报错了 ,现在的报错是:
Preliminary link application ELF
/home/jumper/FPGA_projects/sdsoc2018.2/HLSxfOpenCV/Release/_sds/swstubs/xf_myxf_tb.o:在函数‘void xf::imwrite(char const*, xf::Mat&)’中:
xf_myxf_tb.cpp:(.text._ZN2xf7imwriteILi0ELi1080ELi1920ELi1EEEvPKcRNS_3MatIXT_EXT0_EXT1_EXT2_EEE[_ZN2xf7imwriteILi0ELi1080ELi1920ELi1EEEvPKcRNS_3MatIXT_EXT0_EXT1_EXT2_EEE]+0x2dc):对‘cv::_InputArray::_InputArray(cv::Mat const&)’未定义的引用
make: *** [HLSxfOpenCV.elf] Error 1
xf_myxf_tb.cpp:(.text._ZN2xf7imwriteILi0ELi1080ELi1920ELi1EEEvPKcRNS_3MatIXT_EXT0_EXT1_EXT2_EEE[_ZN2xf7imwriteILi0ELi1080ELi1920ELi1EEEvPKcRNS_3MatIXT_EXT0_EXT1_EXT2_EEE]+0x2fc):对‘cv::imwrite(std::__cxx11::basic_string, std::allocator > const&, cv::_InputArray const&, std::vector > const&)’未定义的引用
/home/jumper/FPGA_projects/sdsoc2018.2/HLSxfOpenCV/Release/_sds/swstubs/xf_myxf_tb.o:在函数‘void hls::arithm_pro<:kernel_scale unsigned="" char="" double="">(hls::Mat&, hls::Scalar>(11))+(1), unsigned char>, hls::Mat&, double, double, double)’中:
xf_myxf_tb.cpp:(.text._ZN3hls10arithm_proINS_12kernel_scaleELi1080ELi1920ELi4096EhLi4096EdddEEvRNS_3MatIXT0_EXT1_EXT2_EEENS_6ScalarIXplrsanT2_lsmiLi512ELi1ELi11ELi11ELi1EET3_EERNS2_IXT0_EXT1_EXT4_EEET5_T6_T7_[_ZN3hls10arithm_proINS_12kernel_scaleELi1080ELi1920ELi4096EhLi4096EdddEEvRNS_3MatIXT0_EXT1_EXT2_EEENS_6ScalarIXplrsanT2_lsmiLi512ELi1ELi11ELi11ELi1EET3_EERNS2_IXT0_EXT1_EXT4_EEET5_T6_T7_]+0xac):对‘hls::__isnan(double)’未定义的引用
/home/jumper/FPGA_projects/sdsoc2018.2/HLSxfOpenCV/Release/_sds/swstubs/xf_myxf_tb.o:在函数‘main’中:
xf_myxf_tb.cpp:(.text.startup+0x218):对‘cv::imread(std::__cxx11::basic_string, std::allocator > const&, int)’未定义的引用
xf_myxf_tb.cpp:(.text.startup+0x32c):对‘cv::Mat::operator _IplImage() const’未定义的引用
collect2: error: ld returned 1 exit status
ERROR: [SdsCompiler 83-5019] Exiting sds++ : Error when calling 'arm-linux-gnueabihf-g++ /home/jumper/FPGA_projects/sdsoc2018.2/HLSxfOpenCV/Release/_sds/swstubs/xf_myxf_accel.o /home/jumper/FPGA_projects/sdsoc2018.2/HLSxfOpenCV/Release/_sds/swstubs/xf_myxf_tb.o /home/jumper/FPGA_projects/sdsoc2018.2/HLSxfOpenCV/Release/_sds/swstubs/portinfo.o -L/home/jumper/workspace/xilinx_opencv_3.4.1/lib -lopencv_world -L /opt/Xilinx/SDx/2018.2/target/aarch32-linux/lib -L/home/jumper/FPGA_projects/sdsoc2018.2/HLSxfOpenCV/Release/_sds/swstubs -Wl,--start-group -Wl,--end-group -Wl,--start-group -lpthread -lsds_lib -lxlnk_stub -Wl,--end-group -o /home/jumper/FPGA_projects/sdsoc2018.2/HLSxfOpenCV/Release/_sds/swstubs/HLSxfOpenCV.elf'
sds++ log file saved as /home/jumper/FPGA_projects/sdsoc2018.2/HLSxfOpenCV/Release/_sds/reports/sds.log
ERROR: [SdsCompiler 83-5004] Build failed

makefile:45: recipe for target 'HLSxfOpenCV.elf' failed

好像是缺少库,看来在编译32位的opencv3.4.1时没有编译所有需要的库。

此时此刻黎明前的黑暗的例子是这样:只改了main函数部分:

#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
//#include "sds_lib.h"

//the following two hpp can only be included in testbeach!!!!!!!
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_sw_utils.h"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_infra.h"

//why can't include these following head file?!
#include "hls_opencv.h"
#include "hls/hls_video_arithm.h"
#include "hls/hls_video_types.h"
#include "hls/hls_video_core.h"
#include "hls/hls_video_imgproc.h"

#include "xf_myxf_accel.h"

int main(int argc, char** argv)
{
cv::Mat in_img,in_img1,out_img,ocv_ref;
cv::Mat in_gray,in_gray1,diff;

// reading in the color image
in_gray = cv::imread("./data/im0.jpg",0);

if (in_gray.data == NULL)
{
fprintf(stderr,"Cannot open image\n");
return 0;
}

//hls video function can only be here ?!
hls::stream > bgr_src;
cvMat2AXIvideo(in_gray, bgr_src);
hls::stream > bgr_scaleimg;

hls::Mat bgr_src_mat(HEIGHT,WIDTH);
hls::Mat bgr_scaleimg_mat(HEIGHT,WIDTH);
hls::Scale(bgr_src_mat,bgr_scaleimg_mat,1.5);
hls::Mat grayimg;
hls::CvtColor(bgr_scaleimg_mat, grayimg);

// hls::stream > bgr_src;
// cvMat2AXIvideo(in_gray, bgr_src);
// hls::stream > grayimg;
// hlsfun(bgr_src,grayimg);

static xf::Mat imgInput(in_gray.rows,in_gray.cols);
static xf::Mat imgOutput(in_gray.rows,in_gray.cols);
static xf::Mat threshimgtb(in_gray.rows,in_gray.cols);
static xf::Mat dilateimgtb(in_gray.rows,in_gray.cols);

// xf::AXIvideo2xfMat(grayimg,imgInput);

#pragma SDS data copy(in_gray.data)
imgInput.copyTo(in_gray.data);

myxffun(imgInput,threshimgtb,dilateimgtb, imgOutput);

// Write output image
xf::imwrite("hls_out.jpg",imgOutput);

// cv::Mat dstimg(HEIGHT,WIDTH,CV_8UC1);
// dstimg.data=imgOutput.copyFrom();
// cv::imwrite("debug.jpg",dstimg);

return 0;
}

现在不会报说hls的函数找不到,如hls::Scale hls::CvtColor,现在这些函数都找得到,但就是报上面那些无意义的错。

找了很久资料,也尝试了很多次去解决,但最终还是failed !哎,在Xilinx论坛上问了,也还没人回答。难道是不能在Sdx中使用HLS video functions ??!!如果有人知道,麻烦告知,不胜感激。

今天从Xilinx论坛了解到因为hls只支持仿真,不支持综合,所以不能在Sdx 2018.2中使用!!!!!!!但是最新的Sdx 2018.3中新增了hls video function的端口,所以可以使用hls video function and xfopencv了,不会再报错了!!!所以想同时使用这两种函数可以升级Sdx!!

五、标准xfopencv实例设置

看完前面应该知道,我在Sdx 2018.2的界面Sdx library添加进xfopencv后出现很多默认的设置(路径和库),然后我是修改源代码的#include变成绝对路径才编译通过。可是我发现我同事的居然不用修改成绝对路径,而且更奇怪的是他将xfopencv-add to project后没有出现那些默认的设置?!(这里尚不知原因,可能是版本不同?!)于是我也想用他一样的相对路径,又不想重新卸载重装,于是开始我的探索:

当我改成相对路径后如#include "common/xf_common.h" 同时将xfopencv-add to project带来的默认设置删掉同时删掉SYSROOT改成下图所示:

然后编译出现问题如下:
Preliminary link application ELF
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/lib/crt1.o:找不到
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/lib/crt1.o:找不到
collect2: error: ld returned 1 exit status

然后我将/opt/Xilinx/SDx/2018.2/gnu/aarch32/5.2.1/lnx64/arm-linux-gnueabihf/libc/usr/lib 下的crti.o和crt1.o拷贝到 /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/lib下出现问题:
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: 找不到 -lpthread
collect2: error: ld returned 1 exit status

于是我又将 /opt/Xilinx/SDx/2018.2/gnu/aarch32/5.2.1/lnx64/arm-linux-gnueabihf/libc/usr/lib/libpthread.so和 libpthread_nonshared.a复制到
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/lib/下面,并且vi libpthread.so将Group指定的绝对路径去掉即去掉/lib和/usr/lib。结果还是报错:

Preliminary link application ELF
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find libpthread.so.0
collect2: error: ld returned 1 exit status

无论我把我电脑哪里的libpthread.so.0复制过来,都仍旧报错,要么说“跳过不兼容的libpthread.so.0 找不到libpthread.so.0”要么说“无法识别的格式 libpthread.so.0”要么说“libpthread.so.0被截断”等。。。而我同事的什么错误都没报。

后来我又看到:

我看到这里居然还有-sysroot /lib /usr/lib我明白这是之前使用xfopencv-add to project带来的,而且修改不了。

所以我重新新建一个工程,直接将上一个工程得到的libs/xfopencv复制进我的新工程,这样我就不用使用Sdx界面的xilinx-sdx library-add to project这个功能而带来很多我修改不了的设置了。没有使用SYSROOT,也没有使用/lib或者/usr/lib。然后将我的工程设置如下:

然后重新编译!竟然编译通过了!!!太开心了!!!那就是对于我电脑上的这个版本而言,我不能使用Sdx界面的xilinx-sdx library-xfopencv-add to project这个功能(我同事的可以使用),然后以后可以使用相对路径,同时以后只能复制libs/xfopencv去新的工程并将新工程配置如上图所示,那么就可以编译成功了!!!

另外很久以前我编译完的sd_card不可以在ubuntu下跑,后来找到 https://www.cnblogs.com/jadeny/p/7674313.html 按下图这样就可以在ubuntu下跑起来了。不用每次编译完后把板子拿到windows下跑了!!!

终于搞好了!觉得这种东西真是同人不同命,也许一样的步骤,你的结果就是和别人不一样,甚至出现某些报错,而别人就没出现,而你要去解决这些报错,达到和别人一样的效果。其实可能还是电脑哪里配置不一样。

本文转载自:https://blog.csdn.net/wd1603926823/article/details/82867166

推荐阅读