MicroPython’u Taşıma¶
MicroPython projesi, farklı mikrodenetleyici ailelerine ve mimarilerine yönelik çeşitli taşımalar içerir. Proje deposunda, desteklenen her taşıma için bir alt dizin içeren bir ports dizini bulunur.
Bir taşıma genellikle birden çok “kartın” tanımlarını içerir; bunların her biri, o taşımanın üzerinde çalışabileceği belirli bir donanım parçasıdır, örneğin bir geliştirme kiti veya cihaz.
minimal port, bir MicroPython taşımasının basitleştirilmiş bir referans uygulaması olarak mevcuttur. Hem ana sistemde hem de bir STM32F4xx MCU üzerinde çalışabilir.
Genel olarak, bir taşımaya başlamak için şunlar gerekir:
Araç zincirinin kurulması (Makefile dosyalarının yapılandırılması vb.).
Önyükleme yapılandırmasının ve CPU başlatmasının uygulanması.
Geliştirme ve hata ayıklama için gereken temel sürücülerin başlatılması (örn. GPIO, UART).
Karta özgü yapılandırmaların gerçekleştirilmesi.
Taşımaya özgü modüllerin uygulanması.
Asgari MicroPython aygıt yazılımı¶
MicroPython’u yeni bir karta taşımaya başlamanın en iyi yolu, asgari bir MicroPython yorumlayıcısını entegre etmektir. Bu anlatım için, ports dizininde yeni taşıma için bir alt dizin oluşturun:
$ cd ports
$ mkdir example_port
Temel MicroPython aygıt yazılımı ana taşıma dosyasında uygulanır, örn. main.c:
#include "py/builtin.h"
#include "py/compile.h"
#include "py/gc.h"
#include "py/mperrno.h"
#include "shared/runtime/gchelper.h"
#include "shared/runtime/pyexec.h"
// Allocate memory for the MicroPython GC heap.
static char heap[4096];
int main(int argc, char **argv) {
// Initialise the MicroPython runtime.
mp_cstack_init_with_sp_here(2048);
gc_init(heap, heap + sizeof(heap));
mp_init();
// Start a normal REPL; will exit when ctrl-D is entered on a blank line.
pyexec_friendly_repl();
// Deinitialise the runtime.
gc_sweep_all();
mp_deinit();
return 0;
}
// Handle uncaught exceptions (should never be reached in a correct C implementation).
void nlr_jump_fail(void *val) {
for (;;) {
}
}
// Do a garbage collection cycle.
void gc_collect(void) {
gc_collect_start();
gc_helper_collect_regs_and_stack();
gc_collect_end();
}
// There is no filesystem so stat'ing returns nothing.
mp_import_stat_t mp_import_stat(const char *path) {
return MP_IMPORT_STAT_NO_EXIST;
}
// There is no filesystem so opening a file raises an exception.
mp_lexer_t *mp_lexer_new_from_file(qstr filename) {
mp_raise_OSError(MP_ENOENT);
}
Bu noktada taşıma için bir Makefile dosyasına da ihtiyacımız var:
# Include the core environment definitions; this will set $(TOP).
include ../../py/mkenv.mk
# Include py core make definitions.
include $(TOP)/py/py.mk
include $(TOP)/extmod/extmod.mk
# Set CFLAGS and libraries.
CFLAGS += -I. -I$(BUILD) -I$(TOP)
LIBS += -lm
# Define the required source files.
SRC_C = \
main.c \
mphalport.c \
shared/readline/readline.c \
shared/runtime/gchelper_generic.c \
shared/runtime/pyexec.c \
shared/runtime/stdout_helpers.c \
# Define source files containing qstrs.
SRC_QSTR += shared/readline/readline.c shared/runtime/pyexec.c
# Define the required object files.
OBJ = $(PY_CORE_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
# Define the top-level target, the main firmware.
all: $(BUILD)/firmware.elf
# Define how to build the firmware.
$(BUILD)/firmware.elf: $(OBJ)
$(ECHO) "LINK $@"
$(Q)$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
$(Q)$(SIZE) $@
# Include remaining core make rules.
include $(TOP)/py/mkrules.mk
Makefile dosyasını girintilemek için uygun sekmeler (tab) kullanmayı unutmayın.
MicroPython Yapılandırmaları¶
Yukarıdaki asgari kodu entegre ettikten sonra, sonraki adım taşıma için MicroPython yapılandırma dosyalarını oluşturmaktır. Derleme zamanı yapılandırmaları mpconfigport.h dosyasında, zaman tutma gibi ek donanım soyutlama işlevleri ise mphalport.h dosyasında belirtilir.
Aşağıda bir mpconfigport.h dosyası örneği verilmiştir:
#include <stdint.h>
// Python internal features.
#define MICROPY_ENABLE_GC (1)
#define MICROPY_HELPER_REPL (1)
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
// Fine control over Python builtins, classes, modules, etc.
#define MICROPY_PY_ASYNC_AWAIT (0)
#define MICROPY_PY_BUILTINS_SET (0)
#define MICROPY_PY_ATTRTUPLE (0)
#define MICROPY_PY_COLLECTIONS (0)
#define MICROPY_PY_MATH (0)
#define MICROPY_PY_IO (0)
#define MICROPY_PY_STRUCT (0)
// Type definitions for the specific machine.
typedef long mp_off_t;
// We need to provide a declaration/definition of alloca().
#include <alloca.h>
// Define the port's name and hardware.
#define MICROPY_HW_BOARD_NAME "example-board"
#define MICROPY_HW_MCU_NAME "unknown-cpu"
#define MP_STATE_PORT MP_STATE_VM
Bu yapılandırma dosyası, farklı MicroPython özelliklerinin etkinleştirilip etkinleştirilmeyeceği gibi yönleri içeren makineye özgü yapılandırmaları içerir, örn. #define MICROPY_ENABLE_GC (1). Bunu (0) olarak ayarlamak özelliği devre dışı bırakır.
Diğer yapılandırmalar arasında tür tanımları, kök işaretçiler, kart adı, mikrodenetleyici adı vb. bulunur.
Benzer şekilde, asgari bir mphalport.h dosyası örneği şöyle görünür:
static inline void mp_hal_set_interrupt_char(char c) {}
Standart giriş/çıkış desteği¶
MicroPython, en azından karakterleri çıkarmak için bir yola ihtiyaç duyar ve bir REPL’e sahip olmak için karakterleri girmek için de bir yola ihtiyaç duyar. Bunun için işlevler mphalport.c dosyasında uygulanabilir, örneğin:
#include <unistd.h>
#include "py/mpconfig.h"
// Receive single character, blocking until one is available.
int mp_hal_stdin_rx_chr(void) {
unsigned char c = 0;
int r = read(STDIN_FILENO, &c, 1);
(void)r;
return c;
}
// Send the string of given length.
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
int r = write(STDOUT_FILENO, str, len);
(void)r;
}
Bu giriş ve çıkış işlevlerinin, belirli kart API’sine bağlı olarak değiştirilmesi gerekir. Bu örnek standart giriş/çıkış akışını kullanır.
Oluşturma ve çalıştırma¶
Bu aşamada yeni taşımanın dizini şunları içermelidir:
ports/example_port/
├── main.c
├── Makefile
├── mpconfigport.h
├── mphalport.c
└── mphalport.h
Taşıma artık make çalıştırılarak (veya başka bir şekilde, sisteminize bağlı olarak) oluşturulabilir.
Yukarıda verilen Makefile dosyasındaki varsayılan derleyici ayarlarını kullanıyorsanız, bu, doğrudan yürütülebilen build/firmware.elf adlı bir yürütülebilir dosya oluşturur. İşlevsel bir REPL elde etmek için önce terminali ham (raw) moda yapılandırmanız gerekebilir:
$ stty raw opost -echo
$ ./build/firmware.elf
Bu size bir MicroPython REPL vermelidir. Ardından şu gibi komutları çalıştırabilirsiniz:
MicroPython v1.26.0-preview on 2025-08-01; minimal with unknown-cpu
>>> def sum(n, m):
... return n + m
...
>>> 3, 4, sum(3, 4)
(3, 4, 7)
>>>
Çıkmak için Ctrl-D kullanın ve ardından terminali sıfırlamak için reset çalıştırın.
Taşımaya bir modül ekleme¶
myport gibi özel bir modül eklemek için, önce modül tanımını bir modmyport.c dosyasına ekleyin:
#include "py/runtime.h"
static mp_obj_t myport_info(void) {
mp_printf(&mp_plat_print, "info about my port\n");
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_0(myport_info_obj, myport_info);
static const mp_rom_map_elem_t myport_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_myport) },
{ MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&myport_info_obj) },
};
static MP_DEFINE_CONST_DICT(myport_module_globals, myport_module_globals_table);
const mp_obj_module_t myport_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&myport_module_globals,
};
MP_REGISTER_MODULE(MP_QSTR_myport, myport_module);
Ayrıca modmyport.c dosyasını SRC_C listesine eklemek ve aynı dosyayı SRC_QSTR listesine ekleyen yeni bir satır (böylece qstr’ler bu yeni dosyada aranır) eklemek için Makefile dosyasını düzenlemeniz gerekir, şöyle:
SRC_C = \
main.c \
modmyport.c \
mphalport.c \
...
SRC_QSTR += modmyport.c
Her şey doğru gittiyse, yeniden oluşturmadan sonra yeni modülü içe aktarabilmeniz gerekir:
>>> import myport
>>> myport.info()
info about my port
>>>