aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/porting.rst68
1 files changed, 68 insertions, 0 deletions
diff --git a/docs/porting.rst b/docs/porting.rst
new file mode 100644
index 000000000..f46160b7d
--- /dev/null
+++ b/docs/porting.rst
@@ -0,0 +1,68 @@
+We love CircuitPython and would love to see it come to more microcontroller
+platforms. With 3.0 we've reworked CircuitPython to make it easier than ever to
+add support. While there are some major differences between ports, this page
+covers the similarities that make CircuitPython what it is and how that core
+fits into a variety of microcontrollers.
+
+Architecture
+============
+
+There are three core pieces to CircuitPython:
+
+The first is the Python VM that the awesome MicroPython devs have created.
+These VMs are written to be portable so there is not much needed when moving to
+a different microcontroller, especially if it is ARM based.
+
+The second is the infrastructure around those VMs which provides super basic
+operating system functionality such as initializing hardware, running USB,
+prepping file systems and automatically running user code on boot. In
+CircuitPython we've dubbed this component the supervisor because it monitors
+and facilitates the VMs which run user Python code. Porting involves the
+supervisor because many of the tasks it does while interfacing with the
+hardware. Once its going though, the REPL works and debugging can migrate to a
+Python based approach rather than C.
+
+The third core piece is the plethora of low level APIs that CircuitPython
+provides as the foundation for higher level libraries including device drivers.
+These APIs are called from within the running VMs through the Python interfaces
+defined in ``shared-bindings``. These bindings rely on the underlying
+``common_hal`` C API to implement the functionality needed for the Python API.
+By splitting the two, we work to ensure standard functionality across which
+means that libraries and examples apply across ports with minimal changes.
+
+Porting
+=======
+
+Step 1: Getting building
+------------------------
+The first step to porting to a new microcontroller is getting a build running.
+The primary goal of it should be to get ``main.c`` compiling with the assistance
+of the ``supervisor/supervisor.mk`` file. Port specific code should be isolated
+to the port's directory (in the top level until the ``ports`` directory is
+present). This includes the Makefile and any C library resources. Make sure
+these resources are compatible with the MIT License of the rest of the code!
+
+Step 2: Init
+--------------
+Once your build is setup, the next step should be to get your clocks going as
+you expect from the supervisor. The supervisor calls `port_init` to allow for
+initialization at the beginning of main. This function also has the ability to
+request a safe mode state which prevents the supervisor from running user code
+while still allowing access to the REPL and other resources.
+
+The core port initialization and reset methods are defined in
+``supervisor/port.c`` and should be the first to be implemented. Its required
+that they be implemented in the ``supervisor`` directory within the port
+directory. That way, they are always in the expected place.
+
+The supervisor also uses three linker variables, ``_ezero``, ``_estack`` and
+``_ebss`` to determine memory layout for stack overflow checking.
+
+Step 3: REPL
+------------
+Getting the REPL going is a huge step. It involves a bunch of initialization to
+be done correctly and is a good sign you are well on your porting way. To get
+the REPL going you must implement the functions and definitions from
+``supervisor/serial.h`` with a corresponding ``supervisor/serial.c`` in the port
+directory. This involves sending and receiving characters over some sort of
+serial connection. It could be UART or USB for example.