Forum: Compiler & IDEs Erzeugen/Einbinden einer Library (Threads-)


von Manuel (Gast)


Lesenswert?

Hallo!

Ich möchte in AVR-Studio mit Threads programmieren. Diese sind in der 
AVR-Libc aber ja nicht mit drin.

Ich habe im Internet folgende Library dafür gefunden:
http://www.bourbonstreetsoftware.com/AVRDevelopment.html

Dort ist auch eine Erläuterung bei und ich weiß auch, dass es hier auf 
der Seite einen Artikel zu Libraries gibt, aber ehrlich gesagt komme ich 
mit beidem nicht weiter.

In der Erläuterung der Lib steht :
1
2.1 Build
2
3
To install the AVR Threads Library, unpack the source tree. If you downloaded
4
the *.tgz version, you can do this with the following command:
5
6
tar -xzf threads-1.3-src.tgz
7
8
Next, change directory to the head of the source tree that was just unpacked
9
and run the make command:
10
11
$ cd threads-1.3
12
$ make
13
14
This should build the AVR Threads Library for all the supported AVR microcontrollers.
15
16
17
2.2 Installation
18
19
Once the libraries have been successfully built, you need to install the library
20
components to a location where the AVR GCC compiler can find them.
21
The default installation directory prefix is /usr/local. If you wish to change
22
this, you will have to edit the src/Makefile file in the source tree. In the
23
Makefile, you’ll find a line that looks like this:
24
25
prefix = /usr/local
26
27
Change this line to desired directory prefix. For example, if you’re using
28
WinAVR, you will need to change this this point to where WinAVR has been installed.
29
For example, if WinAVR has been installed in c:\WinAVR, then change
30
the prefix line to this:
31
32
prefix = c:/WinAVR
33
34
Finally, from the head of the source tree, or from the src directory, run this:
35
36
$ make install

wo kann ich denn diese Befehle eingeben?

Selbiges Problem, wenn ich das über die "Libraries-Anleitung" versuchen 
will:
1
Compileraufruf 
2
Da eine Library lediglich kompiliert und assembliert, aber nicht gelinkt
3
werden soll, muss das beim Compileraufruf berücksichtigt werden. Der 
4
Kommandozeilenschalter dafür ist '-c'. 
5
6
$ gcc -c -ggdb -O2 -o libmylibfunc1.o libmylibfunc1.c
7
8
[Bearbeiten] Archiv erstellen 
9
Das Archivierungsprogramm 'ar' wird dazu verwendet, um die kompilierten
10
Objektfiles zu einer Library zusammen zu fügen. 
11
12
$ ar -rcs libmylib.a libmylibfunc1.o libmylibfuncs.o

Auch hier bin ich ehrlich gesagt überfragt wie ich direkt einen 
Compileraufruf starten kann...

Oder alternativ, welche Threads-Lib ist gut und wie bekomme ich diese 
auch genutzt >.<

mfg, danke

von Peter (Gast)


Lesenswert?

Manuel schrieb:
> Ich möchte in AVR-Studio mit Threads programmieren

Auf einem µC (kleiner 8bit atmel) gibt es keine BS auch gibt es dort 
soetwas wie Thread nichts, da hilft es auch nicht wenn man die lib 
benutzt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter schrieb:
> Manuel schrieb:
>> Ich möchte in AVR-Studio mit Threads programmieren
>
> Auf einem µC (kleiner 8bit atmel) gibt es keine BS auch gibt es dort
> soetwas wie Thread nichts, da hilft es auch nicht wenn man die lib
> benutzt.

Dann lies Dir einfach mal die Beschreibung auf 
http://www.bourbonstreetsoftware.com/AVRDevelopment.html durch, und Du 
wirst sehen, daß diese Library genau das tut, sie stellt 
Threadfunktionalität auf einem AVR zur Verfügung:
1
The AVR Threads Library provides basic preemptive multitasking/multi-
2
threading to the Atmel AVR family of microcontrollers. It is written 
3
mostly in C with some assembly language. It implements a simple round-
4
robin style task switcher.
5
6
This library provides basic thread start and stop functions, a couple 
7
of flavors of mutual exclusion semaphore, and events to help synchronize
8
threads.

von Rolf Magnus (Gast)


Lesenswert?

Ob das auf einem AVR sinnvoll ist, sei aber mal dahingestellt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dann ist auch jedes RTOS auf einem µC sinnlos.

von Rolf Magnus (Gast)


Lesenswert?

Rufus t. Firefly schrieb:
> Dann ist auch jedes RTOS auf einem µC sinnlos.

Na das ist dann doch etwas arg allgmein. Beim AVR hat man z.B. das 
Problem, daß ein Taskwechsel aufgrund der großen Zahl an Registern, die 
alle einzeln gesichert werden müssen, recht teuer ist (sowohl im Bezug 
auf die Taskwechsel-Dauer, als auch im Bezug auf Speicherverbrauch). 
Dazu kommt, daß für jeden Thread ein eigener Stack benötigt wird.
Wenn man nur einen Stack hat, ist der eben so groß, wie der noch nicht 
anderweitig verbrauchte Speicher. Sobald man Threads hat, muß man für 
jeden Thread schauen, wie groß der Stack jeweils maximal sein kann und 
die entsprechende Menge Speicher dafür allokieren, auch wenn es nie 
vorkommt, daß alle Threads gleichzeitig die maximale Stackauslastung 
haben. Das ist halt auf vielen AVRs mit ihrem knappen SRAM eher 
einschränkend.
Da muß man schauen, daß man nicht für die Threads ein Vielfaches der 
Ressourcen verbraucht, die nachher für die eigentliche Aufgabe noch 
übrig sind und daß man dabei überhaupt einen Vorteil aus der Verwendung 
von Multithreading ziehen kann.

von Manuel (Gast)


Lesenswert?

also ich hab nen Atmega2561, der hat immerhin den doppelten SRAM :)

bevor ich auf diesen atmega umgestiegen bin hatte ich ein JControl 
Board, mit einem mir nicht bekannten µC, auch 8-bit, 64kFlash und soweit 
ich weiß nochmal deutlich weniger SRAM, den habe ich über JAVA 
programmiert und da liefen Threads ohne Probleme und ohne großen 
Aufwand...

Wie kann ich denn sonst realisieren, mehrere ADC-Eingänge "gleichzeitig" 
abzufragen? Denn sonst wäre das ja sinnlos, dass er überhaupt mehrere 
hat.

Wie dem auch sei, freut mich ja dass ich hier ne Diskussion angestoßen 
habe, aber ich als Neuling stehe immernoch vor dem Library-Problem!

von Peter (Gast)


Lesenswert?

Manuel schrieb:
> Wie kann ich denn sonst realisieren, mehrere ADC-Eingänge "gleichzeitig"
> abzufragen? Denn sonst wäre das ja sinnlos, dass er überhaupt mehrere
> hat.

was soll denn das? Sotwas wird immer nacheinander gemacht. Auch wenn du 
es über threads macht wird es nicht gleichzeit gemacht. Wo soll das 
Problem sein?

wert[0] = GetADC(1);
wert[2] = GetADC(2);
wert[3] = GetADC(3);
wert[4] = GetADC(4);
wert[5] = GetADC(5);
wert[6] = GetADC(6);

bei java wird ja jeder mist über ein einen Thread gemacht, weil es dort 
teilweise nicht anders geht - aber resourcend schonen ist das bestimmt 
nicht. Ich denke mal das 95% aller Projekte hier ohne Thread arbeiten 
und drozdem scheinbar viele dinge gleichzeig machen.

von mano (Gast)


Lesenswert?

Dein Mikro hat einen ADC und der hat 8 Kanäle, oder hebe ich mich 
verschaut?

von roflkartoffel (Gast)


Lesenswert?

der hat genau 1 ADC .. über einen multiplexer werden 8 eingänge 
umgeschalten

wenn du mit threads arbeitest und er würde dir in den thread kotzen und 
dann das sample des ADC4 auf ADC3 ausgeben ... blöd gesagt

du kannst eh nur nacheinander abarbeiten von daher erübrigt sich das 
ganze gethreade


lass den ADC im freerunning mode laufen und mach einen ADC complete 
interupt
wenn der interrupt kommt schalteste den eingang um und speicherst das 
ergebnis
mit dem nächsten interrupt kommt auch das nächste ergebnis
das kannste dann einfach so laufen lassen

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Manuel schrieb:

> wo kann ich denn diese Befehle eingeben?

In einer Shell/Kommandozeile/Eingabeaufforderung (cmd.exe)

Damit das funktioniert muss eine bestimmte Umgebung vorhanden sein. Was 
fehlt, wird man erst sehen, wenn die Fehlermeldungen zu den eingegebenen 
Kommandos kommen -- und so wie's aussieht ist recht wahrscheinlich, daß 
was fehlt.

von Manuel (Gast)


Angehängte Dateien:

Lesenswert?

okay ja, dann fehlt da tatsächlich was.

naja, wie dem auch sei, ich komme wirklich ohne Threads aus, war ein 
anderes Problem wodurch ich den Eindruck hatte, der ADC wäre zu langsam.

Passt zwar nicht mehr zum Thread-Namen aber kann mal jemand bei 
Gelegenheit kurz in die Datei gucken und mir sagen, warum ich am PinE3 
und E4 kein PWM-Signal erhalte?! Irgendetwas scheine ich da noch nicht 
ganz verstanden zu haben.
Ich möchte die aus der Spannung am Eingang gewonnene Zahl direkt an den 
PWM weitergeben und dadurch die Pulsweite bestimmen. Ich kann mir auf 
meinem Display die Spannungen, die ich anlege, anzeigen lassen, das 
funktioniert, aber ich bekomm hinten nicht das raus was ich haben 
will...(Nicht über die LCD_Befehle wundern, die sind vom 
Display-Hersteller mitgeliefert)

von Manuel (Gast)


Lesenswert?

hm, hat keiner ne Idee für mich? Ich seh den Fehler, auch nach 
vergleichen mit Tutorial und anderen Beiträgen nicht. Eig kann der 
Fehler nur in PWM_Init oder PWM_Set sein, aber keine Ahnung was ich da 
ändern sollte.

von Karl H. (kbuchegg)


Lesenswert?

1
void PWM_Init(void)
2
{
3
     DDRE |= (1<<PE3) | (1<<PE4);             // PinE3 und E4 auf Ausgang
4
    TCCR3A |= (1<<COM3A1) | (1<<COM3B1);     //OC3A PINE3/OC3B PinE4 auf nicht inv.PWM
5
    TCCR3A = ((1<<WGM31) | (1<<WGM30));      // 10 Bit PWM

mit der 2.ten Zuweisung löscht du dir die bei der ersten Zuweisung 
gesetzten COM Bits wieder.

von Manuel (Gast)


Lesenswert?

äh ja klingt logisch...

gehen tuts leider trotzdem nicht >.<

hab aus verzweiflung jetzt erstmal nur nen anderes Programm zum Dimmen 
einer LED (der LED des Displays, welche an (OC0A/OC1C/PCINT7) PB7 
anliegt) geschrieben, aber nichtmal das geht, bin langsam echt am 
verzweifeln an PWM obwohl das ja eigentlich gar nichts schweres ist. 
sobald ich einmal ein lauffähiges prog habe, bekomm ich es auch sicher 
hin aber irgendwas muss ich scheinbar noch vergessen
1
#include <stdio.h>
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <avr/pgmspace.h>
5
#include <stdint.h>
6
#include <glcd-Display3000-211.h>
7
8
9
void delay_ms(uint16_t period);
10
11
12
int main (void)
13
{
14
15
  uint8_t i;  
16
  char c[8];
17
18
  DDRB |= (1<<PB7);
19
20
21
22
  TCCR0A = (1<<COM0A1) | (1<<WGM00);//Phasenkorrektes PWM, clear on compare match
23
  TCCR0B = (1<<CS01);                //Prescaler 8
24
  //sei();
25
26
  LCD_Init();
27
  Orientation = Portrait180;//Ausgaberichtung nach unten 
28
  delay_ms(1000);            //Display braucht wegen Trägheit bisschen Zeit
29
  LCD_Cls(white);           // Clear Screen
30
  
31
  LCD_Print("Dimmen testen", 0, 10, 1, 1, 2, blue, dark_red);
32
33
  
34
35
  for(i=0; i<=255; i++)
36
  {
37
    OCR0A = i;              //Zählerwert von i für Helligkeit
38
    itoa(i, c, 10);
39
    LCD_Print("Dimmwert:", 0, 40, 1, 1, 1, black, white);
40
    LCD_Print(c, 60, 40, 1, 1, 1, red, white);
41
    delay_ms(500);
42
43
  }
44
45
  OCR0A = 130;              //Mittlere Helligkeit zum Ende
46
  for(;;);
47
48
49
  return 0;
50
}
51
52
53
54
55
56
57
58
/****************************************************************/
59
void delay_ms(uint16_t period)   //delay routine (milliseconds)
60
{
61
  for(unsigned int i=0; i<=period; i++)
62
    _delay_ms(1);
63
}

muss ich vielleicht noch soetwas wie global interups enablen oder 
sonstige interrupt-routines? im PWM-modus ja eigentlich nicht?!

von Manuel (Gast)


Lesenswert?

Kann meinen letzten Beitrag hier leider nicht wieder löschen (weil ich 
nicht angemeldet bin?)

aber das LED-Dimm Programm funktioniert doch, die LED des Displays war 
nur über einen Spannungsbooster dauerhaft auf HIGH gestellt, ich musste 
einen Kontakt umlöten.

Zu meinem eigentlichen Programm: ich vermute, dass ich den simplen 
Fehler gemacht habe, OCR3A/B bei Mode 15 (fast PWM, 10-bit) als 
einzustellende Weite genommen habe und nicht als Obergrenze, aber was 
nehme ich denn dann zum einstellen der Pulsweite?

von Karl H. (kbuchegg)


Lesenswert?

Manuel schrieb:

> Zu meinem eigentlichen Programm: ich vermute, dass ich den simplen
> Fehler gemacht habe, OCR3A/B bei Mode 15 (fast PWM, 10-bit) als
> einzustellende Weite genommen habe und nicht als Obergrenze

Das kann nicht sein.
Bei einer 10-Bit PWM ist die Obergrenze fox auf 10 Bit, also 1024

>, aber was
> nehme ich denn dann zum einstellen der Pulsweite?
OCR3A bzw OCR3B, je nachdem welche Pins du mit den COMxx Bits 
freigegeben hast.

von Manuel (Gast)


Lesenswert?

Zwar nicht sehr übersichtlich, aber hier die Liste ausm Datenblatt.
Ich hatte Modus 15 eingestellt, dort ist OCRnA Top, habs jetzt auf Modus 
7 geändert, da ist es tatsächlich so wie du meintest und nun 
funktioniert auch alles, danke für die Hilfen!

1
0 0 0 0 0 Normal 0xFFFF Immediate MAX
2
1 0 0 0 1 PWM, Phase Correct, 8-bit 0x00FF TOP BOTTOM
3
2 0 0 1 0 PWM, Phase Correct, 9-bit 0x01FF TOP BOTTOM
4
3 0 0 1 1 PWM, Phase Correct, 10-bit 0x03FF TOP BOTTOM
5
4 0 1 0 0 CTC OCRnA Immediate MAX
6
5 0 1 0 1 Fast PWM, 8-bit 0x00FF BOTTOM TOP
7
6 0 1 1 0 Fast PWM, 9-bit 0x01FF BOTTOM TOP
8
7 0 1 1 1 Fast PWM, 10-bit 0x03FF BOTTOM TOP
9
8 1 0 0 0 PWM, Phase and Frequency Correct ICRn BOTTOM BOTTOM
10
9 1 0 0 1 PWM,Phase and Frequency Correct OCRnA BOTTOM BOTTOM
11
10 1 0 1 0 PWM, Phase Correct ICRn TOP BOTTOM
12
11 1 0 1 1 PWM, Phase Correct OCRnA TOP BOTTOM
13
12 1 1 0 0 CTC ICRn Immediate MAX
14
13 1 1 0 1 (Reserved) – – –
15
14 1 1 1 0 Fast PWM ICRn BOTTOM TOP
16
15 1 1 1 1 Fast PWM OCRnA BOTTOM TOP

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.