Forum: Mikrocontroller und Digitale Elektronik Zeiger mit AT90CAN


von Mirco G. (mirco432)


Lesenswert?

Hallo!

Ich arbeite gerade mit einem AT90CAN also einem 8-bit Controller.

Wie genau muss ich da mit Zeigern umgehen? Die Adressen sind ja 
eigentlich zu lang für den Controller.

Gibt es irgendwelche Zugriffsbeschränkungen? Angenommen ich habe eine 
NICHT globale Variable. Kann ich trotzdem über die Adresse in einem 
anderen Teil des Programms auf die Variable zugreifen? Also aus einem 
Teil in dem ein normaler Zugriff nicht möglich wäre.


Vielen Dank

Mirco

von Axel S. (a-za-z0-9)


Lesenswert?

Mirco G. schrieb:
> Ich arbeite gerade mit einem AT90CAN also einem 8-bit Controller.
> Wie genau muss ich da mit Zeigern umgehen? Die Adressen sind ja
> eigentlich zu lang für den Controller.

Du sprichst in Rätseln. Was für "Zeiger"? Programmierst du in C? Denn da 
gibt es Zeiger. Und die sind auch nicht "zu lang für den Controller" 
(was auch immer du damit meinst)

> Gibt es irgendwelche Zugriffsbeschränkungen? Angenommen ich habe eine
> NICHT globale Variable. Kann ich trotzdem über die Adresse in einem
> anderen Teil des Programms auf die Variable zugreifen? Also aus einem
> Teil in dem ein normaler Zugriff nicht möglich wäre.

C hat an sich gar keine Zugriffsbeschränkungen. Aber die Sichtbarkeit 
von Variablen ist eingeschränkt, was bei Zugriff auf eine nicht 
sichtbare Variable zu einem Fehler schon beim Compilieren des Programms 
führt.

Im Prinzip kann man das umgehen, z.B. indem man aus einer Funktion einen 
Zeiger auf eine lokale Variable herausgibt (als Returnwert, per 
Zuweisung an eine globale (Zeiger)variable, etc). Der Zugriff selber 
kann dann aber in die Hose gehen, weil bspw. lokale Variablen zum 
Zeitpunkt des Zugriffs gar nicht mehr existieren müssen.

von Toni Tester (Gast)


Lesenswert?

Du wirfst hier alles Mögliche durcheinander.

- Um welche Programmiersprache geht es - C? => Das C-Buch deiner Wahl 
sagt dir, wie man Zeiger deklariert und anwendet.
- AVR ist eine Harvard-Architektur, d. h. getrennte Speicherbereiche für 
Flash und RAM, d. h. es gibt identische/überlappende Adressbereiche, und 
der µC unterscheidet an Hand der genutzten Mnemonics, auf welchen 
Speicher zugegriffen werden soll. Die AVR-libC bietet auf C-Ebene 
entsprechende Unterstützung durch dedizierte Makros.
- "8-bit-Mikrocontroller" heißt nur, dass die internen Register, ALU 
usw. 8 Bit breit sind. Das ist nicht zwangsläufig auch die Breite der 
Speicher-Adressregister.
- Theoretisch kannst du aus jedem Programmteil auf jeden Speicherbereich 
zugreifen - du musst "nur" die Adresse im Speicher (und bei der 
Harvard-Architektur den gewünschten Speicher) kennen.

von Peter D. (peda)


Lesenswert?

Mirco G. schrieb:
> Die Adressen sind ja
> eigentlich zu lang für den Controller.

Sagt wer?
Das Datenblatt bestimmmt nicht. Warum schaust Du da nicht einfach mal 
rein?

von Falk B. (falk)


Lesenswert?

Mirco G. schrieb:
> Hallo!
>
> Ich arbeite gerade mit einem AT90CAN also einem 8-bit Controller.
>
> Wie genau muss ich da mit Zeigern umgehen?

So wie auf allen anderen C-Plattformen.

> Die Adressen sind ja
> eigentlich zu lang für den Controller.

Quark. Sie sind so lang, wie es der Compiler benötigt.

> Gibt es irgendwelche Zugriffsbeschränkungen? Angenommen ich habe eine
> NICHT globale Variable.

Das ist nicht eindeutig.

> Kann ich trotzdem über die Adresse in einem
> anderen Teil des Programms auf die Variable zugreifen?

Jain. Klingt aber nach einem schlechten Konzept. Wenn man an mehreren 
Stellen im Programm auf eine Variable zugreifen muss, dann sollte die 
global sein.

> Also aus einem
> Teil in dem ein normaler Zugriff nicht möglich wäre.

Warum ist der nicht möglich?

Sagen wir es so. Eine Funktion kann nicht auf lokale Variablen anderer 
Funktionen zugreifen. Schon gar nicht auf die normalen, nicht 
statischen. Und auf die statischen nur mit Handständen, die man 
praktisch nicht machen sollte.

>
> Vielen Dank

von Mirco G. (mirco432)


Lesenswert?

Entschuldigt meinen schwammigen Beitrag! War keine Absicht.

Axel S. schrieb:
> Du sprichst in Rätseln. Was für "Zeiger"? Programmierst du in C? Denn da
> gibt es Zeiger. Und die sind auch nicht "zu lang für den Controller"
> (was auch immer du damit meinst)

Ich Programmiere in C, ja.

Anscheinend hab ich ein ungesundes Halbwissen bezüglich Rechner- bzw. 
Mikrocontroller Architektur bzw. Arbeitsweise.

Kann mir jemand vielleicht Literatur bezüglich Rechnerstruktur 
empfehlen?
Also bez. Datenbus, Adressbus, Steuerbus, Programmierspeicher usw.? 
Komischerweise finde ich gerade mit Google nichts gescheites.

Axel S. schrieb:
> C hat an sich gar keine Zugriffsbeschränkungen. Aber die Sichtbarkeit
> von Variablen ist eingeschränkt, was bei Zugriff auf eine nicht
> sichtbare Variable zu einem Fehler schon beim Compilieren des Programms
> führt.
>
> Im Prinzip kann man das umgehen, z.B. indem man aus einer Funktion einen
> Zeiger auf eine lokale Variable herausgibt (als Returnwert, per
> Zuweisung an eine globale (Zeiger)variable, etc). Der Zugriff selber
> kann dann aber in die Hose gehen, weil bspw. lokale Variablen zum
> Zeitpunkt des Zugriffs gar nicht mehr existieren müssen.

Ok. Das wollte ich wissen :).

Toni Tester schrieb:
> - Theoretisch kannst du aus jedem Programmteil auf jeden Speicherbereich
> zugreifen - du musst "nur" die Adresse im Speicher (und bei der
> Harvard-Architektur den gewünschten Speicher) kennen.


Da "theoretisch" im sinne von Axel S.?

Toni Tester schrieb:
> Das C-Buch deiner Wahl
> sagt dir, wie man Zeiger deklariert und anwendet.

Genau deswegen hab ich den Beitrag ja geschrieben. Habe sogar direkt 
Copy-Paste aus dem Buch gemacht und der Compiler sagt trd nein.

Hier der Code den ich getestet habe:
1
int x; 
2
float y;
3
4
int *pi; 
5
float *pf;
6
7
pi = &x; 
8
pf = &y;
9
10
*pi = 1234;
11
*pf = *pi + 0.5

Peter D. schrieb:
> Das Datenblatt bestimmmt nicht. Warum schaust Du da nicht einfach mal
> rein?

Hab ich. Aber ich bin daraus bezüglich Adressen und Zugriffsrechte nicht 
wirklich schlau geworden. Liegt aber wie oben erwähnt vermutlich daran 
das die Grundlagen noch nicht richtig sitzen, wie ich jetzt gemerkt 
habe. Hole ich jetzt nach.

Falk B. schrieb:
> Jain. Klingt aber nach einem schlechten Konzept. Wenn man an mehreren
> Stellen im Programm auf eine Variable zugreifen muss, dann sollte die
> global sein.

Ist auch nicht mein Konzept. Hab ich nur aus Neugierde gefragt.


Vielen Dank für eure Geduld.

War nicht meine Absicht so einen schlechten Beitrag zu schreiben. 
Sry!!!!!

von Peter D. (peda)


Lesenswert?

Mirco G. schrieb:
> Ich Programmiere in C, ja.

Dann kümmert sich der Compiler doch um alles. Der AVR-GCC legt int als 
16Bit fest, d.h. Du kannst bis zu 64kB Variablen und 64kWorte Code 
linear adressieren.

Mirco G. schrieb:
> Aber ich bin daraus bezüglich Adressen und Zugriffsrechte nicht
> wirklich schlau geworden.

8Bitter mit Zugriffsrechten sind mir nicht bekannt.

von Toni Tester (Gast)


Lesenswert?

Mirco G. schrieb:
> Da "theoretisch" im sinne von Axel S.?

Nein.
Ich meinte, mit C an sich kannst du bereits lesend und schreibend auf 
alle möglichen Adressen zugreifen. Beispiel (schnell von Stackoverflow 
kopiert):
1
    char *ptr = (char *)0x12345678; //the addr you wish to access the contents of
2
    printf("%c\n", *ptr); //this will give you the first byte, you can add any more bytes you need to the ptr itself, like so: *(ptr + nbyte).

Denn: Ein Zeiger ist ja definitionsgemäß die Adresse eines 
Speicherbereichs. Nach Einstellen der Adresse kannst du somit jeglichen 
Blödsinn anstellen. Und das erklärt hoffentlich auch, warum das für 
"normale" Programme bad practice ist, und man einfach dem Compiler die 
Verwaltung der Variablen im Speicher überlässt.
Für programmteilübergreifende Variablen gibt es ja eben genau deswegen 
global.

Mirco G. schrieb:
> Habe sogar direkt
> Copy-Paste aus dem Buch gemacht und der Compiler sagt trd nein.

Wenn du uns jetzt noch die Meldung(en) des Compilers verraten hättest, 
könnte man hier evtl. weiterhelfen. Nicht umsonst produziert der 
Compiler ausführliche Meldungen inkl. Zeilennummernangabe.
Auf den ersten Blick sehe ich ein fehlendes Semikolon und keinen 
Funktionsrumpf (main()) oder eingebundene Header.
Ob die Addition eines Integers mit einem Float so compiliert, hängt 
AFAIR von den Compilersettings ab - aber bin schon ewig raus aus der 
Materie.

von Toni Tester (Gast)


Lesenswert?

Toni Tester schrieb:
> Ob die Addition eines Integers mit einem Float so compiliert, hängt
> AFAIR von den Compilersettings ab - aber bin schon ewig raus aus der
> Materie.

Korregation: Geht natürlich - allerdings wird der Float in Int gerundet 
=> wenig sinnvolles Beispiel.
Als C-Buch hatte ich damals "C programmieren von Anfang an" - 
Rechnerarchitekturen hatte ich allerdings nie im Studium und nie ein 
dediziertes Buch, d. h. müsste ich selbst recherchieren.
Für den Anfang sollten die Suchbegriffe Von-Neumann-Architektur und 
Harvard-Architektur allerdings mal ausreichen. Einfach mal die 
Wikipedia-Artikel durchlesen für einen Einstieg.

von Falk B. (falk)


Lesenswert?

Peter D. schrieb:
> Mirco G. schrieb:
>> Ich Programmiere in C, ja.
>
> Dann kümmert sich der Compiler doch um alles. Der AVR-GCC legt int als
> 16Bit fest,

Das ist richtig, hat aber mit der Größe eines Zeigers wenig bis gar 
nichts zu tun.

> d.h. Du kannst bis zu 64kB Variablen und 64kWorte Code
> linear adressieren.

Man sollte es anders formulieren. Die Zeiger sind im avr gcc 16 Bit 
breit und können damit 64kB Daten und 128kB (=64K Worte a 16 Bit) 
Programm adressieren. Letzteres ist eine Eigenart des AVRs, welcher den 
Programmspeicher mit 16 Bit Datenbreite anspricht.

> 8Bitter mit Zugriffsrechten sind mir nicht bekannt.

Naja, wenn man pedantisch sein will, kann man die minimalen 
Verriegelungsmechanismen im AVR bzw. ATXmega als solche bezeichnen, z.B. 
wenn der EEPROM geschrieben wird oder der Taktteiler umgeschaltet wird.

von Walter S. (avatar)


Lesenswert?

Toni Tester schrieb:
> Ob die Addition eines Integers mit einem Float so compiliert, hängt
> AFAIR von den Compilersettings ab
nein!


Toni Tester schrieb:
> Korregation: Geht natürlich - allerdings wird der Float in Int gerundet

nein!



> - aber bin schon ewig raus aus der
> Materie.

in der Tat

von Toni Tester (Gast)


Lesenswert?

Walter S. schrieb:
> in der Tat

Und, wo bleibt jetzt die Erklärung des besser Wissenden, die dem TO auch 
weiterhilft? Kommt da noch was?
Bis dato enthält dein Posting nämlich nichts Hilfreiches - ich versuche 
es zumindest.

von Dirk B. (dirkb2)


Lesenswert?

Mirco G. schrieb:
> Copy-Paste aus dem Buch gemacht und der Compiler sagt trd nein.

Was sagt der genau?

> Hier der Code den ich getestet habe:

Du hast das aber in eine Funktion verpackt? (main ist auch eine 
Funktion)

von Mirco G. (mirco432)


Lesenswert?

Dirk B. schrieb:
> Du hast das aber in eine Funktion verpackt? (main ist auch eine
> Funktion)

Nein hatte ich nicht wenn ich es in main packe funktioniert es. Jetzt 
stehe ich natürlich ultra blöd da.... Sry. Aber war in keinem Buch so 
explizit aufgeführt das es in eine Funktion muss.




Die Anzeige das ich einen Pointer habe (int *pi) kann ich ja in oder 
außerhalb einer Funktion machen.

Warum kann ich Zuweisung nur innerhalb einer Funktion machen?

Weil erst durch den Linker am Ende des Buildvorgangs (Erzeugung des 
Maschinencodes) die Adresse bzw. der Speicherplatz für Funktionen und 
Variablen festgelegt wird?

Ich kann natürlich erst die Adresse einem Pointer zuweisen wenn eine 
Adresse für eine Variable festgelegt wurde.

Macht das Sinn? :D

von Dirk B. (dirkb2)


Lesenswert?

Mirco G. schrieb:
> Sry. Aber war in keinem Buch so
> explizit aufgeführt das es in eine Funktion muss.

Einschränkung: In keinem Buch, das du gelesen hast

> Die Anzeige das ich einen Pointer habe (int *pi) kann ich ja in oder
> außerhalb einer Funktion machen.

Das ist eine Definition.
Außerhalb einer Funktion werden globale Variablen erzeugt.

> Warum kann ich Zuweisung nur innerhalb einer Funktion machen?

Weil das so in C definiert ist.
Hast du schon mal eine Initialisierung probiert?
1
int x; 
2
int *pi = &x;

Aber globale Variablen sollte man soweit es geht vermeiden.

> Ich kann natürlich erst die Adresse einem Pointer zuweisen wenn eine
> Adresse für eine Variable festgelegt wurde.

Ja.

von Thomas G. (thgauweiler)


Lesenswert?

mag ja nur trivial sein, aber...

> *pf = *pi + 0.5

da fehlt das Semikolon.

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.