https://techtutorialsx.com/2017/10/0...er-interrupts/
Portabfrage und Zählen in der ISR bekommst Du alleine hin?
natürlich nicht für jede Aufgabe - wer behauptet das?
Aber für jede Aufgabe braucht man auch keinen M7 oder M4 oder ESP32 und keine single- oder double fpu.
Pinstates habe ich aber selber schon mit Arduino Due und Raspi gelesen (100us bzw. 500ns-1us- Takt), da sehe ich keine Einschränkung - bei preemptivem MT und diesen großen cpus aber sehr wohl (und auf kleineren ntl erst recht).
FreeRTOS ist nur die Basis, auf der ESP32 das std:thread und pthread implementiert hat, analog zu std::thread und pthread auf Linux - Teensy hat da andere, aber entfernt ähnliche Libs wie RTOS.
Mich interessiert hierbei allerdings weder wie Linux funktioniert noch wie RTOS funktioniert, ich nutze nur die reinen C99/C++14 API Libs.
Geändert von HaWe (11.08.2019 um 19:22 Uhr)
https://techtutorialsx.com/2017/10/0...er-interrupts/
Portabfrage und Zählen in der ISR bekommst Du alleine hin?
Ja, dann trau Dich.
Du musst doch nur den Code kopieren und etwas abändern.
poste am besten den vollständigen fertigen Code, dann kann ich sehen was man daraus machen kann.
edit:
ich sehe in dem Link nur die if-Abfrage in einer main() loop, ohne weitere zusätzliche Funktionsaufrufe (Rechenfunktionen, GPIO r/w, ...).
Zusätzliche Funktionsaufrufe brauchen aber Rechenzeit, die dann nach if() auf diese weiteren Funktionen verteilt werden kann, bevor die if() Abfrage sich wiederholt.
Wieviel Gesamt-Rechenzeit haben denn die anderen Funktionen zur Verfügung, zwischen 2 if() in aufeinanderfolgenden main() loops?
Hier müsstest du ja dann auch fibonacci, GPIO r/w, sort, Blink und die alte 500ms-delay main loop bei dir mit rein kriegen.
Bei MT müsste dann deine Timerfunktion diese dazwischenliegende Zeit reservieren - ich muss also wissen, wieviel.
ggf 100us?
Das könnte ich probieren...
- - - Aktualisiert - - -
deine Abfrage in loop() würde ich dann ZUSÄTZLICH zu meinen 5 Threads so formulieren:
Ich habe allerdings überhaupt keine Idee, wasCode:volatile static int interruptCounter; volatile static int totalInterruptCounter; hw_timer_t * timer = NULL; portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; void IRAM_ATTR onTimer() { portENTER_CRITICAL_ISR(&timerMux); interruptCounter++; portEXIT_CRITICAL_ISR(&timerMux); } std::thread *thread_1; std::thread *thread_2; std::thread *thread_3; std::thread *thread_4; std::thread *thread_5; // meine threads und Hilfsfunktionen 1-4 wie bisher void timer_loop() { vTaskPrioritySet(NULL,4);//set Priority Serial.println((String)"\ntimer_loop Current priority :" + uxTaskPriorityGet(NULL)+"\n"); while(true) { if (interruptCounter > 0) { portENTER_CRITICAL(&timerMux); interruptCounter--; portEXIT_CRITICAL(&timerMux); totalInterruptCounter++; Serial.println( (String)"\nAn interrupt as occurred. Total number: " + totalInterruptCounter +"\n"); } std::this_thread::sleep_for(std::chrono::microseconds(100)); } } void setup() { Serial.begin(115200); delay(1000); timer = timerBegin(0, 80, true); timerAttachInterrupt(timer, &onTimer, true); timerAlarmWrite(timer, 1000000, true); timerAlarmEnable(timer); thread_1 = new std::thread(blinker_loop); thread_2 = new std::thread(fibonacci_loop); thread_3 = new std::thread(sort_loop); thread_4 = new std::thread(GPIO_loop); thread_5 = new std::thread(timer_loop); } void loop() { // meine void loop wie bisher }
void IRAM_ATTR onTimer() {},
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
machen und wie sie funktionieren, genausowenig, was die settings in setup dafür bedeuten - wie gesagt, IRQs habe ich bisher nie benutzt, kann sie also nur 1:1 übernehmen.
Und wie sähe aber dann DEIN Gesamt-Programm aus, in dem du alle Funktionen (meine 5 threads + deinen Timer) gemeinsam unterbringst? Würdest du das überhaupt schaffen?
Geändert von HaWe (11.08.2019 um 21:11 Uhr)
Oh, oh, da klaffen aber Lücken.
Nö, ehrlich gesagt ist da meine Hilfsbereitschaft Dir gegenüber gerade etwas runter. Meinetwegen kannste dumm sterben. Erst dreist werden und dann betteln müssen kommt halt nicht gut.
Geändert von Holomino (12.08.2019 um 07:32 Uhr)
Ihr scheint nicht wirklich irgendwann mal ein Multitaskingbetriebssystem erstellt und damit dann auch gearbeitet zu haben. Das ist jetzt nicht böse gemeint oder abwertig, aber die Argumente, die hier oft dafür genannt werden, sprechen eigentlich genau dagegen.
Auf einem Single-CPU-System wird das über Timer gelöst, das ist Standardvorgehen, um dort die verschachtelte Ausführung zu erreichen. Einmal eine Codeumschaltung per Timer zu haben und noch eine oben drauf zu setzen, vernichtet noch mehr Rechenzeit.In DEINEM Falle würde ich ZUSÄTZLICH zum MT einen festen Takt per ESP32-timer programmieren: der läuft dann fest per 50kHz (oder was auch immer), und der Rest läuft trotzdem per MT unabhängig, simultan + asynchron. Dies könnte u.U sowohl per IRQ als auch per high-prio-thread geschehen, wäre aber nicht unbedingt zwingend aufs eine oder andere festgelegt.
Mit Timern alleine aber kriegt man langdauernde Threads per MT + asynchron nicht hin.
Ein kooperatives Multitasking ist für sehr rechenintensive Aufgaben eher das Mittel der Wahl.
Programmabarbeitung im Multithreading bringt mit sich dass, ein Programm auf das andere warten muss. Je öfter eine zeitintensive Aufgabe unterbrochen wird, die erst erledigt sein muss, umso länger warten andere Programmteile. Nicht zwingend ist deswegen ein dauerndes Umschalten der Programmcodes sinnvoll, wo dann auch ständig Register gesichert und wieder hergestellt werden müssen. Solches auf Single-CPUs timergesteuertes Programmwechseln kann das Hauptprogramm daher wesentlich verlangsamen. Mit kooperativem Verhalten erreicht man auf Single-CPU-Systemen eigentlich genau das, was benötigt wird. Ein schnelles Abarbeiten der einzelnen Aufgaben nebeneinander, wobei das Ergebnis möglichst schnell zur Verfügung steht.
Einen Punkt kann man gelten lassen:
Wenn fest steht dass, dauernd Aufgaben nebeneinander her laufen, die keinen Leerlauf beinhalten. Also beispielsweise 5mal derselbe Programmcode nebeinander ausgeführt wird. Aber dafür ist die sequentielle Abarbeitung besser geeignet, da schneller, weil hier die eingestreuten Taktzyklen fehlen, die für Dinge benötigt werden, die nicht dem Hauptzweck entsprechen.
Auf jeden Fall sollte man sich damit erst einmal im Detail grundlegend auseinandersetzen bevor man meint, man könnte auf etwas nicht verzichten. Sonst bleibt nur, die Nachteile mit noch mehr MHz zu erschlagen.
MfG
Geändert von Moppi (12.08.2019 um 07:54 Uhr)
@Moppi:
du hast auch echt nicht verstanden, worum es eigentlich geht. Lies noch mal oben alles genau nach und versuche mal selber mit einem "hängenden Thread" bei einem kooperativen MT Programm heraus zu kommen. Was du schreibst, entbehrt wirklich jeglicher Grundlage.
Ich arbeite seit 20 Jahren mit Multithreading-Programmen auf single- und multicore-cpus, auch mit kooperativen, danach aber überwiegend mit preemptiven und selbstverständlcih inzwischen auch mit Linux (multiuser-mulititasking OS). ich glaube, DU hast keine Ahnung von Multithreading-Programmierung, insbesondere nicht mit preemptiver.
Holomino aber schießt mal wieder den Vogel ab:
Holomino, du bist doch echt ein A******ch - da kommt nun doch wieder deine bekannte beleidigende Trollnatur zum Vorschein.
Ich habe nicht vor, dir deine Programme zu schreiben, ich hatte um nichts "gebettelt" und ich hatte nicht vor, dich um irgendeine "Hilfsbereitschaft" zu bitten
DU warst es, der wollte, dass ich deinen Code in meinen integriere - ich hatte lediglich deinen von dir verlinkten Code portiert und in mein voriges MT-Programm integriert, um zu zeigen dass es grundsätzlich geht.
Bei mir selber für meine Zwecke stehen keine Timer zur Debatte, sondern nur teilweise landauernde, asynchron parallel laufende Threads mit unterschiedlicher Priorität, das hatte ich bereits vorher eindeutig klargestellt.
Du warst es andererseits, der behauptet hatte, er käme ganz ohne MT für das gesamte Programm aus - nur zeigen hast du es nicht können, hast wohl den Mund gehörig zu voll genommen.
Geändert von HaWe (12.08.2019 um 09:30 Uhr) Grund: typo
Du merkst nicht wie undankbar deine art zu schreiben ist ... jemand macht die einen Vorschlag für einen alternativen Weg und von dir kommt A) eine Abwertende Bemerkung dass deine Lösung soweiso besser ist oder B) sofort die Frage nach compile fertigem Code ... wenn das nicht Trollig ist, ist es mindestens Uneinsichtigdeine bekannte beleidigende Trollnatur zum Vorschein
Du provozierst mit deiner Art solche Reaktionen und bist dir dessen scheinbar noch nicht mal bewusst. Aber du nutzt die Reaktion um deinen Standpunkt zu verteidigen.
Skank Hunt (Southpark) wäre echt stolz auf dich. Das wäre genau seine Methode, Leute mit abwertenden Komentaren in eine explodierende Diskussion locken und dann mit dem Finger auf sie zeigen.
Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
nicht.
Zwei Semester Betriebssysteme und ein Semester Echtzeitsysteme reichen nicht? Du vermutest hier ziemlich ins Blaue.
Und was meinst du mit Hauptprogramm? Auf dem Esp32 'endet' die main() im Scheduler, loop() ist nur eine Task.
[Im Folgenden beziehen sich die Aussagen Multitasking betreffend auf FreeRTOS]
Der einzige Nachteil der Nutzung eines präemptiven Multitaskings, den ich sehe, ist, dass auch wenn nur eine Task mit der gerade höchsten aktiven Priorität läuft, sie trotzdem im Scheduler-Takt unterbrochen wird, um zu sehen, ob eine andere Task dran ist. Wenn einem diese kleine Unterbrechung nicht passt, kann man den Scheduler suspenden oder einen kritischen Bereich definieren.
Wenn ich Nebenläufigkeit mit Zeitscheiben will, gebe ich den entprechenden Tasks eine gleiche Priorität, sonst nicht.
Und ich behaupte nicht, nicht auf etwas verzichten zu KÖNNEN, sondern zu WOLLEN. Es ist am Ende eine Frage des Entwicklungszeit. Ich will das Rad nicht jedesmal neu erfinden. Oder mein Design umstellen, wenn ich merke, dass ich Nebenläufigkeit mit Zeitscheiben brauche. Ich will eine API, die ich kenne, und deren Funktionalität getestet und dokumentiert ist.
Wie gesagt: Wenn ich das Multitasking nicht brauche, oder es stört, schalte ich sie aus.
Und das Vorhandensein / die Nützlichkeit von Queues, Semaphoren, Software-Timern, Gruppenevents etc. in diesem Kontext habe ich noch nicht einmal erwähnt... Alles Dinge, die man für gutes Design von System mit Nebenläufigkeit braucht.
Geändert von Sisor (12.08.2019 um 09:27 Uhr)
Lesezeichen