Trying to port Micropython to Mega 2560 clones
Mibi88
03/10/2025
I just quickly wrote this article, so it is quite messy, and my English is not so good, so… sorry for that.
I had finished all the exercises very quickly in NSI class, so the teacher asked us, who had finished early, if we could try getting micropython working on mega 2560 clones to help him. I searched on the internet, and found that there was no port, and that it had really low specs. Later, when at home I was curious if I could make a port of micropython to it, as I knew it was easy from contributing to PythonExtra and it might be fun. I quickly set up a fedora VM to install all the AVR tools in (I don’t want to pollute my PC which such a useless toolchain as I have no such boards myself). I cloned the master branch and copy-pasted all the sample code at https://docs.micropython.org/en/latest/develop/porting.html. It compiled and I was able to run the build/firmware.elf file in a terminal. Now I needed to get it to build for the microcontroller. I added
CROSS_COMPILE ?= avr-
to the makefile and started fixing errors. I had to change
typedef intptr_t mp_int_t; // must be pointer size
typedef uintptr_t mp_uint_t; // must be pointer size
to
typedef long long mp_int_t; // must be pointer size
typedef unsigned long long mp_uint_t; // must be pointer size
in mpconfigport.h, because of a MP_STATIC_ASSERT that checks if sizeof(mp_int_t) == sizeof(long long), I don’t understand why, this is incoherent with what the doc says by saying that mp_int_t “must be pointer size”, but whatever…
Next I had to fix some issues with the libc and libm, as they lack some functions for some reason. It was quickly solved with some hacks.
Here are the messy things I had to do in mpconfigport.h
// HACK: Awful hacks with the types
typedef long long mp_int_t; // must be pointer size
typedef unsigned long long mp_uint_t; // must be pointer size
typedef long mp_off_t;
typedef long ssize_t;
// HACK: Really awful hack to get things compiling
#include <math.h>
#undef nanf
float __nanf(const char *tagp);
#define nanf __nanf
float __nearbyintf(float n);
#define nearbyintf __nearbyintf
// HACK: More awful hacks to get things compiling!
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEK_END 2
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
// NOTE: Actually IIRC those FE_* defines are useless
#define FE_DOWNWARD 1
#define FE_TONEAREST 2
#define FE_TOWARDZERO 3
#define FE_UPWARD 4
And here are my messy implementations of __nanf and __nearbyintf that I’ve just thrown in mphalport.c
float __nanf(const char *tagp) {
return 0;
}
float __nearbyintf(float n) {
return roundf(n); // It seems like mpy only uses it for rounding
}
I then added the following define to mpconfigport.h
#define MICROPY_GCREGS_SETJMP (1)
By the way at some point I also found https://micropythpn.readthedocs.io/en/docs-chap1/develop/porting.html at some point which was very helpful, because it listed a lot of flags. If I’m not mistaken at this point all the C code was compiling, but not linking yet: the .text section was overflowing. I had commented CROSS_COMPILE ?= avr- in the Makefile and it compiled and worked on Linux, so at least my quick and dirty hacks worked.
So I enabled LTO with -flto=auto and added -mmcu=atmega2560 to use the correct linker script. The .text section was still too full.
I then had to stop coding, and continue the next day: today.
I had some time this morning, so I tried the fix I had in mind: just adding -Oz to the CFLAGS. And it worked! …but I was now facing another issue: .data and .bss were full. So I tried disabling more and more features, removing all the useless platform-dependant things micropython links by default for some reason, writing the OBJ list by hand, only including what’s needed, but I didn’t got any of it working.
So I just give up, I don’t want to spend more time on this.
I hope all what I’ve written down in this article may help someone in the future, who also tries to port it to this board. If you want the code of my port attempt, please contact me. I won’t publish it publicly as it is a mess and I’ve done a lot of copy-paste from various places.