Skip to content

Commit adb5ef0

Browse files
authored
Merge pull request #40 from sparkfun/features_for_launch
First Release
2 parents 819eda1 + e502357 commit adb5ef0

28 files changed

+4063
-187
lines changed

.github/workflows/build.yml

Lines changed: 0 additions & 18 deletions
This file was deleted.

.gitmodules

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
[submodule "src/opencv"]
2-
path = src/opencv
3-
url = https://github.com/sfe-SparkFro/opencv.git
4-
[submodule "src/ulab"]
5-
path = src/ulab
1+
[submodule "opencv"]
2+
path = opencv
3+
url = https://github.com/opencv/opencv.git
4+
[submodule "ulab"]
5+
path = ulab
66
url = https://github.com/v923z/micropython-ulab.git
7-
[submodule "micropython"]
8-
path = micropython
9-
url = https://github.com/sparkfun/micropython.git

Makefile

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
1-
# Set Pico SDK flags to create our own malloc wrapper and enable exceptions
2-
CMAKE_ARGS += -DSKIP_PICO_MALLOC=1 -DPICO_CXX_ENABLE_EXCEPTIONS=1
1+
ifndef PLATFORM
2+
$(error PLATFORM not specified. Use 'make PLATFORM=rp2350' or similar.)
3+
endif
34

4-
# Get current directory
5-
CURRENT_DIR = $(shell pwd)
5+
TOOLCHAIN_FILE = platforms/${PLATFORM}.toolchain.cmake
66

7-
# Set the MicroPython user C module path to the OpenCV module
8-
MAKE_ARGS = USER_C_MODULES="$(CURRENT_DIR)/src/opencv_upy.cmake"
7+
# TODO: For some reason, specifying this in the toolchain file doesn't work
8+
CMAKE_ARGS += -DBUILD_LIST=core,imgproc,imgcodecs
99

10-
# Build MicroPython with the OpenCV module
10+
# Generic build
1111
all:
12-
@cd micropython/ports/rp2 && export CMAKE_ARGS="$(CMAKE_ARGS)" && make -f Makefile $(MAKEFLAGS) $(MAKE_ARGS)
12+
cd opencv && mkdir -p build && cmake -S . -B build -DPICO_BUILD_DOCS=0 -DCMAKE_TOOLCHAIN_FILE=../${TOOLCHAIN_FILE} ${CMAKE_ARGS} && make -C build -f Makefile $(MAKEFLAGS) $(MAKE_ARGS)
1313

14-
# Clean the MicroPython build
14+
# Clean the OpenCV build
1515
clean:
16-
@cd micropython/ports/rp2 && make -f Makefile $(MAKEFLAGS) clean
17-
18-
# Load the MicroPython submodules
19-
submodules:
20-
@cd micropython/ports/rp2 && make -f Makefile $(MAKEFLAGS) submodules
16+
cd opencv && rm -rf build

README.md

Lines changed: 292 additions & 1 deletion
Large diffs are not rendered by default.

micropython

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/opencv_upy.cmake renamed to micropython_opencv.cmake

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
1+
#-------------------------------------------------------------------------------
2+
# SPDX-License-Identifier: MIT
3+
#
4+
# Copyright (c) 2025 SparkFun Electronics
5+
#-------------------------------------------------------------------------------
6+
# opencv_upy.cmake
7+
#
8+
# CMake file for the MicroPython port of OpenCV.
9+
#-------------------------------------------------------------------------------
10+
111
# Create an INTERFACE library for our CPP module.
212
add_library(usermod_cv2 INTERFACE)
313

414
# Add our source files to the library.
515
target_sources(usermod_cv2 INTERFACE
6-
${CMAKE_CURRENT_LIST_DIR}/alloc.c
7-
${CMAKE_CURRENT_LIST_DIR}/convert.cpp
8-
${CMAKE_CURRENT_LIST_DIR}/core.cpp
9-
${CMAKE_CURRENT_LIST_DIR}/imgproc.cpp
10-
${CMAKE_CURRENT_LIST_DIR}/numpy.cpp
11-
${CMAKE_CURRENT_LIST_DIR}/opencv_upy.c
16+
${CMAKE_CURRENT_LIST_DIR}/src/alloc.c
17+
${CMAKE_CURRENT_LIST_DIR}/src/convert.cpp
18+
${CMAKE_CURRENT_LIST_DIR}/src/core.cpp
19+
${CMAKE_CURRENT_LIST_DIR}/src/highgui.cpp
20+
${CMAKE_CURRENT_LIST_DIR}/src/imgcodecs.cpp
21+
${CMAKE_CURRENT_LIST_DIR}/src/imgproc.cpp
22+
${CMAKE_CURRENT_LIST_DIR}/src/numpy.cpp
23+
${CMAKE_CURRENT_LIST_DIR}/src/opencv_upy.c
1224
)
1325

1426
# Add the src directory as an include directory.
@@ -21,16 +33,16 @@ target_link_libraries(usermod INTERFACE usermod_cv2)
2133

2234
# OpenCV creates some global variables on the heap. These get created before
2335
# the GC is initialized, so we need to allocate some space for them on the C
24-
# heap. 10kB seems sufficient. TODO: See if we can get away with less.
25-
set(MICROPY_C_HEAP_SIZE 10240)
36+
# heap. 64kB seems sufficient.
37+
set(MICROPY_C_HEAP_SIZE 65536)
2638

2739
# Makes m_tracked_calloc() and m_tracked_free() available. These track pointers
2840
# in a linked list to ensure the GC does not free them. Needed for some OpenCV
2941
# functions
3042
set(MICROPY_TRACKED_ALLOC 1)
3143

32-
# Set ULAB max number of dimensions to 4 (default is 2). TODO: See if 4 is
33-
# actually needed, or if we can get away with 2.
44+
# Set ULAB max number of dimensions to 4 (default is 2), which is needed for
45+
# some OpenCV functions
3446
target_compile_definitions(usermod INTERFACE ULAB_MAX_DIMS=4)
3547

3648
# Include ULAB
@@ -48,3 +60,8 @@ target_link_libraries(usermod INTERFACE "-Wl,--wrap,malloc")
4860
target_link_libraries(usermod INTERFACE "-Wl,--wrap,free")
4961
target_link_libraries(usermod INTERFACE "-Wl,--wrap,calloc")
5062
target_link_libraries(usermod INTERFACE "-Wl,--wrap,realloc")
63+
64+
# __NEWLIB__ is not defined for some reason, which causes a conflicting
65+
# definition of uint here:
66+
# https://github.com/opencv/opencv/blob/9cdd525bc59b34a3db8f6db905216c5398ca93d6/modules/core/include/opencv2/core/hal/interface.h#L35-L39
67+
target_compile_definitions(usermod INTERFACE -D__NEWLIB__)

opencv

Submodule opencv added at 31b0eee

platforms/common.cmake

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Derived from:
2+
# https://github.com/joachimBurket/esp32-opencv/blob/master/esp32/doc/detailed_build_procedure.md
3+
set(CMAKE_BUILD_TYPE Release)
4+
set(BUILD_SHARED_LIBS OFF)
5+
set(CV_DISABLE_OPTIMIZATION OFF)
6+
set(WITH_IPP OFF)
7+
set(WITH_TBB OFF)
8+
set(WITH_OPENMP OFF)
9+
set(WITH_PTHREADS_PF OFF)
10+
set(WITH_QUIRC OFF)
11+
set(WITH_1394 OFF)
12+
set(WITH_CUDA OFF)
13+
set(WITH_OPENCL OFF)
14+
set(WITH_OPENCLAMDFFT OFF)
15+
set(WITH_OPENCLAMDBLAS OFF)
16+
set(WITH_VA_INTEL OFF)
17+
set(WITH_EIGEN OFF)
18+
set(WITH_GSTREAMER OFF)
19+
set(WITH_GTK OFF)
20+
set(WITH_JASPER OFF)
21+
set(WITH_JPEG OFF)
22+
set(WITH_OPENJPEG OFF)
23+
set(WITH_WEBP OFF)
24+
set(BUILD_ZLIB ON)
25+
set(BUILD_PNG ON)
26+
set(WITH_TIFF OFF)
27+
set(WITH_V4L OFF)
28+
set(WITH_LAPACK OFF)
29+
set(WITH_ITT OFF)
30+
set(WITH_PROTOBUF OFF)
31+
set(WITH_IMGCODEC_HDR OFF)
32+
set(WITH_IMGCODEC_SUNRASTER OFF)
33+
set(WITH_IMGCODEC_PXM OFF)
34+
set(WITH_IMGCODEC_PFM OFF)
35+
# TODO: For some reason, specifying this in the toolchain file doesn't work
36+
# set(BUILD_LIST core,imgproc,imgcodecs)
37+
set(BUILD_JAVA OFF)
38+
set(BUILD_opencv_python OFF)
39+
set(BUILD_opencv_java OFF)
40+
set(BUILD_opencv_apps OFF)
41+
set(BUILD_PACKAGE OFF)
42+
set(BUILD_PERF_TESTS OFF)
43+
set(BUILD_TESTS OFF)
44+
set(CV_ENABLE_INTRINSICS OFF)
45+
set(CV_TRACE OFF)
46+
set(OPENCV_ENABLE_MEMALIGN OFF)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef RP2350_UNSAFE_CV_XADD_H
2+
#define RP2350_UNSAFE_CV_XADD_H
3+
4+
// Fix for https://github.com/raspberrypi/pico-sdk/issues/2505
5+
// TLDR; OpenCV uses atomic operations for incrementing reference counters by
6+
// default. However, the Pico SDK does not support atomic operations on data in
7+
// PSRAM; attempting to do so just causes an infinite loop where the value is
8+
// incremented forever. The workaround is to use a non-atomic operation by
9+
// re-defining the `CV_XADD` macro. This is "unsafe" because it's not atomic,
10+
// but it *should* be fine since we're only using one thread. Also see:
11+
// https://github.com/opencv/opencv/blob/52bed3cd7890192700b2451e2713c340209ffd79/modules/core/include/opencv2/core/cvdef.h#L697-L723
12+
static inline int unsafe_cv_xadd(int* addr, int delta)
13+
{
14+
int tmp = *addr;
15+
*addr += delta;
16+
return tmp;
17+
}
18+
#define CV_XADD(addr, delta) unsafe_cv_xadd(addr, delta)
19+
20+
#endif

platforms/include/zephyr_stdint.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2019 BayLibre SAS
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_STDINT_H_
8+
#define ZEPHYR_INCLUDE_TOOLCHAIN_STDINT_H_
9+
10+
/*
11+
* Some gcc versions and/or configurations as found in the Zephyr SDK
12+
* (questionably) define __INT32_TYPE__ and derivatives as a long int
13+
* which makes the printf format checker to complain about long vs int
14+
* mismatch when %u is given a uint32_t argument, and uint32_t pointers not
15+
* being compatible with int pointers. Let's redefine them to follow
16+
* common expectations and usage.
17+
*/
18+
19+
#if __SIZEOF_INT__ != 4
20+
#error "unexpected int width"
21+
#endif
22+
23+
#undef __INT32_TYPE__
24+
#undef __UINT32_TYPE__
25+
#undef __INT_FAST32_TYPE__
26+
#undef __UINT_FAST32_TYPE__
27+
#undef __INT_LEAST32_TYPE__
28+
#undef __UINT_LEAST32_TYPE__
29+
#undef __INT64_TYPE__
30+
#undef __UINT64_TYPE__
31+
#undef __INT_FAST64_TYPE__
32+
#undef __UINT_FAST64_TYPE__
33+
#undef __INT_LEAST64_TYPE__
34+
#undef __UINT_LEAST64_TYPE__
35+
36+
#define __INT32_TYPE__ int
37+
#define __UINT32_TYPE__ unsigned int
38+
#define __INT_FAST32_TYPE__ __INT32_TYPE__
39+
#define __UINT_FAST32_TYPE__ __UINT32_TYPE__
40+
#define __INT_LEAST32_TYPE__ __INT32_TYPE__
41+
#define __UINT_LEAST32_TYPE__ __UINT32_TYPE__
42+
#define __INT64_TYPE__ long long int
43+
#define __UINT64_TYPE__ unsigned long long int
44+
#define __INT_FAST64_TYPE__ __INT64_TYPE__
45+
#define __UINT_FAST64_TYPE__ __UINT64_TYPE__
46+
#define __INT_LEAST64_TYPE__ __INT64_TYPE__
47+
#define __UINT_LEAST64_TYPE__ __UINT64_TYPE__
48+
49+
/*
50+
* The confusion also exists with __INTPTR_TYPE__ which is either an int
51+
* (even when __INT32_TYPE__ is a long int) or a long int. Let's redefine
52+
* it to a long int to get some uniformity. Doing so also makes it compatible
53+
* with LP64 (64-bit) targets where a long is always 64-bit wide.
54+
*/
55+
56+
#if __SIZEOF_POINTER__ != __SIZEOF_LONG__
57+
#error "unexpected size difference between pointers and long ints"
58+
#endif
59+
60+
#undef __INTPTR_TYPE__
61+
#undef __UINTPTR_TYPE__
62+
#define __INTPTR_TYPE__ long int
63+
#define __UINTPTR_TYPE__ long unsigned int
64+
65+
/*
66+
* Re-define the INTN_C(value) integer constant expression macros to match the
67+
* integer types re-defined above.
68+
*/
69+
70+
#undef __INT32_C
71+
#undef __UINT32_C
72+
#undef __INT64_C
73+
#undef __UINT64_C
74+
#define __INT32_C(c) c
75+
#define __UINT32_C(c) c ## U
76+
#define __INT64_C(c) c ## LL
77+
#define __UINT64_C(c) c ## ULL
78+
79+
#endif /* ZEPHYR_INCLUDE_TOOLCHAIN_STDINT_H_ */

0 commit comments

Comments
 (0)