micropython/examples/natmod
Angus Gratton decf8e6a8b all: Remove the "STATIC" macro and just use "static" instead.
The STATIC macro was introduced a very long time ago in commit
d5df6cd44a.  The original reason for this was
to have the option to define it to nothing so that all static functions
become global functions and therefore visible to certain debug tools, so
one could do function size comparison and other things.

This STATIC feature is rarely (if ever) used.  And with the use of LTO and
heavy inline optimisation, analysing the size of individual functions when
they are not static is not a good representation of the size of code when
fully optimised.

So the macro does not have much use and it's simpler to just remove it.
Then you know exactly what it's doing.  For example, newcomers don't have
to learn what the STATIC macro is and why it exists.  Reading the code is
also less "loud" with a lowercase static.

One other minor point in favour of removing it, is that it stops bugs with
`STATIC inline`, which should always be `static inline`.

Methodology for this commit was:

1) git ls-files | egrep '\.[ch]$' | \
   xargs sed -Ei "s/(^| )STATIC($| )/\1static\2/"

2) Do some manual cleanup in the diff by searching for the word STATIC in
   comments and changing those back.

3) "git-grep STATIC docs/", manually fixed those cases.

4) "rg -t python STATIC", manually fixed codegen lines that used STATIC.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-03-07 14:20:42 +11:00
..
btree all: Remove the "STATIC" macro and just use "static" instead. 2024-03-07 14:20:42 +11:00
deflate all: Remove the "STATIC" macro and just use "static" instead. 2024-03-07 14:20:42 +11:00
features0 all: Remove the "STATIC" macro and just use "static" instead. 2024-03-07 14:20:42 +11:00
features1 all: Remove the "STATIC" macro and just use "static" instead. 2024-03-07 14:20:42 +11:00
features2 all: Remove the "STATIC" macro and just use "static" instead. 2024-03-07 14:20:42 +11:00
features3 all: Remove the "STATIC" macro and just use "static" instead. 2024-03-07 14:20:42 +11:00
features4 all: Remove the "STATIC" macro and just use "static" instead. 2024-03-07 14:20:42 +11:00
framebuf all: Remove the "STATIC" macro and just use "static" instead. 2024-03-07 14:20:42 +11:00
heapq examples/natmod: Rename umodule to module. 2023-06-08 17:54:24 +10:00
random examples/natmod: Rename umodule to module. 2023-06-08 17:54:24 +10:00
re all: Remove the "STATIC" macro and just use "static" instead. 2024-03-07 14:20:42 +11:00
.gitignore
README.md examples/natmod: Add features4 as a class definition example. 2023-09-02 00:16:16 +10:00

README.md

Dynamic Native Modules

Dynamic Native Modules are .mpy files that contain native machine code from a language other than Python. For more info see [the documentation] (https://docs.micropython.org/en/latest/develop/natmod.html).

This should not be confused with [User C Modules] (https://docs.micropython.org/en/latest/develop/cmodules.html) which are a mechanism to add additional out-of-tree modules into the firmware build.

Examples

This directory contains several examples of writing dynamic native modules, in two main categories:

  1. Feature examples.

    • features0 - A module containing a single "factorial" function which demonstrates working with integers.

    • features1 - A module that demonstrates some common tasks:

      • defining simple functions exposed to Python
      • defining local, helper C functions
      • defining constant integers and strings exposed to Python
      • getting and creating integer objects
      • creating Python lists
      • raising exceptions
      • allocating memory
      • BSS and constant data (rodata)
      • relocated pointers in rodata
    • features2 - This is a hybrid module containing both Python and C code, and additionally the C code is spread over multiple files. It also demonstrates using floating point (only when the target supports hardware floating point).

    • features3 - A module that shows how to use types, constant objects, and creating dictionary instances.

    • features4 - A module that demonstrates how to define a class.

  2. Dynamic version of existing built-ins.

    This provides a way to add missing functionality to firmware that doesn't include certain built-in modules. See the heapq, random, re, deflate, btree, and framebuf directories.

    So for example, if your firmware was compiled with MICROPY_PY_FRAMEBUF disabled (e.g. to save flash space), then it would not include the framebuf module. The framebuf native module provides a way to add the framebuf module dynamically.

    The way these work is they define a dynamic native module which #include's the original module and then does the necessary initialisation of the module's globals dict.

Build instructions

To compile an example, you need to have the same toolchain available as required for your target port. e.g. arm-none-eabi-gcc for any ARM Cortex M target. See the port instructions for details.

You also need to have the pyelftools Python package available, either via your system package manager or installed from PyPI in a virtual environment with pip.

Each example provides a Makefile. You should specify the ARCH argument to make (one of x86, x64, armv6m, armv7m, xtensa, xtensawin):

$ cd features0
$ make ARCH=armv7m
$ mpremote cp features0.mpy :