Forum: Mikrocontroller und Digitale Elektronik Parallel Programmieren


von simon (Gast)


Lesenswert?

hallo!!

ich möchte einen thread im programm starten, hat mir jemand ein kleines 
codebeispiel wie so ein thread aussehen muss, wie ich ihn starte und was 
ich sonst noch so alles dafür brauche(includes prototypen usw.)?
controller ist ein attiny2313, falls es jemanden interessiert :~)

dank euch schonmal :)

von Klaus W. (mfgkw)


Lesenswert?

Threads hast du, wenn dein Betriebssystem dir welche anbietet.
Falls du eines hast ... :-)

Auf einem AVR wirst du das in aller Regel von Hand bauen müssen
mit Interrupts - siehe Tutorial.

von simon (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Auf einem AVR wirst du das in aller Regel von Hand bauen müssen
> mit Interrupts - siehe Tutorial.

interrupts sind kein problem, das tutorial habe ich auch schon fast ganz 
durch. möchte einen 2ten thread parallel zum hp starten der mir dann zb 
was einliest oder so.

von Peter (Gast)


Lesenswert?

simon schrieb:
> möchte einen 2ten thread parallel zum hp starten der mir dann zb
> was einliest oder so

und genau das macht mit mit interupts, dafür braucht man keine Threads.

von heinzhorst (Gast)


Lesenswert?

Ok, Grundlangen der Mikrocontroller - Firmwareentwicklung. Weist du, was 
"kooperatives Multitasking" ist? Wenn nein - goolen und durchlesen.

von simon (Gast)


Lesenswert?

heinzhorst schrieb:
> Multitasking

genau das ist das stichwort :)
wie stelle ich es bem avr an??
die abarbeitung meines programms soll "parallel" erfolgen, also ein 
interrupt scheidet aus.

von Εrnst B. (ernst)


Lesenswert?

simon schrieb:
> die abarbeitung meines programms soll "parallel" erfolgen, also ein
> interrupt scheidet aus.

in main:
1
while(1) {
2
  mach_ein_bischen_was_von_thread_a();
3
  mach_ein_bischen_was_von_thread_b();
4
}

Musst also nur die Einzelaufgaben in kleine Stückchen zerlegen, und die 
jeweils abwechselnd ausführen.

von Peter (Gast)


Lesenswert?

simon schrieb:
> die abarbeitung meines programms soll "parallel" erfolgen, also ein
> interrupt scheidet aus.

mach es am besten so wie es die meisten leuten auf einem Amtel machen, 
also mit interupts. Man sollte auf einem µC nicht wie auf einem PC 
programmieren, threads sind nicht immer die beste wahl.

von simon (Gast)


Lesenswert?

Εrnst B✶ schrieb:
> Musst also nur die Einzelaufgaben in kleine Stückchen zerlegen, und die
> jeweils abwechselnd ausführen.

das war mal meine ursprüngliche idee, wenn ich jetzt aber (nur 
beispielhaft) zb eine led blinken lassen möchte im thread 1 (also 
irgendwas prozessor blockierendes) und mit dem 2ten thread zb einen 
taster einlesen möcht (blödes beispiel :), dann sollte ich ja schon 
echtes multithreading betreiben.

von Klaus W. (mfgkw)


Lesenswert?

Auf einem Prozessor mit nur einem Kern gibt es kein "parallel".

Es gibt höchstens ein "quasi parallel", indem laufend zwischen
den Dingern umgeschaltet wird, die du "Thread" nennst.

Und das musst du auf einem AVR von Hand programmieren, und
dazu brauchst du Interrupts.

Wenn du echte Threads (die das für dich irgendwo versteckt dann
auch machen), brauchst du ein Betriebssystem - und wahrscheinlich
einen etwas kräftigeren Prozessor.

von Peter (Gast)


Lesenswert?

simon schrieb:
> das war mal meine ursprüngliche idee, wenn ich jetzt aber (nur
> beispielhaft) zb eine led blinken lassen möchte im thread 1 (also
> irgendwas prozessor blockierendes) und mit dem 2ten thread zb einen
> taster einlesen möcht (blödes beispiel :), dann sollte ich ja schon
> echtes multithreading betreiben.

nein auch dafür braucht man das nicht, die LED kann schön von interupt 
geblinkt werden dafür muss auch nichts blockieren.

von simon (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Wenn du echte Threads (die das für dich irgendwo versteckt dann
> auch machen), brauchst du ein Betriebssystem - und wahrscheinlich
> einen etwas kräftigeren Prozessor.

geht es nicht das ich zwei threads vom hp aus starte?
das es nicht wirklich parallel ist, ist mir klar :)

von simon (Gast)


Lesenswert?

simon schrieb:
> Klaus Wachtler schrieb:
>> Wenn du echte Threads (die das für dich irgendwo versteckt dann
>> auch machen), brauchst du ein Betriebssystem - und wahrscheinlich
>> einen etwas kräftigeren Prozessor.
>
> geht es nicht das ich zwei threads vom hp aus starte?
> das es nicht wirklich parallel ist, ist mir klar :)

@peter: war ja nur ein beispiel :)

von simon (Gast)


Lesenswert?

wenn jetzt die led über einen längeren zeitraum blinkn soll und ich 
währenddessen was anderes machen möchte wie stelle ich das an, 
interrupts sollten ja nicht ewig laufen!

von Peter (Gast)


Lesenswert?

simon schrieb:
> wenn jetzt die led über einen längeren zeitraum blinkn soll und ich
> währenddessen was anderes machen möchte wie stelle ich das an,
> interrupts sollten ja nicht ewig laufen!

i++;
if ( i == 100 ) {
 LAMPE_AN
}

if ( i == 200 )  {
  LAMPE_AUS
  i = 0;
}

von Karl H. (kbuchegg)


Lesenswert?

zb so

1
volatile uint8_t led_soll_blinken;
2
3
interrupt service routine
4
{
5
  if( led_soll_blinken )
6
    schalte LED in den anderen Zustand
7
}
8
9
int main()
10
{
11
12
  setze timer so auf, dass die interrupt service routine
13
  regelmässig aufgerufen wird
14
15
  while( 1 ) {
16
17
     if irgendwas
18
       led_soll_blinken = 1;
19
20
     if irgendwas anderes
21
       led_soll_blinken = 0;
22
  }
23
}

In dem Moment, in dem du '_delay_ms' denkst, bist du schon falsch. Das 
wird dann nichts mehr.

von der Blinker (Gast)


Lesenswert?

Interrupt regelmäßig auslösen und jedes Mal LED-Port 
setzen/zurücksetzen.

Alles andere läuft im Hauptprogramm und wird nur für das 
Setzen/Rücksetzen unterbrochen.

von Karl H. (kbuchegg)


Lesenswert?


von Imon (Gast)


Lesenswert?

Wenn du auf ein AVR mit threads Arbeiten willst, wirst du selber denn 
Thread Wechsel Programmieren müssen. Das Läuft im Allgemeinen darauf 
hinaus das du einen Timerinterrupt hast der regelmäßig kommt und ein 
Scheduling auslöst das deine thread ggf umschaltet, ob sich das bei ein 
Tiny2313 wirklich Lohnt ist fraglich, aber eine schöner Zeitvertreib.
Zumal man dann ganz schnell solche Sachen wie Priotäten und Semaphore 
will. Dann Kommt man auf Problem wie Priotätsinversion etc. Das Ganze 
ist ein schönes aber nicht Trivialesfeld um zu verstehen wie 
Betriebsysteme Ticken.
Ich wünsch echt viel Erfolg wenn du dich da hinein Arbeiten willst, 
allerdings Driftest du da schnell vom Hundertstel ins Tausendstel.


Benutz mal die Suche,ich meine wir hatten vor ein paar Wochen eine 
Diskussion hier im Forum wo jemand seine Arbeit zu denn Thema Tasks & 
AVR vorgestellt hat. Vielleicht Hilft dir das ein Anfang zu finden.

von simon (Gast)


Lesenswert?

super, ich danke euch für die tollen antworten! ich weiß es wird nicht 
ganz trivial, aber mir geht es um den aha effekt :))

von heinzhorst (Gast)


Lesenswert?

Mann, da hab ich ja was losgetreten...

Für das Blinken on LEDs braucht man keine Interrupts zu verschwenden. Ob 
eine LED dabei ein paar ms früher oder Später eingeschaltet wird ist 
Sch**ßegal.

Also erstmal ganz zum Anfang. Prinzipiell sollte mal seine Firmware für 
eine bessere Portierbarkein und wiederverwertbarkeit von einmal 
erstelltem Quellcode modular aufbauen. Jedes Modul bekommt seine eigene 
Quellcode und Headerdatei. Darüber hinaus hat jedes Modul:

- Initialisierungsfunktion

Hier werden alle Aufgaben abgeaubeitet, die Das Modul beim Booten 
erledigen Muss, z.B. Variablen und Register mit Startwerten vorbelegen, 
Initialisierung der Hardware, etc.

- Task

Hier werden alle zyklisch auszuführenden Aufgaben abgearbeitet, z.B. 
Werde von externem Sensor abholen, Werte von ADC abholen. Der Task darf 
nicht durch das Warten auf irgendein Ereignis oder durch Zeitschleifen 
blockiert werden.

- IO-Funktionen

Die IO-Funtionen dienen zur Kommunikation der Module untereinander. 
Beispiel: Der im Taskabgefragte Wert aus dem ADC wird durch eine 
IO-Funktion den anderen Mudulen zur Verfügung gestellt.


So. Nun zurück zum Multitasking. Die Main ruft nacheinander alle 
initialisierungsfunktionen auf. Danach läuft sie in eine Endlosschleife, 
in der nacheinander die Tasks der einzelnen Module abgearbeitet werden. 
Das sieht dann so aus:
1
void main(void){
2
3
// initialisation
4
5
modu1_1_init();
6
modu1_2_init();
7
modu1_3_init();
8
...
9
modu1_n_init();
10
11
// endless loop
12
13
while(1){
14
15
modu1_1_task();
16
modu1_2_task();
17
modu1_3_task();
18
...
19
modu1_n_task();
20
21
   }
22
}

von simon (Gast)


Lesenswert?

das klingt gut, aber wird so nicht jeder task zyklisch abgearbeitet und 
darauf dann der nächste gestartet?

grüße und danke schon mal!

von Karl H. (kbuchegg)


Lesenswert?

simon schrieb:
> das klingt gut, aber wird so nicht jeder task zyklisch abgearbeitet und
> darauf dann der nächste gestartet?

Wenn jeder Task nur kurz genug ist, ist das ja kein Problem.

von Bastler (Gast)


Lesenswert?

Das Zeitscheiben Prinzip ist simpel, aber oft auch ausreichend.

Messaufgaben, Tastenabfragen, ... können so z.B. alle 10ms aufgerufen 
werden und Display-Ausgaben alle 0,5s.

Da wird auch nur ein Timer benötigt, also echt resourcenfreundlich.
Du musst nur darauf achten, dass sie einzelnen Tasks nicht länger dauern 
als die Aufrufe.


Task_1ms(void)
{
  CheckAlarmFlags();
}

Task_10ms(void)
{
  ReadInPuts();
  ReadADC();
}

Task_100ms(void)
{
  ToggleLEDs();
  HandleWatchdog();
}

Task_1s(void)
{
  RefreshDisplay();
}

von sepepe97 (Gast)


Lesenswert?

Wenn Dein Timer z.B. einen 10ms-Takt generiert und alle weiteren 
(langsameren) Zeitscheiben von der 10ms-Zeitscheibe abgeleitet werden,
darf die Summe aller Abarbeitungszeiten in allen Zeitscheiben nicht mehr 
als 10ms betragen.
Ansonsten überschreitest Du den 10ms-Basistakt und verlässt die 
Echtzeitfähigkeit. Andersrum sind die Zeitpunkte der Abarbeitung der 
einzelnen "Tasks" in den Zeitscheiben sowieso von der Abarbeitungszeit 
der restlichen vorher durchlaufenen "Tasks" abhängig und verschiebt sich 
daher ständig ein wenig hin und her.

Je nach Implementation würdest Du dann einen 10ms-Zyklus vergessen oder 
die 10ms-Zeitscheibe nach Durchlauf sofort wieder starten.

Ist aber beides nicht sinnvoll. Beim ersten wie auch beim zweiten würde 
Dein grobes Timing nicht mehr vorhersagbar sein.

Eine Ausnahmebehandlung bei Zeitüberschreitung sollte daher immer 
vorhanden sein.

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
Noch kein Account? Hier anmelden.