Skip to content

Commit 0dcb8f7

Browse files
Initial commit
0 parents  commit 0dcb8f7

File tree

9 files changed

+159
-0
lines changed

9 files changed

+159
-0
lines changed

.github/workflows/build.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Build MicroPython + module
2+
3+
on:
4+
push:
5+
branches: '*'
6+
pull_request:
7+
branches: '*'
8+
9+
jobs:
10+
build:
11+
strategy:
12+
matrix:
13+
# macos-13 is x86_64, and macos-14 is arm64
14+
os: [ubuntu-22.04, macos-13, macos-14]
15+
fail-fast: false
16+
runs-on: ${{ matrix.os }}
17+
name: build.py ${{ matrix.os }}
18+
steps:
19+
- uses: actions/checkout@v4
20+
with:
21+
submodules: true
22+
- uses: actions/setup-python@v5
23+
with:
24+
python-version: '3.11'
25+
- uses: carlosperate/arm-none-eabi-gcc-action@v1
26+
with:
27+
release: 10.3-2021.10
28+
- name: Install CMake v3.22 via PyPI
29+
run: python -m pip install cmake==3.28.3
30+
- name: Check Versions
31+
run: |
32+
arm-none-eabi-gcc --version
33+
cmake --version
34+
python --version
35+
uname -a
36+
- name: Initialise micro:bit MicroPython submodules
37+
run: git -C micropython-microbit-v2 submodule update --init
38+
- name: Build mpy-cross
39+
run: make -C micropython-microbit-v2/lib/micropython/mpy-cross -j2
40+
- name: Build MicroPython with C++ module
41+
run: make -C micropython-microbit-v2/src USER_C_MODULES=../../.. -j2
42+
- name: Upload hex file
43+
uses: actions/upload-artifact@v4
44+
with:
45+
name: MICROBIT-MICROPYTHON-${{ github.sha }}-${{ matrix.os }}.hex
46+
path: micropython-microbit-v2/src/build/MICROBIT.hex

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "micropython-microbit-v2"]
2+
path = micropython-microbit-v2
3+
url = https://github.com/microbit-foundation/micropython-microbit-v2.git

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Micro:bit Educational Foundation
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# micropython-module-example
2+
A template to create a MicroPython for micro:bit V2 C/C++ module
3+
4+
5+
## Build instructions
6+
7+
Clone this repository, initialise the git submodules and build MicroPython's
8+
mpy-cross:
9+
```
10+
git submodule update --init
11+
git -C micropython-microbit-v2 submodule update --init
12+
make -C micropython-microbit-v2/lib/micropython/mpy-cross
13+
```
14+
15+
Build MicroPython with the C++ module included:
16+
17+
```
18+
make -C micropython-microbit-v2/src USER_C_MODULES=../../..
19+
```
20+
21+
Hex file: `micropython-microbit-v2/src/build/MICROBIT.hex`

micropython-microbit-v2

Submodule micropython-microbit-v2 added at 558553f

module/micropython.mk

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CPPEXAMPLE_MOD_DIR := $(USERMOD_DIR)
2+
3+
# Add our source files to the respective variables.
4+
SRC_USERMOD += $(CPPEXAMPLE_MOD_DIR)/src/examplemodule.c
5+
SRC_USERMOD_CXX += $(CPPEXAMPLE_MOD_DIR)/src/example.cpp
6+
7+
# Add our module directory to the include path.
8+
CFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR)/src
9+
CXXFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR)/src -std=c++11
10+
11+
12+
# We use C++ features so have to link against the standard library.
13+
LDFLAGS_USERMOD += -lstdc++

module/src/example.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
extern "C" {
2+
#include <examplemodule.h>
3+
#include <py/objstr.h>
4+
5+
// Here we implement the function using C++ code, but since it's
6+
// declaration has to be compatible with C everything goes in extern "C" scope.
7+
mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj) {
8+
// The following no-ops are just here to verify the static assertions used in
9+
// the public API all compile with C++.
10+
MP_STATIC_ASSERT_STR_ARRAY_COMPATIBLE;
11+
if (mp_obj_is_type(a_obj, &mp_type_BaseException)) {
12+
}
13+
14+
// Prove we have (at least) C++11 features.
15+
const auto a = mp_obj_get_int(a_obj);
16+
const auto b = mp_obj_get_int(b_obj);
17+
const auto sum = [&]() {
18+
return mp_obj_new_int(a + b);
19+
} ();
20+
// Prove we're being scanned for QSTRs.
21+
mp_obj_t tup[] = {sum, MP_ROM_QSTR(MP_QSTR_hellocpp)};
22+
return mp_obj_new_tuple(2, tup);
23+
}
24+
}

module/src/examplemodule.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <examplemodule.h>
2+
3+
// Define a Python reference to the function we'll make available.
4+
// See example.cpp for the definition.
5+
static MP_DEFINE_CONST_FUN_OBJ_2(cppfunc_obj, cppfunc);
6+
7+
// Define all attributes of the module.
8+
// Table entries are key/value pairs of the attribute name (a string)
9+
// and the MicroPython object reference.
10+
// All identifiers and strings are written as MP_QSTR_xxx and will be
11+
// optimized to word-sized integers by the build system (interned strings).
12+
static const mp_rom_map_elem_t cppexample_module_globals_table[] = {
13+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cppexample) },
14+
{ MP_ROM_QSTR(MP_QSTR_cppfunc), MP_ROM_PTR(&cppfunc_obj) },
15+
};
16+
static MP_DEFINE_CONST_DICT(cppexample_module_globals, cppexample_module_globals_table);
17+
18+
// Define module object.
19+
const mp_obj_module_t cppexample_user_cmodule = {
20+
.base = { &mp_type_module },
21+
.globals = (mp_obj_dict_t *)&cppexample_module_globals,
22+
};
23+
24+
// Register the module to make it available in Python.
25+
MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule);

module/src/examplemodule.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Include MicroPython API.
2+
#include "py/runtime.h"
3+
4+
// Declare the function we'll make available in Python as cppexample.cppfunc().
5+
extern mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj);

0 commit comments

Comments
 (0)