Ich frage mich gerade wie man bei einem ESP32 ohne jetzt das IDF Framework nutzen zu wollen, sondern in C auf Low Level Basis Interrupts zum laufen zu bekommen. Im Datenblatt steht einiges zu der RISC-V Architektur und auch etwas zu den Interrupts. Es gibt eine Tabelle "Tram Vector" dort gibt es 31 "Vektoren" für die jeweiligen Interrupts die vorher konfiguriert wurden. Jetzt meine Frage.. Wie bekomme ich meine Funktion die ausgeführt werden soll dorthin "gemoppt"? Kann ich meiner Funktion die ausgeführt werden soll bei dem Interrupt die Adresse des Vektors zuweisen? Oder wie ist hier die Vorgehensweise?
:
Bearbeitet durch User
UPS. Habe es aktualisiert. Es geht speziell um den C3. Danke für den Hinweis.
Ueblicherweise gehoert zu einem C-Compiler eine Runtime, In der findet sich dann eine "startup.s" in der die Interruptvektoren "weak" auf vordefinierte Interruptroutinen zeigen. Will man selbst einen Interrupt bedienen, schreibt man eine gleichnamige Funktion, die eben nicht "weak" definiert ist, und so beim linken im Programm landet. Das wird beim RISC-V auch nicht wesentlich anders ein...
:
Bearbeitet durch User
Motopick schrieb: > Ueblicherweise gehoert zu einem C-Compiler eine Runtime, In der > findet sich dann eine "startup.s" in der die Interruptvektoren > "weak" auf vorderinierte Interruptroutingen zeigen. > Will man selbst einen Interrupt bedienen, schreibt man eine > gleichnamige Funktion, die eben nicht "weak" definiert ist, > und so beim linken im Programm landet. > Das wird beim RISC-V auch nicht wesentlich anders ein... Okay. Und die im Bild zu sehenden Adressen sind dann quasi die wo die Funktionen stehen bzw. die Adressen dafür?
Jan H. schrieb: > Und die im Bild zu sehenden Adressen sind dann quasi die wo die > Funktionen stehen bzw. die Adressen dafür? Im Bild ist die Interruptvektortabelle zu sehen. Unter "Address" sind die Adressen aufgeführt, wo die Startadresse der aufzurufenden Interruptfunktion einzutragen ist.
Rainer W. schrieb: > Jan H. schrieb: >> Und die im Bild zu sehenden Adressen sind dann quasi die wo die >> Funktionen stehen bzw. die Adressen dafür? > > Im Bild ist die Interruptvektortabelle zu sehen. Unter "Address" sind > die Adressen aufgeführt, wo die Startadresse der aufzurufenden > Interruptfunktion einzutragen ist. Das heißt unter diesen Adressen kann ich jeweils die Adresse meiner aufzurufenden Funktion schreiben?
Jan H. schrieb: > Das heißt unter diesen Adressen kann ich jeweils die Adresse meiner > aufzurufenden Funktion schreiben? Ja, normalerweise sollte es im Compiler eine Möglichkeit geben, der diese Eintragung der Startadresse der ISR in der Tabelle veranlasst.
Rainer W. schrieb: > Jan H. schrieb: >> Das heißt unter diesen Adressen kann ich jeweils die Adresse meiner >> aufzurufenden Funktion schreiben? > > Ja, normalerweise sollte es im Compiler eine Möglichkeit geben, der > diese Eintragung der Startadresse der ISR in der Tabelle veranlasst. Mir geht es auch darum zu lernen und zu verstehen wie das ganze funktioniert. Ist es dann auch möglich während mein Programm läuft die Adressen in den Interrupt Vektoren zu verändern?
Jan H. schrieb: > Ist es dann auch möglich während mein Programm läuft die Adressen in den > Interrupt Vektoren zu verändern? Ei sischa. Edith: Wenn man sie geschickterweise im RAM haelt.
:
Bearbeitet durch User
Das heißt das ganze könnte dann ungefähr so aussehen? Eine Funktion nimmt quasie die "Callback" Funktion entgegen, deren Adresse dann im besagten Interrupt Vektor gespeichert wird:
1 | uint8_t int_map_interrupt( int_cpu_slot_t _slot, void (*_callback)() ){ |
2 | if( _slot > __INT_CPU_SLOT_MAX__ ) return 1; // slot unknown |
3 | |
4 | int_trap_vector[ _slot ] = _callback; |
5 | |
6 | return 0; |
7 | }
|
Das sind die ganzen 31 Vektoren:
1 | #define MTVEC_REG 0x305
|
2 | #define MTVEC_REG_OFFSET 0x04
|
3 | #define MTVEC_CALC_SLOT(n) ( MTVEC_REG + ( n * MTVEC_REG_OFFSET ) )
|
4 | |
5 | volatile uint32_t* int_trap_vector[] = { |
6 | MTVEC_CALC_SLOT(1), |
7 | MTVEC_CALC_SLOT(2), |
8 | MTVEC_CALC_SLOT(3), |
9 | MTVEC_CALC_SLOT(4), |
10 | MTVEC_CALC_SLOT(5), |
11 | MTVEC_CALC_SLOT(6), |
12 | MTVEC_CALC_SLOT(7), |
13 | MTVEC_CALC_SLOT(8), |
14 | MTVEC_CALC_SLOT(9), |
15 | MTVEC_CALC_SLOT(10), |
16 | MTVEC_CALC_SLOT(11), |
17 | MTVEC_CALC_SLOT(12), |
18 | MTVEC_CALC_SLOT(13), |
19 | MTVEC_CALC_SLOT(14), |
20 | MTVEC_CALC_SLOT(15), |
21 | MTVEC_CALC_SLOT(16), |
22 | MTVEC_CALC_SLOT(17), |
23 | MTVEC_CALC_SLOT(18), |
24 | MTVEC_CALC_SLOT(19), |
25 | MTVEC_CALC_SLOT(20), |
26 | MTVEC_CALC_SLOT(21), |
27 | MTVEC_CALC_SLOT(22), |
28 | MTVEC_CALC_SLOT(23), |
29 | MTVEC_CALC_SLOT(24), |
30 | MTVEC_CALC_SLOT(25), |
31 | MTVEC_CALC_SLOT(26), |
32 | MTVEC_CALC_SLOT(27), |
33 | MTVEC_CALC_SLOT(28), |
34 | MTVEC_CALC_SLOT(29), |
35 | MTVEC_CALC_SLOT(30), |
36 | MTVEC_CALC_SLOT(31), |
37 | };
|
:
Bearbeitet durch User
Wenn es der Compiler uebersetzt, heisst das noch nicht, dass es funktioniert. Du solltest dir fuer den Anfang erstmal ein kleineres Broetchen backen. Z.B. einen Timerinterrupt. Und dann mit offenem Auge erkunden, was der Compiler zu welchem Zweck wohin positioniert hat, und was es tut. Per Default, sind die weak definierten, bereits vorhandenen Interruptroutinen, schon mit einigermassen sinnvollen Aktionen belegt. P.S.: Viele CPUs/Controller schuetzen auch solche Bereiche, und muessen kwasi erst "entsperrt" werden, wenn man darau herumturnen will.
:
Bearbeitet durch User
ESP32 sind eigentlich nicht für diese bare-metal Programmierung vorgesehen. Viele Funktionen kann man mangels Doku gar nicht nutzen. Meinst du nicht, daß ein normaler Mikrocontroller besser geeignet ist? Zum Lernen würde ich mit einem überschaubaren STM32L0 anfangen und später auf einen stärkeres Modell wechseln, falls nötig. Test-Boards findet man unter dem Namen "STM32 Nucleo".
:
Bearbeitet durch User
Sherlock 🕵🏽♂️ schrieb: > ESP32 sind eigentlich nicht für diese bare-metal Programmierung > vorgesehen. Viele Funktionen kann man mangels Doku gar nicht nutzen. > > Meinst du nicht, daß ein normaler Mikrocontroller besser geeignet ist? > Zum Lernen würde ich mit einem überschaubaren STM32L0 anfangen und > später auf einen stärkeres Modell wechseln, falls nötig. Test-Boards > findet man unter dem Namen "STM32 Nucleo". Ja Da gebe ich Dir zu 100% recht. Diese Mikrocontroller sind wirklich nicht leicht zu bedienen (bare metal) aber es macht mir spaß zu forschen und rum zu probieren bis es funktioniert. Angefangen habe ich mit den kleinen 8 bitlern von ATMEL. Da man die ESP32 sau günstig bekommt, habe ich mich einfach mal da dran getraut. Vieles läuft auch schon, einiges noch nicht so ganz perfekt. Dafür gibt es ja aber Foren wo man Hilfe bekommen kann ;)
:
Bearbeitet durch User
Motopick schrieb: > Wenn es der Compiler uebersetzt, heisst das noch nicht, dass es > funktioniert. Du solltest dir fuer den Anfang erstmal ein kleineres > Broetchen backen. > > Z.B. einen Timerinterrupt. > Und dann mit offenem Auge erkunden, was der Compiler zu welchem > Zweck wohin positioniert hat, und was es tut. > > Per Default, sind die weak definierten, bereits vorhandenen > Interruptroutinen, schon mit einigermassen sinnvollen Aktionen > belegt. > > P.S.: > Viele CPUs/Controller schuetzen auch solche Bereiche, und muessen > kwasi erst "entsperrt" werden, wenn man darau herumturnen will. Ich habe mal den ganzen Projekt Ordner auf eine "*.s" durchsuchen lassen, leider findet er nur eine "x509_crt_bundle.S" dort stehen aber keine ASM Befehle.
Jan H. schrieb: > Ich habe mal den ganzen Projekt Ordner auf eine "*.s" durchsuchen > lassen, leider findet er nur eine "x509_crt_bundle.S" dort stehen aber > keine ASM Befehle. Ich habe jetzt doch die passende Datei gefunden. Habe sie mal mit hochgeladen.
Jan H. schrieb: > Ich frage mich gerade wie man bei einem ESP32 ohne jetzt das IDF > Framework nutzen zu wollen, sondern in C auf Low Level Basis Interrupts > zum laufen zu bekommen. ... > Jetzt meine Frage.. Wie bekomme ich meine Funktion die ausgeführt werden > soll dorthin "gemoppt"? Schau nach wie es das IDF macht. Mach dir eine Kanne oder zwei deines bevorzugten Heißgetränkes, stell das Telefon auf Flugmodus und die Hausklingel ab, und dann schau in den IDF-Quelltext. Mögliche, zufällig rausgesuchte Einstiegspunkte: https://github.com/espressif/esp-idf/blob/master/components/esp_hw_support/intr_alloc.c https://github.com/espressif/esp-idf/blob/master/components/hal/include/hal/interrupt_clic_ll.h https://github.com/espressif/esp-idf/blob/master/components/hal/include/hal/interrupt_int_ll.h https://github.com/espressif/esp-idf/blob/master/components/hal/include/hal/interrupt_plic_ll.h https://github.com/espressif/esp-idf/blob/master/components/hal/esp32c3/include/hal/crosscore_int_ll.h https://github.com/espressif/esp-idf/blob/master/components/soc/esp32c3/interrupts.c https://github.com/espressif/esp-idf/blob/master/components/soc/esp32c3/register/soc/interrupt_core0_reg. https://github.com/espressif/esp-idf/blob/master/components/soc/esp32c3/include/soc/interrupts.h Das sieht auf den ersten Blick nicht sehr Spaßig aus. Ich würde die Verwendung einer IDE vorschlagen die gut darin ist Querverweise aufzulösen.
Jan H. schrieb: > Ich habe mal den ganzen Projekt Ordner auf eine "*.s" durchsuchen > lassen, leider findet er nur eine "x509_crt_bundle.S" dort stehen aber > keine ASM Befehle. "Dein" Projektordner ist da auch die flasche Stelle zum Suchen. Die fuer Interrupts darunterliegende Infrastruktur, stellt der Compiler und "seine" Runtime bereit. Da musst du suchen. :) Etwa dort, wo der Compiler seine Libraries aufbewahrt, duerfte sich auch der Startup-Code, und dessen Bestandteile finden lassen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.