Forum: Compiler & IDEs AVR-GCC: ARRAY an eine feste RAM-Adresse legen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Jochen (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wie kann ich ein ARRAY an eine feste Adresse legen? Zum Programmieren 
verwende ich ATMEL Studio 7.

So einfach geht es leider nicht:

unsigned char object[maxobject] absolute 0x100;


von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
1 lesenswert
nicht lesenswert
Was willste denn damit bezwecken?

Ansonsten das Array einer LInkerscript Section zuweisen und diese 
Secteion im LInkerscript fest platzieren.

von Jochen (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Mw E. schrieb:
> Was willste denn damit bezwecken?
>
> Ansonsten das Array einer LInkerscript Section zuweisen und diese
> Secteion im LInkerscript fest platzieren.

Kannst du das genauer erklären? Gibt es eine Referenz für das
Atmel Studio 7, wo ich das nachlesen kann?

von R. M. (Gast)


Bewertung
-4 lesenswert
nicht lesenswert
oder Du weist einem Zeiger die Adresse des Array zu:

unsigned char *object;
object=0x100;

dann kannst Du darüber, wie gewohnt drauf zugreifen:

object[12]='H';

von Wilhelm M. (wimalopaan)


Bewertung
3 lesenswert
nicht lesenswert
Was soll sich denn an der Adresse 0x100 befinden? RAM? Oder ein 
Registersatz? Jedenfalls einfach einer Zeigervariablen eine Adresse 
zuweisen ist zu 99,9% falsch.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
2 lesenswert
nicht lesenswert
Also ich hab jetzt immernoch nicht lesen können warum da jetzt das Array 
genau an eine feste Adresse muss.

von Jochen (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sorry, meine Frage ist schlecht formuliert. Vor allem habe ich vergessen 
zu erwähnen, dass das ARRAY eine feste Adresse im SRAM bekommen soll.

Ein Array ist 0x120 Bytes lang. Dieses Array soll an eine feste Adresse 
im SRAM (ATMega328, 0x200 bis 0x31F) gelegt werden. Wie kann ich das mit 
dem Atmel Studio 7 erreichen?

von Stefan (Gast)


Bewertung
-11 lesenswert
nicht lesenswert
das ist mal eine interessante Frag, die mich auch interessieren würde.
Warum eigentlich immer diese blöden Fragen auch dem Wozu!?
Der Grund ist doch völlig wurscht

von Markus F. (mfro)


Bewertung
6 lesenswert
nicht lesenswert
Stefan schrieb:
> Warum eigentlich immer diese blöden Fragen auch dem Wozu!?

Weil die Frage zusammen mit der Tatsache, daß der TO mit den bereits 
gegebenen Antworten offensichtlich nicht so richtig was anzufangen 
wußte, mit recht großer Wahrscheinlichkeit letztendlich auf die 
(einfachere) Frage "wie schieße ich mir am besten selbst ins Knie" 
rausläuft.

Jemanden mit einem "wozu" hiervon abhalten zu wollen, ist doch nett, 
oder?

von Johann L. (gjlayde) Benutzerseite


Bewertung
8 lesenswert
nicht lesenswert
Weil es sich bei solchen "Anforderungen" i.d.R. um einen Disignfehler 
handelt.

Sowas wird ja nur dann gebraucht, wenn man von ausserhalb der 
Anwendung auf den Speicher zugreifen und hart codierte Adressen 
verwenden muss.

Die Frage ist also, warum man solche hart platzierten Objekte braucht, 
und die Frage stellt sich um so mehr, als es keine einfache Möglichkeit 
gibt, das mit GCC + Binutils zu erreichen.

Einen Zeiger mit der gewünschten Adresse zu initialisieren ist 
jedenfalls falsch, denn das legt kein Objekt an, reserviert keinen 
Speicher und initialisiert das Objekt auch nicht.

In eine eigene Section legen und per --section-start die Section 
irgendwohin legen ist auch keine Lösung, da Section möglicherweise mit 
anderes Sections überlappt.

Ergo: Es braucht ein angepasstes Linker Description File, wo man einen 
entsprechenden MEMROY eintrag hinzufügt und die zugehörige 
Output-Section an die gewünschte Adresse legt.  In die Input-Section 
legt man dann das gewünschte Objekt bzw. eine Input-Section, die man dem 
Objektzugewiesen hat.

Dokumentiert ist das in den Binutils, nicht in XX Studio:

http://sourceware.org/binutils/docs-2.27/ld/Scripts.html

: Bearbeitet durch User
von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
1 lesenswert
nicht lesenswert
Markus F und Johann L habens auf den Punkt gebracht.

Es gibt GCC Attribute um eine Variable zu alignen
(zB L1 Tabellen für die MMU oder ARM Exception Vektoren)
aber nicht um diese an eine feste Adresse zu packen.
Warum das wohl so ist? -> Weils keiner braucht und es eher schlechte 
Üraxis ist sowas überhaupt zu benötigen in einem Programm.

Daher meine Frage warum der Threadersteller diese feste Platzierung 
braucht, denn da findet sich dann sicherlich eine bessere/andere Lösung.

Ansonsten ist hier der GNU LInker erklärt und wie man dort Sections 
platziert:
https://www.eecs.umich.edu/courses/eecs373/readings/Linker.pdf

Eine Variable wird dann mit dem GCC Attribut Section einer LInkerscript 
Section zugewiesen:
https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html

von Johann L. (gjlayde) Benutzerseite


Bewertung
4 lesenswert
nicht lesenswert
Mw E. schrieb:
> https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html

Wobei GCC 3.2 von 2002 ist; nach 14 Jahren darf man durchaus mal einen 
Blick in die aktuelle Dokumentation wagen :-)

https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html

: Bearbeitet durch User
von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
0 lesenswert
nicht lesenswert
Upps, hatte nur den ersten Link kopiert...

Ändert aber nichts daran, dass es nichts gibt um es an eine absolute 
Adresse zu packen.

von Nase (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Das kann manchmal trotzdem sinnvoll sein. Vielleicht nicht im RAM, aber 
zumindest im EEPROM.

Spätestens, wenn man per Bootloader z.B. Firmwareupdates einspielen 
kann, wäre es durchaus wünschenswert, wenn der Inhalt des EEPROMs aus C 
heraus immer noch da zu finden ist, wo er vorher war.

Üblicherweise löst man das behelfsmäßig, indem man nur eine einzige 
struct im EEPROM anlegt und innerhalb dieser dann die Daten platziert 
und dafür sorgt, dass kein Padding eingefügt wird. Andernfalls wäres 
nämlich blöd, wenn der Linker bei einem Build die Reihenfolge im EEPROM 
verändert...

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
0 lesenswert
nicht lesenswert
Man muss ja nicht die EEMEM Erweiterung nehmen, sondern kann sich dort 
das Adresslayout selber ausdenken mit den bereitgestellten Funktionen.

http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__eeprom.html

von Johann L. (gjlayde) Benutzerseite


Bewertung
1 lesenswert
nicht lesenswert
Nase schrieb:
> Das kann manchmal trotzdem sinnvoll sein. Vielleicht nicht im RAM, aber
> zumindest im EEPROM.
>
> Spätestens, wenn man per Bootloader z.B. Firmwareupdates einspielen
> kann, wäre es durchaus wünschenswert, wenn der Inhalt des EEPROMs aus C
> heraus immer noch da zu finden ist, wo er vorher war.

Was aber nicht ausreichend ist, denn selbst wenn EEMEM noch da liegt wo 
es vorher lag (was immer der Fall ist, es sei denn man änder 
Linkerscript o.ä.) gibt dir niemand die Zusicherung, dass der Linker 
aller Objekte an die gleichen Adressen lokatiert wie zuvor.

> Üblicherweise löst man das behelfsmäßig, indem man nur eine einzige
> struct im EEPROM anlegt und innerhalb dieser dann die Daten platziert
> und dafür sorgt, dass kein Padding eingefügt wird.

Das ist die einzige robuste Lösung (neben händischem Lokatieren im 
Linkerskript o.ä.)

> Andernfalls wäres nämlich blöd, wenn der Linker bei einem Build
> die Reihenfolge im EEPROM  verändert...

von Stefan (Gast)


Bewertung
-9 lesenswert
nicht lesenswert
was irgendwie die Frage nach wie vor nicht ebantwortet wie üblich in 
diesem Forum!

Vielleicht will ich ja ein Ram Defragmentierungtool scheiben und msus 
daher wissen oder ich möchte es einfach nur so machen das ist doch 
völlig wurscht!!

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
5 lesenswert
nicht lesenswert
Stefan schrieb:
> Vielleicht will ich ja ein Ram Defragmentierungtool scheiben und msus
> daher wissen oder ich möchte es einfach nur so machen das ist doch
> völlig wurscht!!

Der Threadersteller heißt Jochen und nicht Stefan, also willst du hier 
garnichts!

Stefan schrieb:
>was irgendwie die Frage nach wie vor nicht ebantwortet wie üblich in
>diesem Forum!

Lesen verlernt?
Die eigentliche Frage habe ich schon längst beantwortet, geh wieder 
zurück in deine Trollhöhle.

von Wilhelm M. (wimalopaan)


Bewertung
-2 lesenswert
nicht lesenswert
Warum ist das in diesem Forum eigentlich in fast jedem Thread so, dass 
es nach kurzer Zeit mit Beschimpfungen losgeht. Es ist schon 
"einzigartig" hier ...

von Stefan (Gast)


Bewertung
-6 lesenswert
nicht lesenswert
abgesehen davon das es mich ebenfalls interessiert..ist die 
Kommunikation hier wie bereits erwähnt einfach nur genial .-)
Ich kenne kein anderes Forum wo die Menschen dermaßen unsozial 
miteinander kommunizieren, das es hier schon fast wieder witzig ist :-)
Und die meisten hier sind auch noch stolz drauf :-O)

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
2 lesenswert
nicht lesenswert
Also ich will ja mal nicht auf denjenigen zeigen wer hier direkt zu 
Anfang was von "blöden Fragen" geschrieben hat ;)
Schade, dass die Gäste ihre Negativbewertungen nicht sehen.

von Stefan (Gast)


Bewertung
-7 lesenswert
nicht lesenswert
findest Du die Frage den intelligent?
Ist ja auch wurscht, das Thema wurde beantwortet und weitere 
Diskussionen sind hinfällig..
Und mit Deinem Tonfall in dem Post davor sparre ich mir weitere 
Kommentare und verfolge das jetzt auch nicht weiter 
hier..traurig..traurig..sag ich nur

von Wilhelm M. (wimalopaan)


Bewertung
1 lesenswert
nicht lesenswert
Jeder hat mal klein angefangen: deswegen finde ich, dass es keine dummen 
(ernstgemeinten) Fragen gibt!

Das Problem liegt hier m.E. auf beiden Seiten:

- es gibt Fragesteller, die keine Hilfe zur Selbsthilfe wollen, sondern 
eine Lösung.

- es gibt Antworter, die jeder Frage / Rückfrage als Provokation 
empfinden bzw. als Plattform für ihre sehr einseitigen Ansichten.

Beides zeugt von mangelndem Respekt. Der Ton macht die Musik.

Insgesamt ist das schade, denn ich finde schon, dass hier ein Menge 
Sachkenntnis zusammen kommt. Leider werden allerdings wegen des 
Umgangtons viele ihre Konsequenzen ziehen.

von Johann L. (gjlayde) Benutzerseite


Bewertung
2 lesenswert
nicht lesenswert
Vielleicht sollte darauf hingewiesen werden, dass es DIE Lösung nicht 
gibt.  Je nachdem, welcher Lösungsansatz gewählt wird, ist es z.B. nicht 
egal, ob die Adresse am Anfang oder am Ende des RAM liegt oder 
mittendrin.

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> Weil es sich bei solchen "Anforderungen" i.d.R. um einen Disignfehler
> handelt.

Ich hab sowas auch schonmal gebraucht, allerdings nicht auf AVR, sondern 
auf STM32. Sinn der Sache war, daß ich ein großes struct ins Backup-RAM 
legen wollte, um dort Daten über einen Stromausfall hinweg zu sichern. 
Außerdem sollte auch das komplette Backup-RAM genullt werden können, und 
einen RAM-Test wollte ich dafür auch noch haben.

Also einfach einen Pointer auf die Basisadresse zeigen lassen und je 
nach Anwendungsfall (Daten sichern, RAM nullen/testen) geeignet casten, 
fertig. Hätte man natürlich auch mit dem Linkerfile machen können, aber 
weniger Herumgecaste wäre das auch nicht geworden.

von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht lesenswert
Nop schrieb:
> Johann L. schrieb:
>> Weil es sich bei solchen "Anforderungen" i.d.R. um einen Disignfehler
>> handelt.
>
> Ich hab sowas auch schonmal gebraucht, allerdings nicht auf AVR, sondern
> auf STM32. Sinn der Sache war, daß ich ein großes struct ins Backup-RAM
> legen wollte, um dort Daten über einen Stromausfall hinweg zu sichern.
> Außerdem sollte auch das komplette Backup-RAM genullt werden können, und
> einen RAM-Test wollte ich dafür auch noch haben.
>
> Also einfach einen Pointer auf die Basisadresse zeigen lassen und je
> nach Anwendungsfall (Daten sichern, RAM nullen/testen) geeignet casten,
> fertig. Hätte man natürlich auch mit dem Linkerfile machen können, aber
> weniger Herumgecaste wäre das auch nicht geworden.


Es geht eher darum, dass das "Backup-RAM" (SRAM2 / CCRAM?) dann nicht 
mehr vernünftig genutzt werden kann. Legt man für das RAM eigene 
Sections an, so kann man es ohne schlechtes Gewissen auch für .data und 
.bss nutzen.

Portable ist der Pointer Code übrigens auch nicht. Ohne Eintrag in den 
Linker hast du keine globalen Symbole am Anfang und Ende des RAM. Wenn 
jetzt ein anderer Prozessor mit weniger Speicher verwendet wird, dann 
nullt der Pointer ohne Code Anpassung in nicht zugelassene Adressen, 
usw. usf.

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Vincent H. schrieb:

> Es geht eher darum, dass das "Backup-RAM" (SRAM2 / CCRAM?) dann nicht
> mehr vernünftig genutzt werden kann.

Kann es so oder so nicht, weil es nur 4kB sind, die auch noch in einem 
eigenen Adreßblock liegen, also nicht kontinuierlich zum normalen RAM. 
Von den 4kB brauche ich so etwa 3.8kB für Backupzwecke. Da ist also 
ohnehin nichts mehr, was ich noch mit Verlinkung nutzen kann.

Ganz abgesehen davon, daß man das Backup-RAM vor dem Zugriff ohnehin 
erstmal mit Registerbefehlen freischalten muß (und danach wieder 
verriegeln kann), und bei sowas habe ich kein Vertrauen in 
Compiler-Automatismen. Lieber manuell, dann weiß ich, daß es richtig 
gemacht ist.

> Legt man für das RAM eigene
> Sections an, so kann man es ohne schlechtes Gewissen auch für .data und
> .bss nutzen.

Ja, könnte man machen. Für andere Sachen wie das CCM mache ich das auch 
so, weil ich da diverse Variablen reinlege über Variablen-Attribute mit 
den Sections. Das muß man dnn schon ausknobeln, welche Variablen wo noch 
reinpassen, weil das auch nicht kontinuierlich zum normalen SRAM ist Das 
geht aber gut per Linker.

> Portable ist der Pointer Code übrigens auch nicht. Ohne Eintrag in den
> Linker hast du keine globalen Symbole am Anfang und Ende des RAM.

Der Anfang des RAM ist einfach seine Basisadresse, und die nächsten 4kB 
sind eben das RAM.

> Wenn
> jetzt ein anderer Prozessor mit weniger Speicher verwendet wird, dann
> nullt der Pointer ohne Code Anpassung in nicht zugelassene Adressen,

Mit einem anderen Prozessor müßte ich sowieso die unterste Schicht neu 
portieren, und nebst diversen Registeradressen und Bitmasken ist genau 
im Headerfile des Treibers auch die Basisadresse des RAM drin.

Sollten auf dem anderen Prozessor wesentlich weniger als 4kB Backup-RAM 
vorhanden sein, würde das Backup-Feature in der jetztigen Form aus 
Applikationssicht ohnehin nicht mehr funktionieren.

von A. S. (achs)


Bewertung
4 lesenswert
nicht lesenswert
Vincent H. schrieb:
> Portable ist der Pointer Code übrigens auch nicht.

Sind feste RAM-Adressen nie. Daher fand ich das Beispiel völlig OK.

Leider hat sich der UP ja verabschiedet und Stefan jede sachliche 
Diskussion zerschlagen.

Dennoch an den UP: Das "Warum" entscheidet über den pragmatischen Weg.

Wenn das RAM zusätzlich ist und dem Linker z.B. unbekannt, ist der 
Pointer einfach und ausreichend.

Wenn Du den Linker kennst und beherrschst, oder kennenlernen willst, ist 
die Lösung über eine eigene Section sauber und ebenso einfach.

Wenn Du den Linker nicht kennst, und es nur wenige Bytes vorher oder 
nachher gibt, auf die Du verzichten kannst, reicht eine kleine Änderung 
im Linker-Skript-File.

Wenn es nur darum geht, dass zwei unabhängig voneinander kompilierte 
Codes damit arbeiten sollen, gibt es auch vielfältige Lösungen.

von Gad Z. (gad)


Bewertung
-3 lesenswert
nicht lesenswert
Ich weiß der Thread ist schon älter...
Allerdings ist genau die Speicherverwaltung des Compilers der Grund 
warum ich immernoch mit Assembler arbeite.

Ich bräuchte auch so eine feste Speicherzuordnung.
Der Grund ist ganz einfach.
Ich tausche Daten mit dem PC aus.
Dabei schickt momentan der PC die Adresse und Länge und der AVR schickt 
die Werte aus dem Ram von der Adresse zurück.
Das ganze würde ich eventuell noch umstellen und ganze Ram Bereiche per 
DMA an den PC schicken.
Dazu muß aber der PC wissen, welche Daten an welcher Adresse stehen.

Die Lösung mit dem Linker und der Section habe ich gelesen.
Offensichtlich gibt es keine einfachere Lösung.

Aber vielleicht gibt es eine andere Lösung für meine Datenübertragung?
Ich will einfach nur Daten im Ram vom PC aus lesen und schreiben.
Außerdem müssen einige Daten vom Ram zusätzlich im Eeprom gespeichert 
werden damit sie nach Stromausfall nicht verloren gehen.

Jetzt bin ich mal gespannt ob ich konstruktive Kommentare Lesen darf :-)

von zer0 (Gast)


Bewertung
2 lesenswert
nicht lesenswert
Kannst du nicht einfach mit nm/objdump/libbfd oder sowas die Addressen 
der interessanten Symbole abfragen?
Ich würde dem Compiler nur vorschreiben, wo etwas hingepackt wird, wenn 
es gar nicht anders geht. Ansonsten degradiert man sich selbst 
freiwillig dazu, Arbeit zu machen, die der Linker innerhalb von 
Millisekunden wahrscheinlich besser erledigt.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Bewertung
2 lesenswert
nicht lesenswert
Für sowas denkt man sich Protokolle aus (oder nutzt fertige), aber man 
schreibt nicht wild im Speicher des Controllers rum.

Aber so wie die Frage aufgebaut ist -> Trollfrage -> ignorieren

von Gad Z. (gad)


Bewertung
0 lesenswert
nicht lesenswert
Wenn es nur ein paar interessante Symbole wären, dann würde ich es so 
machen.
Es handelt sich aber um über 400 Variablen (ca. 800 Byte) im Ram, die 
zum PC  übertragen werden und ca. 200 Byte die im Eeprom gesichert 
werden.

Dann ist die Abfrage aller Variable eher unsinning.

Was macht der Compiler wenn ich alle Variablen in eine einzige Strutur 
packe?
Liegen die Variablen dann ab der Startadresse der Struktur 
zusammenhängend im RAM?

In dem Fall könnte ich ja die ganze Structur übertragen.

von Gad Z. (gad)


Bewertung
-1 lesenswert
nicht lesenswert
Mw E. schrieb:
> Für sowas denkt man sich Protokolle aus (oder nutzt fertige)

Ich habe ja ein Protokoll für den Datenaustausch.
Danach stellt der PC eine Datenanforderung nach einem fest vorgegeben 
Protokoll mit Informationen welche Daten gelesen / geschrieben werden 
sollen.
Der AVR reagiert darauf und schickt eine Antwort ebenfalls in einem 
festen Protokoll.

> aber man schreibt nicht wild im Speicher des Controllers rum.

Wie soll ich sonst Parameter am PC ändern können ohne im Speicher rum zu 
schreiben?

> Aber so wie die Frage aufgebaut ist -> Trollfrage -> ignorieren

Wer hier der Troll ist frag ich mich auch gerade...
Also tue mir ein gefallen und ignoriere einfach diesen Thread!

von zer0 (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Gad Z. schrieb:
> Mw E. schrieb:
>> Für sowas denkt man sich Protokolle aus (oder nutzt fertige)
...
> Wer hier der Troll ist frag ich mich auch gerade...
> Also tue mir ein gefallen und ignoriere einfach diesen Thread!

Recht hat er in dem Punkte, dass es zweifellos eleganter ist, statt mit 
irgendwelchen Addressen direkt nach benannten Symbolen zu fragen. Ob das 
realisierbar ist, ist natürlich wieder eine andere Frage: kostet ja 
einiges an Speicher...

von Gad Z. (gad)


Bewertung
-1 lesenswert
nicht lesenswert
zer0 schrieb:
> Gad Z. schrieb:
>> Mw E. schrieb:
>>> Für sowas denkt man sich Protokolle aus (oder nutzt fertige)
> ...
>> Wer hier der Troll ist frag ich mich auch gerade...
>> Also tue mir ein gefallen und ignoriere einfach diesen Thread!
>
> Recht hat er in dem Punkte, dass es zweifellos eleganter ist, statt mit
> irgendwelchen Addressen direkt nach benannten Symbolen zu fragen. Ob das
> realisierbar ist, ist natürlich wieder eine andere Frage: kostet ja
> einiges an Speicher...

Klar ist es eleganter mit Symbolen aber bei der Datenmenge wohl kaum 
machbar.
Außerdem lag die Priorität darauf möglichst kurze Protokole zu haben da 
die Daten sehr schnell übertragen werden müssen.
Der AVR hat aber noch ganz andere Sachen zu tun als nur die 
Datenanforderungen vom PC abzuarbeiten.
Also ist es schon aus Performancegründen mit Symbolen nicht machbar, 
ganz abgesehen vom zusätzlichen Speicherbedarf.

von zer0 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Gad Z. schrieb:
> Was macht der Compiler wenn ich alle Variablen in eine einzige Strutur
> packe?
> Liegen die Variablen dann ab der Startadresse der Struktur
> zusammenhängend im RAM?

Das auf jeden Fall, du musst dann nur auf dem PC aufpassen, die selben 
alignment-Regeln, gleich große Datentypen usw. zu verwenden.

von Gad Z. (gad)


Bewertung
-1 lesenswert
nicht lesenswert
zer0 schrieb:
> Das auf jeden Fall, du musst dann nur auf dem PC aufpassen, die selben
> alignment-Regeln, gleich große Datentypen usw. zu verwenden.

Danke für die Antwort.
das klingt ja schonmal gut.
Es ist logisch das der PC die gleichen Reihenfolge und Datentypen haben 
muß.
Aber im PC habe ich ein Programm geschrieben in dem es eine 
Konfigurationsliste gibt wo eben auch die Adressen drin stehen vom 
AVR-RAM.

Ich könnte also jetzt eine Structur im AVR machen mit allen ca. 400 
Symbolen und die Structur dann per DMA direkt an den PC schicken.
Und der PC weiß dann anhand der Konfigurationsliste, welcher Wert an 
welcher Stelle in dem Datenstrom liegt.

Der Schreibzugriff auf den AVR ist zwar so nicht möglich, aber da könnte 
ich mir noch eine art CASE Anweisung schreiben, die nur das angeforderte 
Symbol verändert da der PC immer nur einen Wert ändern darf und nie 
mehrere gleichzeitig.
Außerdem werden die schreibbaren Parameter sowieso noch zusätzlich in 
den Eprom gespeichert, was sowieso nur einzeln geht.

von zer0 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Gad Z. schrieb:
> Ich könnte also jetzt eine Structur im AVR machen mit allen ca. 400
> Symbolen und die Structur dann per DMA direkt an den PC schicken.
> Und der PC weiß dann anhand der Konfigurationsliste, welcher Wert an
> welcher Stelle in dem Datenstrom liegt.

Über die offizielle Definition von DMA will ich jetzt nichts gesagt 
haben, aber: Wenn du einen portablen Header mit der struct schreibst, 
kennt man die Offsets der einzelnen Attribute genau. D.h. man kann 
einfach den empfangenen Speicherblock auf den struct-Datentyp casten und 
die Dinger auslesen. Genau so kann man dann auch bei frei wählbaren 
Schreibaddressen einfach einen einzelnen Wert auf dem Controller per 
Protokoll poken: Man kennt die Basis-Addresse der struct, kennt Offset 
und Größe des Attributes und kennt dann daher auch die Zieladdresse auf 
dem Controller.
Was mich aber stutzig macht, ist, dass du jetzt doch wieder 
zurückruderst:

Gad Z. schrieb:
> Der Schreibzugriff auf den AVR ist zwar so nicht möglich, aber da könnte
> ich mir noch eine art CASE Anweisung schreiben, die nur das angeforderte
> Symbol verändert da der PC immer nur einen Wert ändern darf und nie
> mehrere gleichzeitig.

Wenn du also eine Symboltabelle z.B. der Form
struct Symbol {
 const char* name;
 void *address;
 int16_t size;
} symlist = {
 { "ganze_struct", &daten, sizeof(daten_t) },
 { "ganze_struct.feld1", &daten.feld1, sizeof(whatever_daten_feld_1_is) },
 ...
};
unterbringen kannst und willst (ist ja bei 400 Feldern schon ein wenig 
Arbeit), dann wäre es vermutlich eine ernsthafte Überlegung wert. Wenn 
die Einträge in der Tabelle alphabetisch sortiert sind, sind die per 
binary-search relativ schnell zu durchsuchen (wobei relativ echt 
"relativ" heißt: Im Vergleich zum einfachen Addressen-Poking ist der 
Aufwand trotzdem enorm).
Ich würde aber für so eine Konstruktion einiges an Speicher einplanen. 
Für 'nen ATtiny ist das eher nichts!

von Gad Z. (gad)


Bewertung
-1 lesenswert
nicht lesenswert
Danke für die Antwort.

zer0 schrieb:
> Über die offizielle Definition von DMA will ich jetzt nichts gesagt
> haben, aber: Wenn du einen portablen Header mit der struct schreibst,
> kennt man die Offsets der einzelnen Attribute genau. D.h. man kann
> einfach den empfangenen Speicherblock auf den struct-Datentyp casten und
> die Dinger auslesen. Genau so kann man dann auch bei frei wählbaren
> Schreibaddressen einfach einen einzelnen Wert auf dem Controller per
> Protokoll poken: Man kennt die Basis-Addresse der struct, kennt Offset
> und Größe des Attributes und kennt dann daher auch die Zieladdresse auf
> dem Controller.
> Was mich aber stutzig macht, ist, dass du jetzt doch wieder
> zurückruderst:
Da hast du völlig Recht!
Aber ich rudere nicht zurück sondern es ist einfach von der PC Software 
so vorgegeben, das immer nur ein Symbol geändert werden darf.
Diese Änderung wird dann als Schreibanforderung an den AVR geschickt und 
der schreibt die Daten in den RAM und gleich noch in den Eprom damit sie 
remantent sind.
Danach quittiert der AVR die Schreibanforderung an den PC.
Demzufolge macht es keine Sinn alle zu schreiben wenn nur ein Wert 
geändert wurde.
Außerdem prüfe ich vor jedem Eprom Schreibzugriff ob der Wert im Eprom 
überhaupt geschrieben werden muß. Schließlich haben ja Eproms eine recht 
begrenzte Anzahl an Schreibzyklen.
Wenn ich den Schreibzugriff auch über die Structur mache, dann würde ich 
ja immer alle Symbole überschreiben, was von den Werten her egal wäre 
aber von den Schreibzyklen des Eproms eben nicht.

>
> Wenn du also eine Symboltabelle z.B. der Form
>
> struct Symbol {
>  const char* name;
>  void *address;
>  int16_t size;
> } symlist = {
>  { "ganze_struct", &daten, sizeof(daten_t) },
>  { "ganze_struct.feld1", &daten.feld1, sizeof(whatever_daten_feld_1_is) 
> },
>  ...
> };
> 
> unterbringen kannst und willst (ist ja bei 400 Feldern schon ein wenig
> Arbeit), dann wäre es vermutlich eine ernsthafte Überlegung wert. Wenn
> die Einträge in der Tabelle alphabetisch sortiert sind, sind die per
> binary-search relativ schnell zu durchsuchen (wobei relativ echt
> "relativ" heißt: Im Vergleich zum einfachen Addressen-Poking ist der
> Aufwand trotzdem enorm).
> Ich würde aber für so eine Konstruktion einiges an Speicher einplanen.
> Für 'nen ATtiny ist das eher nichts!

Momentan habe ich einen Mega1284P im Einsatz.
Der hat schon keine Speicherprobleme mehr selbst wenn ich den Code 
aufblasen wurde.
Aber der läuft noch mit Assembler.
ich denke aber darüber nach auf einen XMega umzusteigen unter anderem um 
den DMA zu nutzen für die Datenübertragung und damit dem AVR selber 
etwas mehr Ressourcen zu geben und nicht so viel zu "verschwenden" für 
Datenübertragungen.

von Gad Z. (gad)


Angehängte Dateien:

Bewertung
-1 lesenswert
nicht lesenswert
zer0 schrieb:
> Wenn du also eine Symboltabelle
> unterbringen kannst und willst (ist ja bei 400 Feldern schon ein wenig
> Arbeit), dann wäre es vermutlich eine ernsthafte Überlegung wert.

Die Parametertabelle ist ja in der PC Software und die gibt es ja jetzt 
schon (siehe Anhang).

> Wenn die Einträge in der Tabelle alphabetisch sortiert sind, sind die per
> binary-search relativ schnell zu durchsuchen (wobei relativ echt
> "relativ" heißt: Im Vergleich zum einfachen Addressen-Poking ist der
> Aufwand trotzdem enorm).
Die Auswertung der Daten richtet sich nach verschiedenen Kriterien.
Je nachdem welche Ansicht angewählt ist, werden nur die sichtbaren 
Symbole aktualisiert.
Aber wie gesagt, der Teil ist ja schon fertig.

> Ich würde aber für so eine Konstruktion einiges an Speicher einplanen.
> Für 'nen ATtiny ist das eher nichts!
Ich denke garnichtmal das der Speicherbedarf so viel wäre.
Im Endeffekt ist es eine Case Anweisung für ca. 150 schreibbare Symbole.
Der PC müsste dann bei der Schreibanforderung statt der Adresse eine ID 
schicken und in der Case Anweisung würde ich anhand der ID das 
entsprechende Symbol beschreiben.

von zer0 (Gast)


Bewertung
2 lesenswert
nicht lesenswert
Ja, mach wie du meinst!

Frei wählbare Schreibzugriffe sind natürlich eine klaffende 
Sicherheitslücke sonder gleichen, weil der PC den Controller dann 
einfach völlig kaputt patchen kann. Vor allem, wenn das EEPROM gleich 
mit versaut wird.
Wenn man aber auf den Zug aufspringt braucht man auch ganz schnell noch 
Wertebereichsprüfungen, checks auf logische Stimmigkeit zwischen 
mehreren Werten (was heißt: man muss dann ggf. doch mehrere auf einmal 
Schreiben können) und und und.

Kommt auf den Use-Case und damit auf die konkreten Anforderungen an.
Wenn du mich fragst: "Kann man das und das machen?" antworte ich ja 
zunächst nur, ob das geht oder nicht und unterstelle damit einfach mal, 
dass du dir über die Konsequenzen im Klaren bist.

Freie oder ungeprüft Schreibzugriffe in einen Controller einzubauen, der 
schwere Maschinerie steuert oder sowas, dürfte hart an der Grenze zur 
Fahrlässigkeit liegen...

von Gad Z. (gad)


Bewertung
-1 lesenswert
nicht lesenswert
zer0 schrieb:
> Ja, mach wie du meinst!
>
> Frei wählbare Schreibzugriffe sind natürlich eine klaffende
> Sicherheitslücke sonder gleichen, weil der PC den Controller dann
> einfach völlig kaputt patchen kann. Vor allem, wenn das EEPROM gleich
> mit versaut wird.
Klar kann man damit den Controller bzw dessen Funktionen auch 
abschießen.
Aber es handelt sich hier um ein privates Projekt welches nur ich nutze.
Und wenn der Controller abgeschossen werden würde und totale 
fehlfunktionen hätte, dann würde es allerschlimmstenfalls zu einem 
Getriebeschaden an meinem Go-Kart kommen.

> Wenn man aber auf den Zug aufspringt braucht man auch ganz schnell noch
> Wertebereichsprüfungen, checks auf logische Stimmigkeit zwischen
> mehreren Werten (was heißt: man muss dann ggf. doch mehrere auf einmal
> Schreiben können) und und und.
Werteüberprüfungen auf Gültigkeit sind in der PC Software drin.
Das ergibt sich ja schon aus dem Datentyp und ob es signed oder unsigned 
ist.
Außerdem bediene ja nur ich die Software.


>
> Kommt auf den Use-Case und damit auf die konkreten Anforderungen an.
> Wenn du mich fragst: "Kann man das und das machen?" antworte ich ja
> zunächst nur, ob das geht oder nicht und unterstelle damit einfach mal,
> dass du dir über die Konsequenzen im Klaren bist.
>
> Freie oder ungeprüft Schreibzugriffe in einen Controller einzubauen, der
> schwere Maschinerie steuert oder sowas, dürfte hart an der Grenze zur
> Fahrlässigkeit liegen...

Übrigens kann ich selbst bei einer Siemens Steuerung Parameter vom PC 
aus so verbiegen das die Steuerung nicht mehr funktioniert bzw. 
Servoantriebe zu schwingen beginnen und schlimmstenfalls mechanische 
schäden verursachen können.

Außerdem geht es ja nicht um eine schwere Maschine sondern nur um einen 
Shifter für mein eigenen Go-Kart.
Also was soll die Frage nach der Sicherheit?

von zer0 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Gad Z. schrieb:
> Übrigens kann ich selbst bei einer Siemens Steuerung Parameter vom PC
> aus so verbiegen das die Steuerung nicht mehr funktioniert bzw.
> Servoantriebe zu schwingen beginnen und schlimmstenfalls mechanische
> schäden verursachen können.

Ja, das ist aber DEREN Problem. Ein Geschäftsmann kalkuliert dann ggf. 
eben wie eine Versicherung:
So und so viel Profit durch Einsparung der 50 Cent extra für 
Wertebereichsprüfungen
vs./-
so und so viel Verlust durch Schadenersatzforderungen/Garantie im Falle 
des Falles
=
(JA = +) / (NEIN = -)


Wenn es sowieso niemanden in Gefahr bringt würde ich mit den Offsets 
arbeiten - Wozu die Arbeit, IDs zu mappen?
Aber wie gesagt: Mach, wie du das haben willst oder was es dir an Arbeit 
wert ist.

von Gad Z. (gad)


Bewertung
-1 lesenswert
nicht lesenswert
zer0 schrieb:
> Gad Z. schrieb:
>> Übrigens kann ich selbst bei einer Siemens Steuerung Parameter vom PC
>> aus so verbiegen das die Steuerung nicht mehr funktioniert bzw.
>> Servoantriebe zu schwingen beginnen und schlimmstenfalls mechanische
>> schäden verursachen können.
>
> Ja, das ist aber DEREN Problem. Ein Geschäftsmann kalkuliert dann ggf.
> eben wie eine Versicherung:
> So und so viel Profit durch Einsparung der 50 Cent extra für
> Wertebereichsprüfungen
> vs./-
> so und so viel Verlust durch Schadenersatzforderungen/Garantie im Falle
> des Falles
> =
> (JA = +) / (NEIN = -)
>
Ok wenn man es aus der geschäftlichen ebene sieht...
War aber nicht das Thema.
>
> Wenn es sowieso niemanden in Gefahr bringt würde ich mit den Offsets
> arbeiten - Wozu die Arbeit, IDs zu mappen?
> Aber wie gesagt: Mach, wie du das haben willst oder was es dir an Arbeit
> wert ist.

Wie soll ich es mit Offsets einfacher machen als mit ID's
Der Punkt ist doch das ich einzelne Elemente der Structur ab und zu 
beschreiben will.
Wie soll ich dann das Symbol finden zu einem Offset?

Oder kann man bei GCC direkt auf die Structur + Offset zugreifen?
Wenn ja, wie? Ist doch kein Array.

von zer0 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Gad Z. schrieb:
> zer0 schrieb:
>> Gad Z. schrieb:
>>> Übrigens kann ich selbst bei einer Siemens Steuerung Parameter vom PC
>>> aus so verbiegen das die Steuerung nicht mehr funktioniert bzw.
>>> Servoantriebe zu schwingen beginnen und schlimmstenfalls mechanische
>>> schäden verursachen können.
>>
>> Ja, das ist aber DEREN Problem. Ein Geschäftsmann kalkuliert dann ggf.
>> eben wie eine Versicherung:
>> So und so viel Profit durch Einsparung der 50 Cent extra für
>> Wertebereichsprüfungen
>> vs./-
>> so und so viel Verlust durch Schadenersatzforderungen/Garantie im Falle
>> des Falles
>> =
>> (JA = +) / (NEIN = -)
>>
> Ok wenn man es aus der geschäftlichen ebene sieht...
> War aber nicht das Thema.
>>
>> Wenn es sowieso niemanden in Gefahr bringt würde ich mit den Offsets
>> arbeiten - Wozu die Arbeit, IDs zu mappen?
>> Aber wie gesagt: Mach, wie du das haben willst oder was es dir an Arbeit
>> wert ist.
>
> Wie soll ich es mit Offsets einfacher machen als mit ID's
> Der Punkt ist doch das ich einzelne Elemente der Structur ab und zu
> beschreiben will.
> Wie soll ich dann das Symbol finden zu einem Offset?
> Oder kann man bei GCC direkt auf die Structur + Offset zugreifen?
> Wenn ja, wie? Ist doch kein Array.

Das Symbol zu einem Offset wirst du so NICHT finden. Aber man kann die 
Addresse zu einem Symbol berechnen.
struct Daten {
 float feld1;
 float feld2;
};

/* das hier ist ein pointer, der nur zur address-berechnung verwendet wird.
 0xadd2 ist die Addresse der Struct auf dem Controller. */
Daten* datenOnController = (Daten*)0xadd2;

void * addr = &(datenOnController->feld2);
Ob das Sinn macht, kommt wieder auf deinen use-case an.

von Gad Z. (gad)


Bewertung
-1 lesenswert
nicht lesenswert
zer0 schrieb:
> Das Symbol zu einem Offset wirst du so NICHT finden. Aber man kann die
> Addresse zu einem Symbol berechnen.
>
> struct Daten {
>  float feld1;
>  float feld2;
> };
> 
> /* das hier ist ein pointer, der nur zur address-berechnung verwendet 
> wird.
>  0xadd2 ist die Addresse der Struct auf dem Controller. */
> Daten* datenOnController = (Daten*)0xadd2;
> 
> void * addr = &(datenOnController->feld2);
> 
> Ob das Sinn macht, kommt wieder auf deinen use-case an.

Da hast du aber in deinem ersten Kommentar folgendes dazu geschrieben :

zer0 schrieb:
> Kannst du nicht einfach mit nm/objdump/libbfd oder sowas die Addressen
> der interessanten Symbole abfragen?

Also wozu eine Adresse zu einem Symbol berechnen wenn ich ohnehin den 
Sybolnamen brauche?

Außerdem war ja mein problem das ich die daten vom PC kommend im AVR dem 
richtigen Symbol zuordnen muß um darauf zu schreiben.
In deinem beispiel also das Symbol "feld2"

ich hätte jetzt eben so eine simple Case gemacht, nur eben mit ca 150 
cases...

switch( receive_ID )
{
    case 0x01:
        Daten.feld1 = receive_Value
    case 0x02:
        Daten.feld2 = receive_Value

}

Oder habe ich da was total falsch verstanden?
Muß dazu sagen das ich wenig C-Erfahrung habe :-(
Deshalb frage ich ja hier so blöd um abzuschätzen ob es in C überhaupt 
geht und ob sich der Aufwand lohnt.

von zer0 (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Gad Z. schrieb:
> Also wozu eine Adresse zu einem Symbol berechnen wenn ich ohnehin den
> Sybolnamen brauche?

Ja, wenn du den brauchst auf dem Controller...
Mit objdump kannst du dir einfach zu jeder Variable im Programm die 
Addresse ausgeben lassen. Zusammen mit dem "bliebig Schreiben und 
Lesen"-Protokoll kann man damit also in ganz genereller Weise alles 
mögliche auf dem Ding schreiben und lesen - könnte man in eine generelle 
GUI packen, wo man dann alle Variablen mit aktuellen Werten sieht und 
ändern kann.
Und das OHNE jede Variable einzeln irgendwo aufzuzählen.
Restringierter wird das natürlich mit den festen IDs.
Das sieht vom Prinzip her richtig aus. Kann man so machen.
(Allerdings fehlt ein "break" in den cases, aber das hättest du sicher 
noch bemerkt :)

Ich würde zwar aus unbestimmten Gründen eine Symboltabelle als array im 
Programm präferieren, aber cases funktionieren ganz bestimmt auch.

von Gad Z. (gad)


Bewertung
-1 lesenswert
nicht lesenswert
zer0 schrieb:
> Gad Z. schrieb:
>> Also wozu eine Adresse zu einem Symbol berechnen wenn ich ohnehin den
>> Sybolnamen brauche?
>
> Ja, wenn du den brauchst auf dem Controller...
> Mit objdump kannst du dir einfach zu jeder Variable im Programm die
> Addresse ausgeben lassen. Zusammen mit dem "bliebig Schreiben und
> Lesen"-Protokoll kann man damit also in ganz genereller Weise alles
> mögliche auf dem Ding schreiben und lesen - könnte man in eine generelle
> GUI packen, wo man dann alle Variablen mit aktuellen Werten sieht und
> ändern kann.
> Und das OHNE jede Variable einzeln irgendwo aufzuzählen.

Genau den Symbolnamen brauche ich nicht sondern Zugriff auf Variablen 
mit Hilfe der Adresse.
Aber laut diesem Thread geht das doch bei C nicht weil der Compiler 
selber die Adressverwaltung macht.
Daher die Sache mit der Struktur um wenigstens die Reihenfolge der 
Variablen im Speicher vorgeben zu können.

> Restringierter wird das natürlich mit den festen IDs.
> Das sieht vom Prinzip her richtig aus. Kann man so machen.
> (Allerdings fehlt ein "break" in den cases, aber das hättest du sicher
> noch bemerkt :)
Ja der Break fehlt..... ich war zu faul es richtig zu tippen :-)
Sollte nur als beispiel dienen, aber danke für den Tip.

>
> Ich würde zwar aus unbestimmten Gründen eine Symboltabelle als array im
> Programm präferieren, aber cases funktionieren ganz bestimmt auch.
Sorry aber ich stehe auf dem Schlauch.
Was meinst du mit einer Symboltabelle als Array?
Ein Array hat doch nur ein Symbol und den Arrayindex...

von Harry L. (mysth)


Bewertung
-2 lesenswert
nicht lesenswert
so sollte das gehen:

#include <avr/io.h>

#define ARRAY_SIZE  10

typedef uint8_t my_fucking_data_t[ARRAY_SIZE];

my_fucking_data_t *foo = 0x1234; // Memory-Adress 0x1234

void main(void)
{
uint8_t i;
  for(i=0; i==ARRAY_SIZE; i++)
    foo[i] = 42;  // the answer of all your questions :-D
}


von Kaj G. (Firma: RUB) (bloody)


Bewertung
1 lesenswert
nicht lesenswert
Harry L. schrieb:
> so sollte das gehen:
Nope!

Harry L. schrieb:
> for(i=0; i==ARRAY_SIZE; i++)
So laeuft das doch gar nicht.
for(i = 0; i < ARRAY_SIZE; i++)


Harry L. schrieb:
> my_fucking_data_t *foo = 0x1234; // Memory-Adress 0x1234
Warnung: initialization makes pointer from integer without a cast [-Wint-conversion]
 my_fucking_data_t *foo = 0x1234; // Memory-Adress 0x1234
                          ^~~~~~


Muesste so sein:
my_fucking_data_t *foo = (my_fucking_data_t *)0x1234; // Memory-Adress 0x1234



Harry L. schrieb:
> foo[i] = 42;  // the answer of all your questions :-D
Fehler: assignment to expression with array type
         foo[i] = 42;  // the answer of all your questions :-D
                ^

Muesste so sein:
for(uint8_t i = 0; i < ARRAY_SIZE; i++) {
    (*foo)[i] = 42;  // the answer of all your questions :-D
}



Darueber hinaus ist das aber trotzdem kacke, denn:
my_fucking_data_t *foo = 0x1234;
Hier wird ein Pointer erzeugt, der einfach auf die Speicheradresse 
0x1234 zeigt, ohne das dort ein gueltiges Objekt existiert. Du weisst 
aber gar nicht, was an dieser Speicheradresse liegt, geschweige denn, ob 
diese Adresse (und die nachfolgenden) ueberhaupt frei sind. 
Moeglicherweise waechst einmal der Stack ueber diese Adresse rueber, und 
schon sind alle deine Werte fuer den Eimer. Oder andersrum, du schreibst 
einfach Werte im Stack kaputt.
Damit ist unvorhersehbares Programmverhalten vorprogrammiert.

von Harry L. (mysth)


Bewertung
-2 lesenswert
nicht lesenswert
Kaj G. schrieb:
> Hier wird ein Pointer erzeugt, der einfach auf die Speicheradresse
> 0x1234 zeigt, ohne das dort ein gueltiges Objekt existiert.

Ja natürlich ist sowas bescheuert, aber das war die Ausgangsfrage.
Der Code compiliert bis auf 1 Warnung hier übrigens problemlos.

von Oliver S. (oliverso)


Bewertung
2 lesenswert
nicht lesenswert
Der implizite Teil der Ausgangsfrage "..., und zwar so, daß das auch 
funktioniert", ist dir halt entgangen.

Oliver

von Kaj G. (Firma: RUB) (bloody)


Bewertung
1 lesenswert
nicht lesenswert
Harry L. schrieb:
> Ja natürlich ist sowas bescheuert
Dann poste nicht so einen Muell.

Harry L. schrieb:
> aber das war die Ausgangsfrage.
Nein. Die Frage war:
Wie legt man ein Objekt an eine bestimmte Stelle, und nicht,
wie man einen Zeiger auf eine bestimmte Adresse zeigen laesst.
Es gibt da einen nicht unerheblichen Unterschied, aber was
langweile ich hier mit Details...

Harry L. schrieb:
> Der Code compiliert bis auf 1 Warnung hier übrigens problemlos.
Glaub ich dir nicht.
#include <stdint.h>

#define ARRAY_SIZE  10

typedef uint8_t my_data_t[ARRAY_SIZE];

my_data_t *foo = 0x1234; // Memory-Adress 0x1234

void main(void)
{
    uint8_t i;
    for(i=0; i==ARRAY_SIZE; i++)
        foo[i] = 42;  // the answer of all your questions :-D
}
$ gcc --version
gcc (GCC) 7.1.1 20170630
$ gcc -std=c99 -o main test.c
test.c:7:18: Warnung: Initialisierung erzeugt Zeiger von Ganzzahl ohne Typkonvertierung [-Wint-conversion]
 my_data_t *foo = 0x1234; // Memory-Adress 0x1234
                  ^~~~~~
test.c: In Funktion »main«:
test.c:13:16: Fehler: Zuweisung an Ausdruck von Arraytyp
         foo[i] = 42;  // the answer of all your questions :-D
Und selbst wenn es compilieren sollte (was es nicht tut), beinhaltet 
dein Code immernoch folgende Probleme:

1) Die Laufbedingung der Schleife ist falsch. Die Schleife wird nie 
durchlaufen und wegoptimiert (wenn es denn compilieren wuerde)

2) Die Zuweisung in der Schleife ist falsch (Fehler: Zuweisung an 
Ausdruck von Arraytyp). foo ist ein Pointer auf ein Array, also ein 
Pointer auf einen Pointer. Du vergisst die Dereferenzierung des ersten 
Pointer. Erst wenn du foo dereferenzierst -> (*foo) kannst du mit dem 
Index gueltig darauf zugreifen -> (*foo)[i]

Der AVR-GCC 5.3.0 ist die aelteste Version die ich gerade hier hab, und 
da compiliert das auch schon nicht.

von Harry L. (mysth)


Bewertung
-2 lesenswert
nicht lesenswert
Ausgangsfrage:
Jochen schrieb:
> Wie kann ich ein ARRAY an eine feste Adresse legen? Zum
> Programmieren
> verwende ich ATMEL Studio 7.
>
> So einfach geht es leider nicht:
>
> unsigned char object[maxobject] absolute 0x100;

Oliver S. schrieb:
> Der implizite Teil der Ausgangsfrage "..., und zwar so, daß das auch
> funktioniert", ist dir halt entgangen.

Und was soll das sein?
Ich hab eher den Eindruck, daß du da irgendwas hinein interpretieren 
möchtest, was da nicht steht.....

So, wie ich das gepostet hab, macht das genau das Gewünschte.
Ob das auch sinnvoll ist, steht auf einem ganz anderen Blatt

von Oliver S. (oliverso)


Bewertung
1 lesenswert
nicht lesenswert
Harry L. schrieb:
> So, wie ich das gepostet hab, macht das genau das Gewünschte.

Nein, macht es nicht, weil das Programm damit abstürzen wird. 
Compilerbarkeit ist eine notwendige Bedingung für ein korrekt 
funktionierendes Programm, aber keine hinreichende. Generationen von 
Programmierern haben das inzwischen ausreichend bewiesen...

Du hast den ersten kleinen Teil der Aufgabe gelöst, wie man einem 
pointer eine konstanten Wert zuweist. Den größeren Problemteil der 
Frage, wie man ein Array an eine feste Adresse im SRam eines AVRs (oder 
jedes anderen Mikrocontrollers) legt, so daß das am Ende auch 
funktioniert, hast du weder beantwortet, noch überhaupt verstanden.

Oliver

: Bearbeitet durch User
von Oliver S. (oliverso)


Bewertung
1 lesenswert
nicht lesenswert
Nachtrag:

Wenn das Array am Anfang des SRam liegen darf, dann liefert
http://www.nongnu.org/avr-libc/user-manual/mem_sections.html

den fehlenden Teil der Antwort.

Wenns dagegen irgendwo mittendrinn oder am Ende platziert sein soll, 
dann ist händisches editieren der linkerskripts erforderlich.

Oliver

von Harry L. (mysth)


Bewertung
-2 lesenswert
nicht lesenswert
Oliver S. schrieb:
> Harry L. schrieb:
>> So, wie ich das gepostet hab, macht das genau das Gewünschte.
>
> Nein, macht es nicht, weil das Programm damit abstürzen wird.
> Compilerbarkeit ist eine notwendige Bedingung für ein korrekt
> funktionierendes Programm, aber keine hinreichende. Generationen von
> Programmierern haben das inzwischen ausreichend bewiesen...
>
> Du hast den ersten kleinen Teil der Aufgabe gelöst, wie man einem
> pointer eine konstanten Wert zuweist. Den größeren Problemteil der
> Frage, wie man ein Array an eine feste Adresse im SRam eines AVRs (oder
> jedes anderen Mikrocontrollers) legt, so daß das am Ende auch
> funktioniert, hast du weder beantwortet, noch überhaupt verstanden.
>
> Oliver

Herr im Himmel!
Ich gebs auf!
Natürlich stürzt das ab.
So what....

Die Frage wurde beantwortet.

Ich bin hier raus....

von standardfratze (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Würde auch  gerne wissen wie das funktioniert weil wenn man testen will 
welche Speicherberiech in einem Mikrocontroller eventuell buggy sind 
sollte man ja direkt mal irgendwo in die Hardware schreiben können ohne 
(wie am anfang vom thread) als doofi bezeichnet zu werden.VIelleicht 
gibts in zwischen ne header mit funktion?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
1 lesenswert
nicht lesenswert
standardfratze schrieb:
> wenn man testen will welche Speicherberiech in einem Mikrocontroller
> eventuell buggy sind

… dann nimmt man einen Zeiger, statt irgendeinen uralten Thread 
auszugraben.

Aber wer sagt dir denn dann, dass der Programmspeicher mit dem Programm, 
das den Speicher testen soll, nicht auch "buggy" sein könnte? In aller 
Regel sind solche Tests nur sehr wenig sinnvoll.

: Bearbeitet durch Moderator

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.