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_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_FLAKE8 "Add target with Python flake8 checker" (BUILD_DOCS OR BUILD_EXAMPLES) IF (NOT CMAKE_CROSSCOMPILING AND NOT APPLE_FRAMEWORK) )
variable_watch(OPENCV_DISABLE_THREAD_SUPPORT ocv_change_mode_var)
set(OPENCV_DISABLE_THREAD_SUPPORT "${OPENCV_DISABLE_THREAD_SUPPORT}")
+
+variable_watch(OPENCV_SEMIHOSTING ocv_change_mode_var)
+set(OPENCV_SEMIHOSTING "${OPENCV_SEMIHOSTING}")
--- /dev/null
+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)
static inline double cbrt(double x) { return (double)cv::cubeRoot((float)x); };
#endif
-using namespace std;
-
namespace {
void solveQuartic(const double *factors, double *realRoots) {
const double &a4 = factors[0];
double q3 = (72 * r4 * p4 - 2 * p4 * p4 * p4 - 27 * q4 * q4) / 432; // /=2
double t; // *=2
- complex<double> w;
+ std::complex<double> w;
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
- 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) {
- w.real(cbrt(w.real()));
+ w.real(std::cbrt(w.real()));
t = 2.0 * (w.real() + p3 / w.real());
} else {
w = pow(w, 1.0 / 3);
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 complex1 = 4 * p4 / 3 + t;
#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/11056
- complex<double> complex2 = 2 * q4;
- complex2 = complex<double>(complex2.real() / sqrt_2m.real(), 0);
+ std::complex<double> complex2 = 2 * q4;
+ complex2 = std::complex<double>(complex2.real() / sqrt_2m.real(), 0);
#else
- complex<double> complex2 = 2 * q4 / sqrt_2m;
+ std::complex<double> complex2 = 2 * q4 / sqrt_2m;
#endif
double sqrt_2m_rh = sqrt_2m.real() / 2;
double sqrt1 = sqrt(-(complex1 + complex2)).real() / 2;
ocv_target_compile_definitions(${the_module} PUBLIC "OPENCV_DISABLE_THREAD_SUPPORT=1")
endif()
+if(OPENCV_SEMIHOSTING)
+ ocv_target_compile_definitions(${the_module} PRIVATE "-DOPENCV_SEMIHOSTING")
+endif(OPENCV_SEMIHOSTING)
+
if(HAVE_HPX)
ocv_target_link_libraries(${the_module} LINK_PRIVATE "${HPX_LIBRARIES}")
endif()
static
int getNumberOfCPUs_()
{
+#ifndef OPENCV_SEMIHOSTING
/*
* 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.
#endif
return ncpus != 0 ? ncpus : 1;
+#else // OPENCV_SEMIHOSTING
+ return 1;
+#endif //OPENCV_SEMIHOSTING
}
int getNumberOfCPUs()
#if defined _WIN32 || defined WINCE
# include <windows.h>
#else
+#if OPENCV_HAVE_FILESYSTEM_SUPPORT
# include <dirent.h>
+#endif
# include <sys/stat.h>
#endif
void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc,
TestInfo* test_info) {
+#if OPENCV_HAVE_FILESYSTEM_SUPPORT
// In order to support thread-safe death tests, we need to
// remember the original working directory when the test program
// was first invoked. We cannot do this in RUN_ALL_TESTS(), as
GTEST_CHECK_(!original_working_dir_.IsEmpty())
<< "Failed to get the current working directory.";
}
+#endif
GetTestCase(test_info->test_case_name(),
test_info->type_param(),
// Returns the current working directory, or "" if unsuccessful.
FilePath FilePath::GetCurrentDir() {
+#if OPENCV_HAVE_FILESYSTEM_SUPPORT
#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
// something reasonable.
# endif // GTEST_OS_NACL
return FilePath(result == NULL ? "" : cwd);
#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.
// directory for any reason, including if the parent directory does not
// exist. Not named "CreateDirectory" because that's a macro on Windows.
bool FilePath::CreateFolder() const {
+#if OPENCV_HAVE_FILESYSTEM_SUPPORT
#if GTEST_OS_WINDOWS_MOBILE
FilePath removed_sep(this->RemoveTrailingPathSeparator());
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
return this->DirectoryExists(); // An error is OK if the directory exists.
}
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
--- /dev/null
+# 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)
--- /dev/null
+// 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
if(INSTALL_PYTHON_EXAMPLES)
add_subdirectory(python)
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)
if(INSTALL_C_EXAMPLES)
install(DIRECTORY data DESTINATION "${OPENCV_SAMPLES_SRC_INSTALL_PATH}" COMPONENT samples_data)
--- /dev/null
+# 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)
--- /dev/null
+# 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
+```
--- /dev/null
+# 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})
--- /dev/null
+// 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;
+}
--- /dev/null
+# 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})
--- /dev/null
+#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
--- /dev/null
+# 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})
--- /dev/null
+// 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;
+}