Gast
#4832835
Wie kann ich ein ARRAY an eine feste Adresse legen? Zum Programmieren verwende ich ATMEL Studio 7. So einfach geht es leider nicht:
1 | |
|
Anzeige
|
AVR-GCC: ARRAY an eine feste RAM-Adresse legen
Gast
#4832835
Wie kann ich ein ARRAY an eine feste Adresse legen? Zum Programmieren verwende ich ATMEL Studio 7. So einfach geht es leider nicht:
Was willste denn damit bezwecken? Ansonsten das Array einer LInkerscript Section zuweisen und diese Secteion im LInkerscript fest platzieren.
Gast
#4832844
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?
Gast
#4832845
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'; 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. Also ich hab jetzt immernoch nicht lesen können warum da jetzt das Array genau an eine feste Adresse muss.
Gast
#4832852
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?
Gast
#4832862
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 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? 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 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 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 Upps, hatte nur den ersten Link kopiert... Ändert aber nichts daran, dass es nichts gibt um es an eine absolute Adresse zu packen.
Gast
#4833039
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... 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 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...
Gast
#4833513
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!! 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. 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 ...
Gast
#4833584
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) 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.
Gast
#4833604
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 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. 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.
Gast
#4833755
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. 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.
Gast
#4833937
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.
Gast
#4833956
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. 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 :-)
Gast
#5102524
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. 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 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. 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!
Gast
#5102549
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... 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.
Gast
#5102557
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. 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.
Gast
#5102581
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
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! 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 >
> 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. 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.
Gast
#5102622
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... 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?
Gast
#5102661
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. 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.
Gast
#5102703
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.
Ob das Sinn macht, kommt wieder auf deinen use-case an. zer0 schrieb: > Das Symbol zu einem Offset wirst du so NICHT finden. Aber man kann die > Addresse zu einem Symbol berechnen. >
> 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.
Gast
#5102858
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. 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... so sollte das gehen:
Harry L. schrieb: > so sollte das gehen: Nope! Harry L. schrieb: > for(i=0; i==ARRAY_SIZE; i++) So laeuft das doch gar nicht.
Harry L. schrieb: > my_fucking_data_t *foo = 0x1234; // Memory-Adress 0x1234
Muesste so sein:
Harry L. schrieb: > foo[i] = 42; // the answer of all your questions :-D
Muesste so sein:
Darueber hinaus ist das aber trotzdem kacke, denn:
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. 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. Der implizite Teil der Ausgangsfrage "..., und zwar so, daß das auch funktioniert", ist dir halt entgangen. Oliver 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.
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. 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 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 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 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....
Gast
#6389398
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? 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. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|