mirror of
https://github.com/opencv/opencv.git
synced 2024-11-24 03:00:14 +08:00
Merge pull request #20392 from fpetrogalli:aarch64-semihosting
AArch64 semihosting * [ts] Disable filesystem support in the TS module. Because of this change, all the tests loading data will file, but tat least the core module can be tested with the following line: opencv_test_core --gtest_filter=-"*Core_InputOutput*:*Core_globbing.accuracy*" * [aarch64] Build OpenCV for AArch64 semihosting. This patch provide a toolchain file that allows to build the library for semihosting applications [1]. Minimal changes have been applied to the code to be able to compile with a baremetal toolchain. [1] https://developer.arm.com/documentation/100863/latest The option `CV_SEMIHOSTING` is used to guard the bits in the code that are specific to the target. To build the code: cmake ../opencv/ \ -DCMAKE_TOOLCHAIN_FILE=../opencv/platforms/semihosting/aarch64-semihosting.toolchain.cmake \ -DSEMIHOSTING_TOOLCHAIN_PATH=/path/to/baremetal-toolchain/bin/ \ -DBUILD_EXAMPLES=ON -GNinja A barematel toolchain for targeting aarch64 semihosting can be found at [2], under `aarch64-none-elf`. [2] https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads The folder `samples/semihosting` provides two example semihosting applications. The two binaries can be executed on the host platform with: qemu-aarch64 ./bin/example_semihosting_histogram qemu-aarch64 ./bin/example_semihosting_norm Similarly, the test and perf executables of the modules can be run with: qemu-aarch64 ./bin/opecv_[test|perf]_<module> Notice that filesystem support is disabled by the toolchain file, hence some of the test that depend on filesystem support will fail. * [semihosting] Remove blank like at the end of file. [NFC] The spurious blankline was reported by https://pullrequest.opencv.org/buildbot/builders/precommit_docs/builds/31158. * [semihosting] Make the raw pixel file generation OS independent. Use the facilities provided by Cmake to generate the header file instead of a shell script, so that the build doesn't fail on systems that do not have a unix shell. * [semihosting] Rename variable for semihosting compilation. * [semihosting] Move the cmake configuration to a variable file. * [semihosting] Make the guard macro private for the core module. * [semihosting] Remove space. [NFC] * [semihosting] Improve comment with information about semihosting. [NFC] * [semihosting] Update license statement on top of sourvce file. [NFC] * [semihosting] Replace BM_SUFFIX with SEMIHOSTING_SUFFIX. [NFC] * [semihosting] Remove double space. [NFC] * [semihosting] Add some text output to the sample applications. * [semihosting] Remove duplicate entry in cmake configuration. [NFCI] * [semihosting] Replace `long` with `int` in sample apps. [NFCI] * [semihosting] Use `configure_file` to create the random pixels. [NFCI] * [semihosting][bugfix] Fix name of cmakedefine variable. * [semihosting][samples] Use CV_8UC1 for grayscale images. [NFCI] * [semihosting] Add readme file. * [semihosting] Remove blank like at the end of README. [NFC] This fixes the failure at https://pullrequest.opencv.org/buildbot/builders/precommit_docs/builds/31272.
This commit is contained in:
parent
755f4f324b
commit
d29c7e7871
@ -513,6 +513,7 @@ OCV_OPTION(ENABLE_CONFIG_VERIFICATION "Fail build if actual configuration doesn'
|
|||||||
OCV_OPTION(OPENCV_ENABLE_MEMALIGN "Enable posix_memalign or memalign usage" ON)
|
OCV_OPTION(OPENCV_ENABLE_MEMALIGN "Enable posix_memalign or memalign usage" ON)
|
||||||
OCV_OPTION(OPENCV_DISABLE_FILESYSTEM_SUPPORT "Disable filesystem support" OFF)
|
OCV_OPTION(OPENCV_DISABLE_FILESYSTEM_SUPPORT "Disable filesystem support" OFF)
|
||||||
OCV_OPTION(OPENCV_DISABLE_THREAD_SUPPORT "Build the library without multi-threaded code." OFF)
|
OCV_OPTION(OPENCV_DISABLE_THREAD_SUPPORT "Build the library without multi-threaded code." OFF)
|
||||||
|
OCV_OPTION(OPENCV_SEMIHOSTING "Build the library for semihosting target (Arm). See https://developer.arm.com/documentation/100863/latest." OFF)
|
||||||
|
|
||||||
OCV_OPTION(ENABLE_PYLINT "Add target with Pylint checks" (BUILD_DOCS OR BUILD_EXAMPLES) IF (NOT CMAKE_CROSSCOMPILING AND NOT APPLE_FRAMEWORK) )
|
OCV_OPTION(ENABLE_PYLINT "Add target with Pylint checks" (BUILD_DOCS OR BUILD_EXAMPLES) IF (NOT CMAKE_CROSSCOMPILING AND NOT APPLE_FRAMEWORK) )
|
||||||
OCV_OPTION(ENABLE_FLAKE8 "Add target with Python flake8 checker" (BUILD_DOCS OR BUILD_EXAMPLES) IF (NOT CMAKE_CROSSCOMPILING AND NOT APPLE_FRAMEWORK) )
|
OCV_OPTION(ENABLE_FLAKE8 "Add target with Python flake8 checker" (BUILD_DOCS OR BUILD_EXAMPLES) IF (NOT CMAKE_CROSSCOMPILING AND NOT APPLE_FRAMEWORK) )
|
||||||
|
@ -16,3 +16,6 @@ endmacro()
|
|||||||
|
|
||||||
variable_watch(OPENCV_DISABLE_THREAD_SUPPORT ocv_change_mode_var)
|
variable_watch(OPENCV_DISABLE_THREAD_SUPPORT ocv_change_mode_var)
|
||||||
set(OPENCV_DISABLE_THREAD_SUPPORT "${OPENCV_DISABLE_THREAD_SUPPORT}")
|
set(OPENCV_DISABLE_THREAD_SUPPORT "${OPENCV_DISABLE_THREAD_SUPPORT}")
|
||||||
|
|
||||||
|
variable_watch(OPENCV_SEMIHOSTING ocv_change_mode_var)
|
||||||
|
set(OPENCV_SEMIHOSTING "${OPENCV_SEMIHOSTING}")
|
||||||
|
10
cmake/vars/OPENCV_SEMIHOSTING.cmake
Normal file
10
cmake/vars/OPENCV_SEMIHOSTING.cmake
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
set(CV_TRACE OFF)
|
||||||
|
|
||||||
|
# These third parties libraries are incompatible with the semihosting
|
||||||
|
# toolchain.
|
||||||
|
set(WITH_JPEG OFF)
|
||||||
|
set(WITH_OPENEXR OFF)
|
||||||
|
set(WITH_TIFF OFF)
|
||||||
|
|
||||||
|
# Turn off `libpng` for some linking issues.
|
||||||
|
set(WITH_PNG OFF)
|
@ -7,8 +7,6 @@
|
|||||||
static inline double cbrt(double x) { return (double)cv::cubeRoot((float)x); };
|
static inline double cbrt(double x) { return (double)cv::cubeRoot((float)x); };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void solveQuartic(const double *factors, double *realRoots) {
|
void solveQuartic(const double *factors, double *realRoots) {
|
||||||
const double &a4 = factors[0];
|
const double &a4 = factors[0];
|
||||||
@ -30,29 +28,29 @@ void solveQuartic(const double *factors, double *realRoots) {
|
|||||||
double q3 = (72 * r4 * p4 - 2 * p4 * p4 * p4 - 27 * q4 * q4) / 432; // /=2
|
double q3 = (72 * r4 * p4 - 2 * p4 * p4 * p4 - 27 * q4 * q4) / 432; // /=2
|
||||||
|
|
||||||
double t; // *=2
|
double t; // *=2
|
||||||
complex<double> w;
|
std::complex<double> w;
|
||||||
if (q3 >= 0)
|
if (q3 >= 0)
|
||||||
w = -sqrt(static_cast<complex<double> >(q3 * q3 - p3 * p3 * p3)) - q3;
|
w = -std::sqrt(static_cast<std::complex<double> >(q3 * q3 - p3 * p3 * p3)) - q3;
|
||||||
else
|
else
|
||||||
w = sqrt(static_cast<complex<double> >(q3 * q3 - p3 * p3 * p3)) - q3;
|
w = std::sqrt(static_cast<std::complex<double> >(q3 * q3 - p3 * p3 * p3)) - q3;
|
||||||
if (w.imag() == 0.0) {
|
if (w.imag() == 0.0) {
|
||||||
w.real(cbrt(w.real()));
|
w.real(std::cbrt(w.real()));
|
||||||
t = 2.0 * (w.real() + p3 / w.real());
|
t = 2.0 * (w.real() + p3 / w.real());
|
||||||
} else {
|
} else {
|
||||||
w = pow(w, 1.0 / 3);
|
w = pow(w, 1.0 / 3);
|
||||||
t = 4.0 * w.real();
|
t = 4.0 * w.real();
|
||||||
}
|
}
|
||||||
|
|
||||||
complex<double> sqrt_2m = sqrt(static_cast<complex<double> >(-2 * p4 / 3 + t));
|
std::complex<double> sqrt_2m = sqrt(static_cast<std::complex<double> >(-2 * p4 / 3 + t));
|
||||||
double B_4A = -a3 / (4 * a4);
|
double B_4A = -a3 / (4 * a4);
|
||||||
double complex1 = 4 * p4 / 3 + t;
|
double complex1 = 4 * p4 / 3 + t;
|
||||||
#if defined(__clang__) && defined(__arm__) && (__clang_major__ == 3 || __clang_major__ == 4) && !defined(__ANDROID__)
|
#if defined(__clang__) && defined(__arm__) && (__clang_major__ == 3 || __clang_major__ == 4) && !defined(__ANDROID__)
|
||||||
// details: https://github.com/opencv/opencv/issues/11135
|
// details: https://github.com/opencv/opencv/issues/11135
|
||||||
// details: https://github.com/opencv/opencv/issues/11056
|
// details: https://github.com/opencv/opencv/issues/11056
|
||||||
complex<double> complex2 = 2 * q4;
|
std::complex<double> complex2 = 2 * q4;
|
||||||
complex2 = complex<double>(complex2.real() / sqrt_2m.real(), 0);
|
complex2 = std::complex<double>(complex2.real() / sqrt_2m.real(), 0);
|
||||||
#else
|
#else
|
||||||
complex<double> complex2 = 2 * q4 / sqrt_2m;
|
std::complex<double> complex2 = 2 * q4 / sqrt_2m;
|
||||||
#endif
|
#endif
|
||||||
double sqrt_2m_rh = sqrt_2m.real() / 2;
|
double sqrt_2m_rh = sqrt_2m.real() / 2;
|
||||||
double sqrt1 = sqrt(-(complex1 + complex2)).real() / 2;
|
double sqrt1 = sqrt(-(complex1 + complex2)).real() / 2;
|
||||||
|
@ -157,6 +157,10 @@ if(OPENCV_DISABLE_THREAD_SUPPORT)
|
|||||||
ocv_target_compile_definitions(${the_module} PUBLIC "OPENCV_DISABLE_THREAD_SUPPORT=1")
|
ocv_target_compile_definitions(${the_module} PUBLIC "OPENCV_DISABLE_THREAD_SUPPORT=1")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(OPENCV_SEMIHOSTING)
|
||||||
|
ocv_target_compile_definitions(${the_module} PRIVATE "-DOPENCV_SEMIHOSTING")
|
||||||
|
endif(OPENCV_SEMIHOSTING)
|
||||||
|
|
||||||
if(HAVE_HPX)
|
if(HAVE_HPX)
|
||||||
ocv_target_link_libraries(${the_module} LINK_PRIVATE "${HPX_LIBRARIES}")
|
ocv_target_link_libraries(${the_module} LINK_PRIVATE "${HPX_LIBRARIES}")
|
||||||
endif()
|
endif()
|
||||||
|
@ -888,6 +888,7 @@ T minNonZero(const T& val_1, const T& val_2)
|
|||||||
static
|
static
|
||||||
int getNumberOfCPUs_()
|
int getNumberOfCPUs_()
|
||||||
{
|
{
|
||||||
|
#ifndef OPENCV_SEMIHOSTING
|
||||||
/*
|
/*
|
||||||
* Logic here is to try different methods of getting CPU counts and return
|
* Logic here is to try different methods of getting CPU counts and return
|
||||||
* the minimum most value as it has high probablity of being right and safe.
|
* the minimum most value as it has high probablity of being right and safe.
|
||||||
@ -979,6 +980,9 @@ int getNumberOfCPUs_()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ncpus != 0 ? ncpus : 1;
|
return ncpus != 0 ? ncpus : 1;
|
||||||
|
#else // OPENCV_SEMIHOSTING
|
||||||
|
return 1;
|
||||||
|
#endif //OPENCV_SEMIHOSTING
|
||||||
}
|
}
|
||||||
|
|
||||||
int getNumberOfCPUs()
|
int getNumberOfCPUs()
|
||||||
|
@ -72,7 +72,9 @@
|
|||||||
#if defined _WIN32 || defined WINCE
|
#if defined _WIN32 || defined WINCE
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#else
|
#else
|
||||||
|
#if OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
|
#endif
|
||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1067,6 +1067,7 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
|
void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
|
||||||
Test::TearDownTestCaseFunc tear_down_tc,
|
Test::TearDownTestCaseFunc tear_down_tc,
|
||||||
TestInfo* test_info) {
|
TestInfo* test_info) {
|
||||||
|
#if OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||||
// In order to support thread-safe death tests, we need to
|
// In order to support thread-safe death tests, we need to
|
||||||
// remember the original working directory when the test program
|
// remember the original working directory when the test program
|
||||||
// was first invoked. We cannot do this in RUN_ALL_TESTS(), as
|
// was first invoked. We cannot do this in RUN_ALL_TESTS(), as
|
||||||
@ -1079,6 +1080,7 @@ class GTEST_API_ UnitTestImpl {
|
|||||||
GTEST_CHECK_(!original_working_dir_.IsEmpty())
|
GTEST_CHECK_(!original_working_dir_.IsEmpty())
|
||||||
<< "Failed to get the current working directory.";
|
<< "Failed to get the current working directory.";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
GetTestCase(test_info->test_case_name(),
|
GetTestCase(test_info->test_case_name(),
|
||||||
test_info->type_param(),
|
test_info->type_param(),
|
||||||
@ -9165,6 +9167,7 @@ static bool IsPathSeparator(char c) {
|
|||||||
|
|
||||||
// Returns the current working directory, or "" if unsuccessful.
|
// Returns the current working directory, or "" if unsuccessful.
|
||||||
FilePath FilePath::GetCurrentDir() {
|
FilePath FilePath::GetCurrentDir() {
|
||||||
|
#if OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||||
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
|
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
|
||||||
// Windows CE doesn't have a current directory, so we just return
|
// Windows CE doesn't have a current directory, so we just return
|
||||||
// something reasonable.
|
// something reasonable.
|
||||||
@ -9183,6 +9186,9 @@ FilePath FilePath::GetCurrentDir() {
|
|||||||
# endif // GTEST_OS_NACL
|
# endif // GTEST_OS_NACL
|
||||||
return FilePath(result == NULL ? "" : cwd);
|
return FilePath(result == NULL ? "" : cwd);
|
||||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||||
|
#else // OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||||
|
return FilePath("");
|
||||||
|
#endif // OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
||||||
@ -9391,6 +9397,7 @@ bool FilePath::CreateDirectoriesRecursively() const {
|
|||||||
// directory for any reason, including if the parent directory does not
|
// directory for any reason, including if the parent directory does not
|
||||||
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
||||||
bool FilePath::CreateFolder() const {
|
bool FilePath::CreateFolder() const {
|
||||||
|
#if OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||||
#if GTEST_OS_WINDOWS_MOBILE
|
#if GTEST_OS_WINDOWS_MOBILE
|
||||||
FilePath removed_sep(this->RemoveTrailingPathSeparator());
|
FilePath removed_sep(this->RemoveTrailingPathSeparator());
|
||||||
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
|
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
|
||||||
@ -9406,6 +9413,9 @@ bool FilePath::CreateFolder() const {
|
|||||||
return this->DirectoryExists(); // An error is OK if the directory exists.
|
return this->DirectoryExists(); // An error is OK if the directory exists.
|
||||||
}
|
}
|
||||||
return true; // No error.
|
return true; // No error.
|
||||||
|
#else // OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||||
|
return false;
|
||||||
|
#endif // OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||||
}
|
}
|
||||||
|
|
||||||
// If input name has a trailing separator character, remove it and return the
|
// If input name has a trailing separator character, remove it and return the
|
||||||
|
40
platforms/semihosting/aarch64-semihosting.toolchain.cmake
Normal file
40
platforms/semihosting/aarch64-semihosting.toolchain.cmake
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# This file is part of OpenCV project.
|
||||||
|
# It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
# of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
|
set(CMAKE_SYSTEM_NAME Generic)
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR AArch64)
|
||||||
|
|
||||||
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||||
|
|
||||||
|
set(PORT_FILE ${CMAKE_SOURCE_DIR}/platforms/semihosting/include/aarch64_semihosting_port.hpp)
|
||||||
|
|
||||||
|
set(COMMON_FLAGS "--specs=rdimon.specs -DOPENCV_INCLUDE_PORT_FILE=\\\"${PORT_FILE}\\\"")
|
||||||
|
|
||||||
|
set(CMAKE_AR ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-ar${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
|
set(CMAKE_ASM_COMPILER ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-gcc${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
|
set(CMAKE_C_COMPILER ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-gcc${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
|
set(CMAKE_CXX_COMPILER ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-g++${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
|
set(CMAKE_LINKER ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-ld${CMAKE_EXECUTABLE_SUFFIX})
|
||||||
|
set(CMAKE_OBJCOPY ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-objcopy${CMAKE_EXECUTABLE_SUFFIX} CACHE INTERNAL "")
|
||||||
|
set(CMAKE_RANLIB ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-ranlib${CMAKE_EXECUTABLE_SUFFIX} CACHE INTERNAL "")
|
||||||
|
set(CMAKE_SIZE ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-size${CMAKE_EXECUTABLE_SUFFIX} CACHE INTERNAL "")
|
||||||
|
set(CMAKE_STRIP ${SEMIHOSTING_TOOLCHAIN_PATH}aarch64-none-elf-strip${CMAKE_EXECUTABLE_SUFFIX} CACHE INTERNAL "")
|
||||||
|
set(CMAKE_C_FLAGS ${COMMON_FLAGS} CACHE INTERNAL "")
|
||||||
|
set(CMAKE_CXX_FLAGS ${COMMON_FLAGS} CACHE INTERNAL "")
|
||||||
|
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
|
||||||
|
set(OPENCV_SEMIHOSTING ON)
|
||||||
|
set(OPENCV_DISABLE_THREAD_SUPPORT ON)
|
||||||
|
set(OPENCV_DISABLE_FILESYSTEM_SUPPORT ON)
|
||||||
|
set(BUILD_SHARED_LIBS OFF)
|
||||||
|
set(OPENCV_FORCE_3RDPARTY_BUILD OFF)
|
||||||
|
|
||||||
|
|
||||||
|
# Enable newlib.
|
||||||
|
add_definitions(-D_GNU_SOURCE)
|
||||||
|
|
||||||
|
add_definitions(-D_POSIX_PATH_MAX=0)
|
42
platforms/semihosting/include/aarch64_semihosting_port.hpp
Normal file
42
platforms/semihosting/include/aarch64_semihosting_port.hpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
// of this distribution and at http://opencv.org/license.html.
|
||||||
|
|
||||||
|
#ifndef AARCH64_BAREMETAL_PORT_HPP
|
||||||
|
#define AARCH64_BAREMETAL_PORT_HPP
|
||||||
|
|
||||||
|
#include <malloc.h> // Needed for `memalign`.
|
||||||
|
#include <sys/errno.h> // Needed for `ENOMEM`.
|
||||||
|
|
||||||
|
// -std=c++11 is missing the following definitions when targeting
|
||||||
|
// semihosting on aarch64.
|
||||||
|
#if __cplusplus == 201103L
|
||||||
|
#include <cmath>
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#define M_SQRT2 1.41421356237309504880
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
inline double cbrt(double x) {
|
||||||
|
return ::cbrt(x);
|
||||||
|
}
|
||||||
|
inline double copysign(double mag, double sgn) {
|
||||||
|
return ::copysign(mag, sgn);
|
||||||
|
}
|
||||||
|
} //namespace std
|
||||||
|
#endif // __cplusplus == 201103L
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
// Redirect the implementation of `posix_memalign` to `memalign`
|
||||||
|
// as the former is
|
||||||
|
// missing at link time. https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html
|
||||||
|
__attribute__((weak)) int posix_memalign(void **memptr, size_t alignment, size_t size) {
|
||||||
|
void * ptr = memalign(alignment, size);
|
||||||
|
if (ptr != NULL) {
|
||||||
|
*memptr = ptr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
#endif
|
@ -45,7 +45,12 @@ endif()
|
|||||||
if(INSTALL_PYTHON_EXAMPLES)
|
if(INSTALL_PYTHON_EXAMPLES)
|
||||||
add_subdirectory(python)
|
add_subdirectory(python)
|
||||||
endif()
|
endif()
|
||||||
|
# The examples in this folder will work with a semihosting version of
|
||||||
|
# OpenCV. For more information about semihosting, see
|
||||||
|
# https://developer.arm.com/documentation/100863/latest
|
||||||
|
if(OPENCV_SEMIHOSTING)
|
||||||
|
add_subdirectory(semihosting)
|
||||||
|
endif()
|
||||||
ocv_install_example_src("." CMakeLists.txt samples_utils.cmake)
|
ocv_install_example_src("." CMakeLists.txt samples_utils.cmake)
|
||||||
if(INSTALL_C_EXAMPLES)
|
if(INSTALL_C_EXAMPLES)
|
||||||
install(DIRECTORY data DESTINATION "${OPENCV_SAMPLES_SRC_INSTALL_PATH}" COMPONENT samples_data)
|
install(DIRECTORY data DESTINATION "${OPENCV_SAMPLES_SRC_INSTALL_PATH}" COMPONENT samples_data)
|
||||||
|
10
samples/semihosting/CMakeLists.txt
Normal file
10
samples/semihosting/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# This file is part of OpenCV project.
|
||||||
|
# It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
# of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
|
set(SEMIHOSTING_SUFFIX semihosting)
|
||||||
|
|
||||||
|
add_subdirectory(include)
|
||||||
|
set(RAW_PIXEL_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||||
|
add_subdirectory(histogram)
|
||||||
|
add_subdirectory(norm)
|
27
samples/semihosting/README.md
Normal file
27
samples/semihosting/README.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Arm semihosting
|
||||||
|
|
||||||
|
This folder contain a toolchain file and a couple of examples for
|
||||||
|
building OpenCV based applications that can run in an [Arm
|
||||||
|
semihosting](https://developer.arm.com/documentation/100863/latest)
|
||||||
|
setup.
|
||||||
|
|
||||||
|
OpenCV can be compiled to target a semihosting platform as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake ../opencv/ \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=../opencv/platforms/semihosting/aarch64-semihosting.toolchain.cmake \
|
||||||
|
-DSEMIHOSTING_TOOLCHAIN_PATH=/path/to/baremetal-toolchain/bin/ \
|
||||||
|
-DBUILD_EXAMPLES=ON -GNinja
|
||||||
|
```
|
||||||
|
|
||||||
|
A barematel toolchain for targeting aarch64 semihosting can be found
|
||||||
|
[here](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads),
|
||||||
|
under `aarch64-none-elf`.
|
||||||
|
|
||||||
|
The code of the examples in the `norm` and `histogram` folders can be
|
||||||
|
executed with qemu in Linux userspace:
|
||||||
|
|
||||||
|
```
|
||||||
|
qemu-aarch64 ./bin/example_semihosting_histogram
|
||||||
|
qemu-aarch64 ./bin/example_semihosting_norm
|
||||||
|
```
|
26
samples/semihosting/histogram/CMakeLists.txt
Normal file
26
samples/semihosting/histogram/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# This file is part of OpenCV project.
|
||||||
|
# It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
# of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
|
set(PROJECT_NAME histogram)
|
||||||
|
project(${PROJECT_NAME})
|
||||||
|
|
||||||
|
ocv_install_example_src(histogram *.cpp *.hpp CMakeLists.txt)
|
||||||
|
|
||||||
|
set(LOCAL_DEPS
|
||||||
|
opencv_core
|
||||||
|
opencv_imgproc
|
||||||
|
${OPENCV_MODULES_PUBLIC}
|
||||||
|
${OpenCV_LIB_COMPONENTS})
|
||||||
|
ocv_check_dependencies(${LOCAL_DEPS})
|
||||||
|
|
||||||
|
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ocv_define_sample(histogram histogram.cpp ${SEMIHOSTING_SUFFIX})
|
||||||
|
ocv_include_modules_recurse(${LOCAL_DEPS})
|
||||||
|
target_include_directories(${histogram} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
target_include_directories(${histogram} PRIVATE ${RAW_PIXEL_INCLUDE})
|
||||||
|
ocv_target_link_libraries(${histogram} PRIVATE ${OPENCV_LINKER_LIBS}
|
||||||
|
${LOCAL_DEPS})
|
43
samples/semihosting/histogram/histogram.cpp
Normal file
43
samples/semihosting/histogram/histogram.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
|
#include <opencv2/imgproc.hpp>
|
||||||
|
#include <opencv2/imgcodecs.hpp>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <array>
|
||||||
|
#include <iostream>
|
||||||
|
#include "raw_pixels.hpp"
|
||||||
|
|
||||||
|
#define IMG_ROWS 100
|
||||||
|
#define IMG_COLS 100
|
||||||
|
|
||||||
|
static_assert(IMG_ROWS * IMG_COLS <= RAW_PIXELS_SIZE, "Incompatible size");
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Number of experiment runs
|
||||||
|
int no_runs = 2;
|
||||||
|
|
||||||
|
// https://docs.opencv.org/master/d3/d63/classcv_1_1Mat.html
|
||||||
|
cv::Mat src_new(IMG_ROWS, IMG_COLS, CV_8UC1, (void *)raw_pixels);
|
||||||
|
|
||||||
|
// Set parameters
|
||||||
|
int imgCount = 1;
|
||||||
|
const int channels[] = {0};
|
||||||
|
cv::Mat mask = cv::Mat();
|
||||||
|
cv::Mat hist;
|
||||||
|
int dims = 1;
|
||||||
|
const int hist_sizes[] = {256};
|
||||||
|
float Range[] = {0,256};
|
||||||
|
const float *ranges[] = {Range};
|
||||||
|
|
||||||
|
// Run calc Hist
|
||||||
|
for(int i=0; i < no_runs; i++){
|
||||||
|
std::cout << "Running iteration # "<< i << std::endl;
|
||||||
|
cv::calcHist(&src_new, imgCount, channels, mask, hist, dims, hist_sizes, ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
16
samples/semihosting/include/CMakeLists.txt
Normal file
16
samples/semihosting/include/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Populate a C array with random data.
|
||||||
|
set(RAW_PIXELS_SIZE 102400)
|
||||||
|
set(RAW_PIXELS_HEADER ${CMAKE_CURRENT_BINARY_DIR}/raw_pixels.hpp)
|
||||||
|
set(RAW_PIXELS_HEADER_IN ${CMAKE_CURRENT_SOURCE_DIR}/raw_pixels.hpp.in)
|
||||||
|
|
||||||
|
set(RAW_PIXEL_VALUES "")
|
||||||
|
# Seed the random number generator.
|
||||||
|
string(RANDOM LENGTH 8 ALPHABET 0123456789abcdf RANDOM_SEED 314 number)
|
||||||
|
math(EXPR LOOP_RANGE "${RAW_PIXELS_SIZE} - 1")
|
||||||
|
|
||||||
|
foreach(i RANGE ${LOOP_RANGE})
|
||||||
|
string(RANDOM LENGTH 8 ALPHABET 0123456789abcdf number)
|
||||||
|
string(CONCAT RAW_PIXEL_VALUES ${RAW_PIXEL_VALUES} "0x${number}, \\\n")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
configure_file(${RAW_PIXELS_HEADER_IN} ${RAW_PIXELS_HEADER})
|
11
samples/semihosting/include/raw_pixels.hpp.in
Normal file
11
samples/semihosting/include/raw_pixels.hpp.in
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef RAW_PIXELS_HPP
|
||||||
|
#define RAW_PIXELS_HP
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#cmakedefine RAW_PIXEL_VALUES @RAW_PIXEL_VALUES@
|
||||||
|
#cmakedefine RAW_PIXELS_SIZE @RAW_PIXELS_SIZE@
|
||||||
|
|
||||||
|
static std::uint32_t raw_pixels[RAW_PIXELS_SIZE] = {
|
||||||
|
RAW_PIXEL_VALUES
|
||||||
|
};
|
||||||
|
#endif //RAW_PIXELS_HPP
|
25
samples/semihosting/norm/CMakeLists.txt
Normal file
25
samples/semihosting/norm/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# This file is part of OpenCV project.
|
||||||
|
# It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
# of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
|
set(PROJECT_NAME norm)
|
||||||
|
project(${PROJECT_NAME})
|
||||||
|
|
||||||
|
ocv_install_example_src(norm *.cpp *.hpp CMakeLists.txt)
|
||||||
|
|
||||||
|
set(LOCAL_DEPS
|
||||||
|
opencv_core
|
||||||
|
${OPENCV_MODULES_PUBLIC}
|
||||||
|
${OpenCV_LIB_COMPONENTS})
|
||||||
|
ocv_check_dependencies(${LOCAL_DEPS})
|
||||||
|
|
||||||
|
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ocv_define_sample(norm norm.cpp ${SEMIHOSTING_SUFFIX})
|
||||||
|
ocv_include_modules_recurse(${LOCAL_DEPS})
|
||||||
|
target_include_directories(${norm} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
target_include_directories(${norm} PRIVATE ${RAW_PIXEL_INCLUDE})
|
||||||
|
ocv_target_link_libraries(${norm} PRIVATE ${OPENCV_LINKER_LIBS}
|
||||||
|
${LOCAL_DEPS})
|
33
samples/semihosting/norm/norm.cpp
Normal file
33
samples/semihosting/norm/norm.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
|
#include <opencv2/core.hpp>
|
||||||
|
#include <opencv2/imgcodecs.hpp>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <array>
|
||||||
|
#include <iostream>
|
||||||
|
#include "raw_pixels.hpp"
|
||||||
|
|
||||||
|
#define IMG_ROWS 100
|
||||||
|
#define IMG_COLS 100
|
||||||
|
|
||||||
|
static_assert(IMG_ROWS * IMG_COLS <= RAW_PIXELS_SIZE, "Incompatible size");
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Number of experiment runs
|
||||||
|
int no_runs = 2;
|
||||||
|
|
||||||
|
// https://docs.opencv.org/master/d3/d63/classcv_1_1Mat.html
|
||||||
|
cv::Mat src(IMG_ROWS, IMG_COLS, CV_8UC1, (void *)raw_pixels);
|
||||||
|
|
||||||
|
// Run calc Hist
|
||||||
|
for(int i=0; i < no_runs; i++){
|
||||||
|
std::cout << "Running iteration # "<< i << std::endl;
|
||||||
|
cv::norm(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user