Skip to content

Can't build on x64 for use with RP2040 #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
esologic opened this issue Nov 9, 2024 · 11 comments
Closed

Can't build on x64 for use with RP2040 #19

esologic opened this issue Nov 9, 2024 · 11 comments
Labels
bug Something isn't working

Comments

@esologic
Copy link

esologic commented Nov 9, 2024

Hi! The issue linked in the README blocking use on RP2040 looks to be resolved as a few weeks ago, but the deployment artifact is from last summer. I'm super interested on trying this project out on an RP2040, so I tried building it myself but ran into problems:

(.venv) devon@ESO-3-DEV-VM:~/Documents/bray_airways/noreaster/lib_source/emlearn-micropython$ make dist ARCH=armv6m MPY_DIR=/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython
make -C src/emlearn_trees/ ARCH=armv6m MPY_DIR=/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython  V=1 clean dist
make[1]: Entering directory '/home/devon/Documents/bray_airways/noreaster/lib_source/emlearn-micropython/src/emlearn_trees'
/usr/lib/gcc/arm-none-eabi/6.3.1/thumb/v6-m/libgcc.a
/bin/rm -rf build _arm_cmpsf2.o lesf2.o _arm_fixsfsi.o fixsfsi.o eqsf2.o gesf2.o _arm_addsubsf3.o _arm_muldivsf3.o addsf3.o _clzsi2.o _udivsi3.o floatsisf.o divsf3.o _thumb1_case_uqi.o
/bin/mkdir -p build/
arm-none-eabi-ar -x /usr/lib/gcc/arm-none-eabi/6.3.1/thumb/v6-m/libgcc.a _arm_cmpsf2.o lesf2.o _arm_fixsfsi.o fixsfsi.o eqsf2.o gesf2.o _arm_addsubsf3.o _arm_muldivsf3.o addsf3.o _clzsi2.o _udivsi3.o floatsisf.o divsf3.o _thumb1_case_uqi.o
GEN build/emlearn_trees.config.h
python3 /home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py '-vvv' --arch armv6m --preprocess -o build/emlearn_trees.config.h trees.c trees.py
CC trees.c
arm-none-eabi-gcc -I. -I/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython -std=c99 -Os -Wall -Werror -DNDEBUG -DNO_QSTR -DMICROPY_ENABLE_DYNRUNTIME -DMP_CONFIGFILE='<build/emlearn_trees.config.h>' -fpic -fno-common -U _FORTIFY_SOURCE  -mthumb -mcpu=cortex-m0 -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_NONE  -I/home/devon/Documents/bray_airways/noreaster/.venv/lib/python3.10/site-packages/emlearn -o build/trees.o -c trees.c
LINK _arm_cmpsf2.o
python3 /home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py '-vvv' --arch armv6m --qstrs build/emlearn_trees.config.h -o build/emlearn_trees.native.mpy _arm_cmpsf2.o lesf2.o _arm_fixsfsi.o fixsfsi.o eqsf2.o gesf2.o _arm_addsubsf3.o _arm_muldivsf3.o addsf3.o _clzsi2.o _udivsi3.o floatsisf.o divsf3.o _thumb1_case_uqi.o build/trees.o
qstr vals: __del__, addleaf, addnode, addroot, emltrees, new, predict, setdata
sections:
  00000008 .text size=116
  0000007c .text size=132
  00000100 .text size=64
  00000140 .text size=76
  0000018c .text size=128
  0000020c .text size=16
  0000021c .text size=804
  00000540 .text size=60
  0000057c .text size=276
  00000690 .text size=160
  00000730 .text size=656
  000009c0 .rodata size=128
  00000a40 .text size=20
  00000a54 .text size=1488
  00000000 .bss size=112
  00001024 .data.rel.ro size=80
  00001074 .data.rel.ro.local size=40
  0000109c .rodata.str1.1 size=236
  00001188 GOT size=20
GOT: 00001188
  00000000 mp_fun_table -> .external+00000000
  00000004 mp_native_qstr_table -> .external.qstr_table+00000000
  00000008 eml_error_strs -> .data.rel.ro.local+00001084
  0000000c trees_builder_type -> .bss+00000030
  00000010 trees_locals_dict_table -> .bss+00000000
_arm_cmpsf2.o: .text relocations via .rel.text:
  00000012 __lesf2 -> 0000007d
  00000022 __eqsf2 -> 00000141
  0000002e __lesf2 -> 0000007d
  00000042 __lesf2 -> 0000007d
  00000056 __gesf2 -> 0000018d
  0000006a __gesf2 -> 0000018d
_arm_addsubsf3.o: .text relocations via .rel.text:
  00000214 __aeabi_fadd -> 0000021d
addsf3.o: .text relocations via .rel.text:
  0000026c __clzsi2 -> 00000541
_udivsi3.o: .text relocations via .rel.text:
  00000680 __aeabi_idiv0 -> 00000f45
floatsisf.o: .text relocations via .rel.text:
  000006a0 __clzsi2 -> 00000541
divsf3.o: .text relocations via .rel.text:
  00000814 __clzsi2 -> 00000541
  0000082c __clzsi2 -> 00000541
Traceback (most recent call last):
  File "/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py", line 1093, in <module>
    main()
  File "/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py", line 1089, in main
    do_link(args)
  File "/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py", line 1060, in do_link
    link_objects(env, len(native_qstr_vals))
  File "/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py", line 850, in link_objects
    do_relocation_text(env, sec.addr, r)
  File "/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py", line 595, in do_relocation_text
    assert 0, r_info_type
AssertionError: 2
/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/py/dynruntime.mk:149: recipe for target 'build/emlearn_trees.native.mpy' failed
make[1]: *** [build/emlearn_trees.native.mpy] Error 1
make[1]: Leaving directory '/home/devon/Documents/bray_airways/noreaster/lib_source/emlearn-micropython/src/emlearn_trees'
Makefile:14: recipe for target 'dist/armv6m_6.3/emlearn_trees.mpy' failed
make: *** [dist/armv6m_6.3/emlearn_trees.mpy] Error 2

The micropython version is the lastest, so that being out of date isn't the problem (I don't think)...

I modified mpy_ld.py to log some more info. In that function do_relocation_text:

env.arch.name = EM_ARM 
r_info_type = 2

The ELF constant for 2 is R_386_PC32. Is the issue that I'm trying to build the armv6m version on an x86 box?

Best,
Devon

@jonnor jonnor added the bug Something isn't working label Nov 10, 2024
@jonnor
Copy link
Contributor

jonnor commented Nov 11, 2024

Hi @esologic and thank you for the report.
There are built versions for armv6m (RP2040 and other ARM Cortex M0+), for MicroPython 1.23 available at https://github.com/emlearn/emlearn-micropython/tree/gh-pages/builds/master/armv6m_6.3 - the latest modules are those with emlearn_ in the name.

The exception you get is likely it is what is tracked in micropython/micropython#14430
I currently use a fork of MicroPython with the fix provided there as a patch. See jonnor/micropython@2cecbb5
So that is needed to build emlearn-micropython for ARM, at the moment. I will try to get that upstream.

@jonnor
Copy link
Contributor

jonnor commented Nov 12, 2024

Btw, branch for updating to MicroPython 1.24 is here: #21

@esologic
Copy link
Author

Thanks so much -- I'll be giving this a shot maybe Friday/Sat of this week and I'll follow up.

@jonnor
Copy link
Contributor

jonnor commented Nov 16, 2024

I tried running the examples and tests with MicroPython 1.24 on RP2040 now, using the prebuilt .mpy files for armv6m on master.
At the moment they are hanging when calling the emlearn-micropython C modules. It happens both for har_trees (using emlearn_trees) and soundlevel_iir (using emlearn_arrayutils and emlearn_iir). This problem does not appear on ESP32, so there seems to be an architecture specific problem.

However, I am unable to debug this right now, due to some other deadlines.

@esologic
Copy link
Author

Took another stab at building tonight. To summarize

  • I checked out emlearn-micropython to the commit referenced above, 350191838f38dfa9992648f3c2a9f68fed7e4174.
  • I updated my micropython version to the v1.24.0 tag, f212bbe837489f297c9d25d608bdb7b8c3da988d.
  • I updated my ARM build toolchain from 6.3.1 -> 13.3.1 . It actually turns out the version in ARM's PPA is very outdated, and one needs to download and symlink the prebuilt executables to get access them.

No dice, I get a very similar error to the original:

(.venv) devon@ESO-3-DEV-VM:~/Documents/bray_airways/noreaster/lib_source/emlearn-micropython$ make dist ARCH=armv6m MPY_DIR=/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython V=2
make -C src/emlearn_trees/ ARCH=armv6m MPY_DIR=/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython  V=1 clean dist
make[1]: Entering directory '/home/devon/Documents/bray_airways/noreaster/lib_source/emlearn-micropython/src/emlearn_trees'
/opt/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp/libgcc.a
/bin/rm -rf build _arm_cmpsf2.o lesf2.o _arm_fixsfsi.o fixsfsi.o eqsf2.o gesf2.o _arm_addsubsf3.o _arm_muldivsf3.o addsf3.o _clzsi2.o _udivsi3.o floatsisf.o divsf3.o _thumb1_case_uqi.o
/bin/mkdir -p build/
arm-none-eabi-ar -x /opt/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp/libgcc.a _arm_cmpsf2.o lesf2.o _arm_fixsfsi.o fixsfsi.o eqsf2.o gesf2.o _arm_addsubsf3.o _arm_muldivsf3.o addsf3.o _clzsi2.o _udivsi3.o floatsisf.o divsf3.o _thumb1_case_uqi.o
GEN build/emlearn_trees.config.h
python3 /home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py '-vvv' --arch armv6m --preprocess -o build/emlearn_trees.config.h trees.c trees.py
CC trees.c
arm-none-eabi-gcc -I. -I/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython -std=c99 -Os -Wall -Werror -DNDEBUG -DNO_QSTR -DMICROPY_ENABLE_DYNRUNTIME -DMP_CONFIGFILE='<build/emlearn_trees.config.h>' -fpic -fno-common -U _FORTIFY_SOURCE  -mthumb -mcpu=cortex-m0 -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_NONE  -I/home/devon/Documents/bray_airways/noreaster/.venv/lib/python3.10/site-packages/emlearn -o build/trees.o -c trees.c
LINK _arm_cmpsf2.o
python3 /home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py '-vvv' --arch armv6m --qstrs build/emlearn_trees.config.h -o build/emlearn_trees.native.mpy _arm_cmpsf2.o lesf2.o _arm_fixsfsi.o fixsfsi.o eqsf2.o gesf2.o _arm_addsubsf3.o _arm_muldivsf3.o addsf3.o _clzsi2.o _udivsi3.o floatsisf.o divsf3.o _thumb1_case_uqi.o build/trees.o
qstr vals: __del__, addleaf, addnode, addroot, emltrees, new, predict, setdata
sections:
  00000008 .text size=116
  0000007c .text.__lesf2 size=144
  0000010c .text.__aeabi_f2iz size=64
  0000014c .text.__eqsf2 size=80
  0000019c .text.__gesf2 size=148
  00000230 .text size=16
  00000240 .text.__aeabi_fadd size=832
  00000580 .text size=60
  000005bc .text size=276
  000006d0 .text.__aeabi_i2f size=148
  00000764 .text.__aeabi_fdiv size=548
  00000988 .rodata.__aeabi_fdiv size=124
  00000a04 .text size=20
  00000a18 .text size=1428
  00000000 .bss size=112
  00000fac .rodata.str1.1 size=236
  00001098 .data.rel.ro size=80
  000010e8 .data.rel.ro.local size=40
  00001110 GOT size=20
GOT: 00001110
  00000000 mp_fun_table -> .external+00000000
  00000004 mp_native_qstr_table -> .external.qstr_table+00000000
  00000008 eml_error_strs -> .data.rel.ro.local+000010f8
  0000000c trees_builder_type -> .bss+00000030
  00000010 trees_locals_dict_table -> .bss+00000000
_arm_cmpsf2.o: .text relocations via .rel.text:
  00000012 __lesf2 -> 0000007d
  00000022 __eqsf2 -> 0000014d
  0000002e __lesf2 -> 0000007d
  00000042 __lesf2 -> 0000007d
  00000056 __gesf2 -> 0000019d
  0000006a __gesf2 -> 0000019d
_arm_addsubsf3.o: .text relocations via .rel.text:
  00000238 __aeabi_fadd -> 00000241
addsf3.o: .text.__aeabi_fadd relocations via .rel.text.__aeabi_fadd:
  000002fe __clzsi2 -> 00000581
_udivsi3.o: .text relocations via .rel.text:
  000006c0 __aeabi_idiv0 -> 00000ed1
floatsisf.o: .text.__aeabi_i2f relocations via .rel.text.__aeabi_i2f:
  000006e0 __clzsi2 -> 00000581
divsf3.o: .text.__aeabi_fdiv relocations via .rel.text.__aeabi_fdiv:
  0000084a __clzsi2 -> 00000581
  0000086c __clzsi2 -> 00000581
Traceback (most recent call last):
  File "/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py", line 1093, in <module>
    main()
  File "/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py", line 1089, in main
    do_link(args)
  File "/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py", line 1060, in do_link
    link_objects(env, len(native_qstr_vals))
  File "/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py", line 850, in link_objects
    do_relocation_text(env, sec.addr, r)
  File "/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/tools/mpy_ld.py", line 595, in do_relocation_text
    assert 0, r_info_type
AssertionError: 2
/home/devon/Documents/bray_airways/noreaster/micropython_firmware/micropython/py/dynruntime.mk:149: recipe for target 'build/emlearn_trees.native.mpy' failed
make[1]: *** [build/emlearn_trees.native.mpy] Error 1
make[1]: Leaving directory '/home/devon/Documents/bray_airways/noreaster/lib_source/emlearn-micropython/src/emlearn_trees'
Makefile:14: recipe for target 'dist/armv6m_6.3/emlearn_trees.mpy' failed
make: *** [dist/armv6m_6.3/emlearn_trees.mpy] Error 2

I also tried building on an ARM system to see if this yielded any other info, and the error is very similar there as well.

As for the prebuilt .mpy files not working -- if there's anything I can try on my end let me know.

@jonnor
Copy link
Contributor

jonnor commented Nov 17, 2024

The (proposed) fix for the ARM relocation is not in 1.24.0, so the patch still needs to be applied separately. The branch I use can be found here, https://github.com/jonnor/micropython/tree/emlearn-micropython-v1.24-1
Without this, it is expected to get the linker error you see. However, it is an open question whether this patch is actually correct... There are both comments in micropython/micropython#14430 indicating that it worked, but also one that it hangs the device.

So the hanging observed on RP2040 may (or may not) be related to this patch. One probably needs to dig out a debugger to see what goes wrong. And maybe try to compare with module code which does not create this type of relocation.

@esologic
Copy link
Author

Ahh I see, my bad for misreading.

I tried again using the branch you linked and I was able to build emlearn_trees.mpy which is great.

However I did run into the same hanging behavior when running through the xor example:

.venv) devon@studio-nuc:~/Documents/noreaster$ mpremote 
Connected to MicroPython at /dev/ttyACM0
Use Ctrl-] or Ctrl-x to exit this shell

>>> import os 
>>> os.listdir("./")
['assumptions_check.py', 'deploy.py', 'emlearn_trees.mpy', 'main.py', 'main_prod.py', 'main_test.py', 'noreaster', 'setup.py', 'tesla_cooler', 'xor_model.csv']
>>> import emlearn_trees
>>> import array
>>> model = emlearn_trees.new(5, 30, 2)
>>> # Load a CSV file with the model
>>> with open('xor_model.csv', 'r') as f:
...     emlearn_trees.load_model(model, f)
... 
>>> max_val = (2**15-1) # 1.0 as int16
>>> examples = [
...     array.array('h', [0, 0]),
...     array.array('h', [max_val, max_val]),
...     array.array('h', [0, max_val]),
...     array.array('h', [max_val, 0]),
... ]
>>> 
>>> for ex in examples: 
...     result = model.predict(ex)
...     print(ex, result)
... 

I tried building the firmware.uf2 for the RP2 port and flashing it from your branch as well to see if it changed the behavior. It also hangs at the same place, after the .predict call.

I'll watch: micropython/micropython#14430 for updates.

@esologic
Copy link
Author

Happy new year @jonnor -- I'm getting back into this related project, are there any experiments and tests I could try to answer questions you have related to this issue?

@jonnor
Copy link
Contributor

jonnor commented Feb 5, 2025

Hi @esologic - happy new year. There are no ready experiements at this point. What we need to create is some minimal reproducing module code and build, which we can provide on the MicroPython issue, so that the people there can help out in creating a proper patch.
I will try to do this in the coming weeks.

@jonnor
Copy link
Contributor

jonnor commented Mar 28, 2025

Seems that getting soft-float for native modules to work on Cortex M0+ etc is quite difficult, ref micropython/micropython#14430 (comment)

So it looks like RP2040 will not really work as native modules. Instead, we like need to support building into the firmware using the user C module instead #18

@jonnor
Copy link
Contributor

jonnor commented Apr 21, 2025

We now have basic support for external module build, and I have given this some very quick testing on RP2040.

For anyone wanting to test, there is a pre-built binary for RP2040 for the RPI Pico here
https://github.com/emlearn/emlearn-micropython/tree/gh-pages/builds/master/ports/rp2/RPI_PICO
The .uf2 can be dropped onto USB drive, and then one can import emlearn_trees and other modules, and run the examples (in git).

Initial documentation on how to build with external modules can be found at https://emlearn-micropython.readthedocs.io/en/latest/external_modules.html
This is a more complicated way of installing, but unfortunately there is no support for in MicroPython for relocations on arm6vm, so we are stuck with this for the time being.

@jonnor jonnor closed this as completed Apr 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants