Wie kompiliert man MicroPython vom Quellcode selbst?

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Ich habe aus der Makefile mal 'network.c', 'help.c' entfernt, das brachte noch nichts. Der Byte-Wert in der Fehlermeldung ist auch gleich groß.
Ich versuche mal noch mehr zu löschen, an sich brauche ich nicht wirklich viel.


Das Linkerscript sieht so aus:

Code: Alles auswählen

/* GNU linker script for ESP8266 with 1M flash

   Flash layout:
    0x40200000 36k  header + iram/dram init
    0x40209000 572k firmware (irom0)
    0x40298000 396k filesystem
    0x402fb000 20k  SDK parameters
*/

MEMORY
{
    dport0_0_seg : org = 0x3ff00000, len = 16
    dram0_0_seg :  org = 0x3ffe8000, len = 80K
    iram1_0_seg :  org = 0x40100000, len = 32K
    irom0_0_seg :  org = 0x40209000, len = 572K
}

/* define common sections and symbols */
INCLUDE boards/esp8266_common.ld
Da traue ich mich nicht einfach so was zu ändern. Kann ich da "einfach" der firmeware mehr Speicher zuweisen und dafür dem filesystem entsprechend weniger? Die Angabe vor der Größe ist die Adresse, wo im Speicher der Speicherort ist?

Edit: Naja das was in deinem Link mit 'irom0...' vorgeschlagen wird kann ich ja mal versuchen.

Ich verwende die aktuellste Version von MicroPython. Auf GitHub steht branche auf master.
Helfen dir die Infos dazu weiter:

Code: Alles auswählen

[dennis@dennis micropython]$ git checkout
M	ports/esp8266/Makefile
Ihr Branch ist auf demselben Stand wie 'origin/master'.
[dennis@dennis micropython]$ git show
commit 0b26efe73dd3396bdc2b77651a78d9f2edeb9004 (HEAD -> master, origin/master, origin/HEAD)
Author: robert-hh <robert@hammelrath.com>
Date:   Sun Aug 28 18:14:53 2022 +0200

    extmod/machine_i2c: Call MICROPY_PY_EVENT_HOOK during i2c.scan().
    
    Avoiding a watchdog reset during i2c.scan() if the hardware is not properly
    set up (eg on esp8266), and also allowing to stop the scan with a
    KeyboardInterrupt.
    
    Fixes issue #8876.

diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c
index 2aa217914..ff597b58c 100644
--- a/extmod/machine_i2c.c
+++ b/extmod/machine_i2c.c
@@ -328,6 +328,9 @@ STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) {
         if (ret == 0) {
             mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr));
         }
+        #ifdef MICROPY_EVENT_POLL_HOOK
+        MICROPY_EVENT_POLL_HOOK
+        #endif
     }
     return list;
 }
Das habe ich heute mit

Code: Alles auswählen

git clone https://github.com/micropython/micropython/tree/master
heruntergeladen.

Danke und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Muss ich denn noch etwas machen, nachdem ich die Linker-Datei geändert habe?

Ich soll ja :

Code: Alles auswählen

irom0_0_seg :  org = 0x40209000, len = 0xa7000
eintragen
Bei mir steht aber

Code: Alles auswählen

irom0_0_seg :  org = 0x40209000, len = 572K
Dann würde ich die 572 in 684 ändern wenn ich das richtig verstanden habe, dann sind wir im gleichen Format.
Das bringt mir aber relativ schnell einen Fehler:

Code: Alles auswählen

[dennis@dennis esp8266]$ sudo docker run --rm -v $HOME:$HOME -u $UID -w $PWD larsks/esp-open-sdk make -j BOARD=GENERIC_1M
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
GEN build-GENERIC_1M/genhdr/root_pointers.collected
Root pointer registrations not updated
CC machine_rtc.c
CC modnetwork.c
LINK build-GENERIC_1M/firmware.elf
xtensa-lx106-elf-ld: build-GENERIC_1M/firmware.elf section `.text' will not fit in region `iram1_0_seg'
xtensa-lx106-elf-ld: region `iram1_0_seg' overflowed by 1304 bytes
make: *** [Makefile:222: build-GENERIC_1M/firmware.elf] Error 1
Wie kann ich den pointer updaten? Ich habe vor dem make-Befehl noch ein 'make clean' ausgeführt, sonst nichts.

Danke und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da steht iram, du änderst aber irom.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Dieser User hat irom vorgeschlagen, deswegen habe ich das versucht.

Der Thread-Ersteller konnte sein Problem mit 'iram' nicht lösen, deswegen habe ich das gar nicht versucht.

Ich bin immer noch am experimentieren, welche Module ich aus der Makefile nehmen darf, oft kommt leider ein Fehler dass Abhängigkeiten nicht gefunden werden. Ich weis jetzt nicht richtig in welche Richtung ich mich konzentrieren soll.

Grüße und Danke
Dennis

Edit: Ich habe gerade 'iram' verdoppelt und bei mir trat das gleiche auf, wie bei dem TE im MicroPython-Forum. MP wurde gebaut und geflasht, aber beim booten rasen unkontrolliert Zeilen in dem Ausgabefenster und ich habe keinen Zugriff auf den ESP.

Code: Alles auswählen

Fatal exception 0(IllegalInstructionCause):
�pc1=0x401084b4, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 34072, room 16 
tail 8
chksum 0xb6
load 0x3ffe8000, len 996, room 0 
tail 4
chksum 0x81
load 0x3ffe83f0, len 1080, room 4 
tail 4
chksum 0xc4
csum 0xc4
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Ich habs! :)

Die Lösung (oder workaround) habe ich hier gefunden:
https://github.com/devbis/st7789_mpy#ov ... ram1_0_seg

Was ich da jetzt gemacht habe, weis ich leider nicht und würde mich über eine Erklärung freuen.

Jetzt schaue ich mal, wie ich damit klar komme. Zumindest 'import st7789' lief ohne Fehlermeldung.

Vielen Dank für die Unterstützung.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Ich weis das ist nicht mein erstes Display, aber jeder hat Pins mit anderen Abkürzungen und ich bekomme die Dinger einfach nie auf Anhieb zum laufen.

Ich habe das jetzt so angeschlossen:
VCC = 5V
GND = GND
DIN = D7 (GPIO13)
CLK = D5 /GPIO14)
CS = D8 (GPIO15)
DC = D1 (GPIO5)
RST = D2 (GPIO4)
BL = D6 (GPIO12)

Das Display und Pinout des ESP8266

Ist das so richtig?

Weil der folgende Code macht mit dem Display gar nichts und ich hätte erwartet, dass das Display rot wird:

Code: Alles auswählen

from time import sleep
import machine
import st7789
spi = machine.SPI(1, baudrate=40000000, polarity=0, phase=0)
display = st7789.ST7789(spi, 135, 240, reset=machine.Pin(5, machine.Pin.OUT), dc=machine.Pin(4, machine.Pin.OUT))
display.init()
sleep(0.2)
display.on()
sleep(0.2)
display.fill(st7789.RED)
while True:
    sleep(1)
Beispiel von st7789 und die Doku zu SPI

Ich vermute jetzt eher einen Fehler im Anschluss, kann mir dazu bitte jemand was sagen? Was ist eigentlich der "BL"-Pin?

Vielen Dank und schönen Samstagabend noch,
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mindestens mal RST und DC vertauscht.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Morgen/Mittag,

leider habe ich das nur beim erstellen des Beitrags vertauscht. DC ist auf D2 (GPIO 4) angeschlossen und RST ist auf D1 (GPIO 5) angeschlossen.


Danke und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Abend,

es funktioniert jetzt :)

Die ST7789-Klasse kann den CS-Pins auch als Argument entgegen nehmen:

Code: Alles auswählen

spi = SPI(1, baudrate=30000000, polarity=0, phase=0)
display = st7789.ST7789(
    spi, 135, 240,
    reset=Pin(4, Pin.OUT),
    cs= Pin(15,  Pin.OUT),
    dc=Pin(5, Pin.OUT)
    )

Meine Frage von gestern, was der BL-Pins sein soll hat sich auch erledigt, BL = Backlight.

Viele Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dennis89 hat geschrieben: Samstag 3. September 2022, 17:57 Die Lösung (oder workaround) habe ich hier gefunden:
https://github.com/devbis/st7789_mpy#ov ... ram1_0_seg

Was ich da jetzt gemacht habe, weis ich leider nicht und würde mich über eine Erklärung freuen.
Ein Linker-Skript (ld) legt fest, wohin Code und Variablen im Speicher platziert werden. Der loader im ESP platziert die dann an die entsprechenden Stellen. Und es gibt eben RAM und ROM, der aus IRQs erreichbar ist (IRAM, IROM). https://docs.espressif.com/projects/esp ... types.html

Warum jetzt nicht aller Code immer nach IROM geht, sondern auch mancher nach IRAM, kann ich auch nicht beantworten. Da muesste man tiefer einsteigen. Aber augenscheinlich ist das erstmal der default, und nur, wenn man es explizit anders einfordert (was dein Patch macht), dann platziert der den Modulcode in IROM.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Vielen Dank für die Erklärung.

Nun hat die Bibliothek keine Methode um direkt Text auf das Display zu schreiben. Eine andere die darauf aufbaut hat das zwar, aber die ist für den ESP32 und ist für den 8266 wohl einfach zu groß. Da ist noch ziemlich viel Zeugs dabei.

Ich werde mal schauen ob ich den 'write_text'-Teil aus der *.c-Datei erkennen kann und ob sich das zufällig einfach in meine *.c-Datei einfügen lässt.
Ich benötige nur Zahlen von 0-9 und ein Prozenzeichen wäre noch schön. Die Alternative zu dem umschreiben der *.c-Datei wäre, das ich jede Zahl durch setzen von einzelnen Pixels manuell erstelle.

Beginnen werde ich mal mit dem Vergleich der *.c - Dateien. Falls das aber aus mir unbekannten Gründen gar nicht geht, bin ich über den Hinweis natürlich dankbar. Ansonsten melde ich mich mit Neuigkeiten zurück.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Abend,

wahrscheinlich könnt ihr es euch schon denken, aber bei dem Versuch die *.c - Datei zu ändern war ich gar nicht erfolgreich. (Was will man auch erwarten wenn man die Sprache nicht lesen kann) Ich habe zwar die Funktion 'text', die ich will, gefunden, aber ich konnte nur von einer Fehlermeldung zur nächsten springen, in dem ich versuchte die richtigen Zeilen zusätzlich in die Datei zu kopieren. Das habe ich dann abgebrochen, denn das macht keinen Sinn.

Gibt es denn ein bekanntes vorgehen, wie ich die Zahlen von 0-9 darstellen kann? Ich stelle es mir nicht sonderlich elegant vor x und y Werte zu setzen bis ich eine "5" habe. Wie würdet ihr da vorgehen ? (Mal abgesehen davon, das ihr den C-Code ändern könntet)

Wenn das aber alles in einem großen Mist enden wird, dann nehme ich einen ESP32, auch wenn der für einen Encoder, einen Schalter und ein Display etwas zu "groß" ist.

Vielen Dank und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na mit Blit Buffer kannst du doch einfach kleine Bitmaps mit den Zahlen in das Display kopieren.

Und dann hat micropython doch das framebuffer interface. Damit sollte das doch sogar mit Text und diversen anderen primitiven gehen. https://docs.micropython.org/en/latest/ ... uffer.text

Wobei da der Speicher ggf ein Problem darstellt. Aber ein kleiner Ausschnitt + blit sind dann die Antwort.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Vielen Dank für die Antwort.

Melde mich erst jetzt, damit es nicht immer Doppelposts von mir gibt.

Ich habe eine Zeit lang etwas mit 'blit_buffer' experimentiert.
In der Beschreibung steht ja:

Code: Alles auswählen


ST7789.blit_buffer(buffer, x, y, width, height)

Copy bytes() or bytearray() content to the screen internal memory. Note: every color requires 2 bytes in the array
'buffer' müsste ja das sein, da ich angezeigt bekommen will. Auf jeden Fall nimmt er eine 1 als String an. x und y sind die Startkoordinaten, an denen angefangen wird, den buffer auf das Display zu schreiben. width und height kann ich nur schätzen, also vielleicht die Pixel des Displays? Dann steht da auch noch was von der Farbe, dafür habe ich gar keine Argumente mehr übrig.

Auf jeden Fall tut sich auf dem Display mit

Code: Alles auswählen

display.blit_buffer('1', 0, 0, 240, 135)
gar nichts. Ich habe die Hintergrundfarbe mal auf schwarz und mal auf weis gesetzt, da ist nichts zu sehen.

Dann kam mir der Gedanke, das ich mit FrameBuffer ein buffer-Objekt erstellen muss. Also habe ich das Beispiel aus der Doku genommen und wollte dass dann 'bit_buffer' übergeben. Aber das Beispiel, ergibt kein buffer-Objekt:

Code: Alles auswählen

fbuf = framebuf.FrameBuffer(bytearray(100 * 10 * 2), 100, 10, framebuf.RGB565)


print(type(fbuf.text('MicroPython!', 0, 0, 0xffff)))
Ergibt '<class 'NoneType'>'.

Puuh wo setz ich denn hier schon wieder falsch an?

Achja es gibt ja noch die Helper Funktion aber dazu fallen mir momentan nicht mal Fragen ein. Die Displays kosten mich Abend für Abend, ich hoffe ich verstehe das jetzt irgendwann mal.

Danke für die Geduld!

Viele Grüße
Dennis

P.S. wir hatten ja vor längerer Zeit schon mal ein ähnliches Problem, da haben wir 'uarray' genutzt. Aber da hatte ich eine Bibliothek die Texte auf ein Display schreiben konnte, da ging es nur um das buffern, damit eine reibungslose Anzeige möglich war. Ich glaube dass ist hier nicht die Lösung.
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der Buffer enthält die Pixel. Ein Pixel sind 2 Byte, wegen RGB565. Die Höhe und Breite geben die Gestalt dessen, was der Buffer repräsentiert, an. Die Display Dimension ist da doch sinnlos, das ist eine Methode des Displays. Das kennt seine Dimension selbst. Breite und Höhe definieren dann natürlich auch die Menge der Pixel im Buffer. Also zb 20 bei einem 4*5 Pixel großen Buffer. 2 Byte pro Pixel, also 40 Bytes. Und die Position ist irgendwo innerhalb der möglichen Koordinaten des Displays. Wenn’s gut gemacht ist, dann auch außerhalb, damit man zb ein sprite aus dem Bild wandern lassen kann.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Vielen Dank.

Das heißt, dass 'blit_buffer' ähnliche Argumente wie 'FrameBuffer' hat. Zumindest ist in der Doku von 'FrameBuffer' eine ähnliche Erklärung zu den Argumenten, wie deine Erklärung.

Also ich "kann" jetzt die Abmessungen, die Position und die Pixelanzahl des Buffers definieren. Doch ich muss irgendwie noch sagen, welche von den Pixel eine andere Farbe erhalten sollen, damit es mir zum Beispiel eine Zahl auf das Display schreibt. Bei 'FrameBuffer' geht das mit 'text', aber mein Display hat so eine Methode nicht und das FrameBuffer-Objekt kann ich nicht an 'blit_buffer' übergeben, das vom Typ None ist.


Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das verstehe ich nicht. Diese Blit Methoden kopiert den vollen Buffer ein. Der muss eine Zahl als Grafik enthalten. Du kannst einen solchen Buffer mit framebuffer erzeugen.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Morgen,

das hatte ich versucht bzw. das Beispiel von FrameBuffer macht nach meinem Verständnis nach genau einen sollchen Buffer, nur halt mit dem Inhalt "MicroPython!". Dabei ist bei mir aber folgendes Problem aufgetreten:
Dennis89 hat geschrieben: Dienstag 6. September 2022, 21:12 Dann kam mir der Gedanke, das ich mit FrameBuffer ein buffer-Objekt erstellen muss. Also habe ich das Beispiel aus der Doku genommen und wollte dass dann 'bit_buffer' übergeben. Aber das Beispiel, ergibt kein buffer-Objekt:

Code: Alles auswählen

fbuf = framebuf.FrameBuffer(bytearray(100 * 10 * 2), 100, 10, framebuf.RGB565)

print(type(fbuf.text('MicroPython!', 0, 0, 0xffff)))
Ergibt '<class 'NoneType'>'.
In der Doku steht zu 'text' folgendes:
"Write text to the FrameBuffer using the the coordinates as the upper-left corner of the text. "

Heißt dass, das ich nicht 'fbuf.text('MicroPython!', 0, 0, 0xffff)' an 'blit_buffer' übergeben muss, sondern im Falle des MicroPython-Beispiels, das ich 'fbuf', nach dem ich 'text' aufgerufen habe, übergeben muss?

Ich kann das mit Glück vielleicht kurz in der Mittagspause testen, ansonsten erst heute Abend, deswegen muss ich die Gedankengänge hier mal festhalten.
Ein Daumen hoch oder runter darf natürlich gern vergeben werden oder sonstige Kommentare.

Vielen Dank und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Woher kommt denn die Erwartung, das text etwas zurueckgibt? Das nimmt den bestehenden fbuf, und modifiziert den, in place. So wie append eine Liste veraendert, und auch None zurueckgibt. Und dann musst du fbuf uebergeben in deinem blit.

Du probierst hier auch schon wieder zwei Dinge, die du beide nicht wirklich durchdrungen hast, gleichzeitig zu machen. Versteh erstmal blit. Im Notfall kannst du sogar nur damit arbeiten (wenn du einfach vordefinierte byte-arrays mit Zahlen benutzt). Und *dann* schau dir an, wie framebuf funktioniert, und uebergib den an blit.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Vielen Dank.
Die erste Frage kann ich nicht begründet beantworten. Jetzt ist das schon mal etwas klarer.

In der Mittagspause habe ich 'blit_buffer' ein 'bytearray' -> bytearray(100 * 100 * 2) übergeben und habe auf dem Display ein schwarzes Quadraht erhalten. Juhu! Für mehr hat die Pause nicht gereicht.

Nun setze ich mich heute Abend intensiver mit 'bytearray' auseinander und kümmere ich mich um die Schlagwörter "vordefinierte byte-arrays mit Zahlen".

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Antworten