Hallo, ich habe ein Array und möchte gern auf dieses in einer ISR
zugreifen. Ich dachte mir die beste Variante ist es einfach einne Zeiger
auf das Array zu setzen und dann hinten in den Eckigen Klammern
vorzugeben was ich gerade bearbeiten möchte. Was mache ich dabei falsch?
Hauptprogramm:
1
constuint16_tarray[10]={xxx,xxx,xxx,xxx,xxx....};
2
uint32_t*volatilezeiger=(uint32_t*)&array;
3
4
.......
5
intmain(void)
6
{
7
// sonstige Funktionen
8
while(1){}
9
}
ISR:
1
//defs
2
externuint32_t*volatilearray;
3
uint32_ttest=0;
4
5
//ISR fkt
6
7
test=zeiger[5];
Bei mir scheint er immer Adressen zu übergeben und nicht deren Inhalte.
Vielleicht gibt es auch bessere Wege?
wenn das array eh global ist, warum dann über den zeiger gehen?
du hast 2 Variabelen mit dem name array, bist du sicher das du und der
compiler weiss wann er welche zu verwenden hat.
depp schrieb:> uint32_t *volatile zeiger = (uint32_t *) &array;
Was soll das?
> uint32_t *volatile zeiger = array;
reicht vollkommen aus.
Warum deklarierst Du in "ISR" array als extern, nicht aber zeiger?
Ich habe mich verschrieben, in der ISR soll es natürlich heißen:
extern uint32_t *volatile zeiger;
Um den Zeiger auf das Array bekannt zu machen. Entschuldige.
Wenn ich auf den Spaß direkt zugreifen könnte wäre das natürlich viel
besser, aber da Zickt er hier rum.
depp schrieb:> Was mache ich dabei falsch?depp schrieb:> const uint16_t array[10] = {xxx,xxx,xxx,xxx,xxx....};> uint32_t *volatile zeiger = (uint32_t *) &array;
'zeiger' ist bei dir ein zeiger auf die Adresse des Zeigers auf 'array'.
Das ganze noch auf ein 32-Bit-Array.
(uint32_t *) -> Ohne hat wohl der Compiler gemeckert? ;-)
Und richtig wäre es wie geschrieben. Um erhlich zu sein habe ich in
zwischen fast alle Varianten durch und das (uint32_t *) habe ich
irgendwo in den dutzenden Seiten die ich auf der Suche nach einer Lösung
durchforstet habe gefunden und einfach mal eingebaut. Es macht aber
scheinbar keinen Unterschied ob es da ist oder nicht. Ich habe es mir
auch schon mal in reinem C geschrieben, da man dort aber einfach ein
"int" nimmt kann man das wohl nicht vergleichen.
Wenn wenigstens nicht dieses dämliche Atollic dauernd abschmieren würde
-.-
Nun ich hatte gehofft, dass mir jemand sagen könnte wie ich jetzt
richtig auf das Array zugreifen kann und mir die 3 Zeilen aufschreibt
oder mir sagt was genau ich ändern muss damit es funktioniert.
So stehts jetzt da::
Hauptprogramm:
1
constuint16_tarray[10]={xxx,xxx,xxx,xxx,xxx....};
2
uint32_t*volatilezeiger=array;
3
4
.......
5
intmain(void)
6
{
7
// sonstige Funktionen
8
while(1){}
9
}
ISR:
1
//defs
2
externuint32_t*volatilezeiger;//ich denke der Fehler liegt hier
Achso, ich dachte ich bräute noch einen weiteren Zeiger auf das Array um
die Elemente richtig auslesen zu können, zumindest hatte ich das bisher
immer gelesen. Das Problem was bleibt ist, dass in der ISR das
bekanntmachen von "array" erwartet wird. Und ich dachte wenn ich das als
eine Art Zeiger behandle dann muss es mit 32Bit angegeben werden, da es
ja auf 32 Bit Adressen verweist, während es bei der ersten Definition
des Array mit 16 Bit werten gefüttert wird, weshalt hier 16Bit
ausgereicht haben.
Was mir jetzt fehlt ist also die Zeile wie ich dieses Array bekannt
macht in der ISR. Ich würde einfach mal lieb gucken und auf Hilfe
dahingehend hoffen.
PS: In Hauptprogramm funktioniert das test=array[n]; natürlich ohne
Probleme.
depp schrieb:> Das Problem was bleibt ist, dass in der ISR das> bekanntmachen von "array" erwartet wird.
Dann verrat's ihr einfach: Schlüsselwort 'extern'
Nun das steht ja schon da, ich denke eher, dass meine Reihenfolge
irgenwie nicht stimmt.
extern uint32_t *volatile array;
auch schon probiert mit
extern uint16_t *volatile array;
depp schrieb:> Und ich dachte wenn ich das als> eine Art Zeiger behandle dann muss es mit 32Bit angegeben werden, da es> ja auf 32 Bit Adressen verweist
Ein Zeiger zeigt doch nicht auf 32-Bit-Adressen (Gut, kann er natürlich,
wenn man's von ihm verlangt.), der zeigt auf das was, man an dieser
Adresse definiert hat! Wie lang die Adresse ist, wo jetzt wieder der
Zeiger gespeichert wird, ist dabei egal.
Ja er zeit auf den Wert, ich dachte er müsste dazu in sich die Adresse
aufnehmen in der der Wert gespeichert ist. Egal, das Problem bleibt. Bei
mir schreibt er die Adresse anstelle des Wertes in die test Variable und
auf spielchen wie ein extra "*" lässt er sich nicht ein.
Vielleicht hab ich irgenwas vergessen oder wir haben irgendwo aneinander
vorbei geredet, kannst du bitte mal die 3 Zeilen aufschreiben wie du es
lösen würdest, es sollte ja reichen:
#######################
Hauptprog:
volatile const uint16_t array[y] = {xxxxx, xx ,xxxx};
ISR:
//Hier muss es noch bekannt gemacht werden und ich weiß nicht wie. Etwa
so?:
extern volatile uint16_t *array;
test = array[y]
############################################
wenn ich das Array als 32 Bit bekannt geben bekomme ich wie gesagt meine
erste Adresse des Array ausgegeben.
Perfekt danke, in der Kombination funktioniert es:
#######################
Hauptprog:
const uint16_t array[y] = {xxxxx, xx ,xxxx};
ISR:
//Hier muss es noch bekannt gemacht werden und ich weiß nicht wie. Etwa
so?:
extern const uint16_t array[];
test = array[y]
############################################
Vielen Dank, da hätte ich noch Jahrelang suchen können. Findet man dazu
eigentlich was brauchbares, scheinbar funktioniert standard C hier nicht
wirklich.
Wie waere es, wenn du testbaren Code und eine verstaendliche
Fehlermeldung posten wuerdest? Ausserdem wuerde es helfen, wenn du
aufhoerst wild rumzuprobieren, anfaengst ein C-Buch zu lesen und die
Compiler-Warnungen beachtest. Eigentlich machst du Alles falsch, was
schon 1000 Andere vor dir falsch gemacht haben.
depp schrieb:> scheinbar funktioniert standard C hier nicht wirklich.
Das ist ganz normaler Standard. Woher soll in der Datei die Variable
sonst bekannt sein.
@Peter Stegemann
was genau hat dir denn an meinem Code nicht genügt? Ich denke es ist
besser wenn man die wesentlichen Dinge postet und nicht noch
irgendwelche Interrupt und Timer Einstellungen. Das bringt dir nämlich
am Ende auch nichts wenn du nicht den gleichen Controller wie ich hast.
Das Fehlerbild hatte ich auch genannt und zwar hat er damals auf die
Adresse und nicht auf den Inhalt zugegriffen. Des weiteren habe ich mir
hier zwei C-Bücher genommen in denen es nicht so erklärt war und ich
konnte das auch keiner Internetseite entnehmen, eventuell habe ich auch
daran vorbei gelesen, weil ich einen teilweise falschen Ansatz hatte.
Ich bin einfach froh, dass Besserwisser eine gute Idee bzw. einfach
Ahnung hat und es jetzt funktioniert.
Wenn du aber bessere Vorschläge haben solltes, dann höre ich dir gern
zu.
depp schrieb:> was genau hat dir denn an meinem Code nicht genügt? Ich denke es ist> besser wenn man die wesentlichen Dinge postet
Nicht ganz:
Das, was du an Code gepostet hast, war zwar schon ein bisschen
Kauderwelsch. Aber mit dem Code (Programmlauf) an sich hat der Fehler
nichts zu tun. Der Fehler war, die ordentliche Aufteilung der
Deklarationen. Natürlich am Besten, in *.h und *.c. Die Stelle, wo ein
Fehler auftritt ist oft nicht die Stelle, wo der Fehler produziert wird!
Ich habe doch sogar selbst mehrfach darauf hin gewiesen wo mein Fehler
wahrscheinlich liegt, eben bei der Deklaration in der ISR.
Siehe:
extern uint32_t *volatile zeiger; //ich denke der Fehler liegt hier
depp schrieb:> extern uint32_t *volatile zeiger; //ich denke der Fehler liegt hier
mir müssen aber wissen wo das steht, schreibe bitte zu jeden
codeabschnitt dazu in welcher dabei er sich befindent. auch wichtig sind
welche datei von welcher includiert wird.
Einfach den 'Fehler mal auslagern' in ein völlig neues (sehr kurzes)
Programm. Die Dateien und Deklarationen so miteinander verknüpfen, wie
man es in dem anderen Projekt gemacht hat. Dann kann jemand anderes
sofort sagen: Das, das und das muss geändert werden, damit es läuft.
Weil er's auf seinem eigenen Rechner nachvollziehen konnte.
Apropos 'Dateien und Deklarationen so miteinander verknüpfen, wie man es
in dem anderen Projekt gemacht hat':
Meistens ist richtig: 'Wie man denkt, dass man es gemacht hat!' Und man
findet den Fehler sofort ganz leicht selbst.
steht alles im 10. Post. o.O nun egal, ich denke es ist besser dieses
Thema nicht weiter in die Länge zu ziehen, es sei denn es kommen noch
neue Erkenntnisse hinzu, vielleicht brauchts ja mal jemand, dann sollte
er sich nicht hier durchwühlen müssen.
Gruß: der Depp ;-)
depp schrieb:> steht alles im 10. Post. o.O nun egal, ich denke es ist besser dieses> Thema nicht weiter in die Länge zu ziehen, es sei denn es kommen noch> neue Erkenntnisse hinzu, vielleicht brauchts ja mal jemand, dann sollte> er sich nicht hier durchwühlen müssen.> Gruß: der Depp ;-)
Naja, solche Sachen wie:
- Hier muss noch...
- sonstige...
- ...
ergänze ich dann, wie ich es für richtig halte. Und Bei mir läuft's dann
auf einmal. Nur kannst du das so möglicherweise nicht verwenden. Da
geht's dann wieder von vorn los. Das Stichwort heißt: 'Compilierbares
Programm'
Wenn die Main und die ISR in der gleichen Datei gewesen wären, dann wär
ein extern fehl am platz. Deshalb Komplett posten. Der Fehler wäre
schneller gefunden worden wenn du auch noch die Errors und Warnungen des
Compilers (per Copy and Paste) mit angehängt hättest.
Hallo,
eines am Rande:
> volatile const uint16_t array[y] = {xxxxx, xx ,xxxx};
volatile
=> hiermit sagt man dem C-Compiler, dass er damit rechnen muss, das sich
der Inhalt einer Speicherstelle jederzeit ändern kann.
Anwendung:
- SpecialFunctionRegister, z.B. Timer-Register
- Variablen, die aus Interrupt heraus beschrieben werden
Der Hintergrund ist, daß der Compiler ansonsten Abfragen der Variable
wegoptimieren kann, weil er nicht damit rechnet, dass sie sich an der
Stelle "ohne sein Zutun" ändern kann.
const
=> die Variable darf nicht überschrieben werden (typischerweise ROM)
Volatile und const schließen sich insofern aus.
Bitte noch eine Sache beachten:
Vorsicht mit Casts! Wenn der Compiler warnt, dass ein Typ nicht passt,
hat das gute Gründe! Wenn man sauber programmiert, gibt braucht man
Casts nur in Ausnahmefällen.
Beispiel:
uint32_t *volatile zeiger = (uint32_t *) &array;
Hier hattest Du einen groben Fehler gemacht, aber durch den Cast hast Du
den Compiler überzeugt, daß Du weißt, was Du tust.
=> Warnung immer ernst nehmen, auch wenn sie auf den ersten Blick
sinnlos erscheinen!
depp schrieb:> Nun das steht ja schon da,
Nein, das steht nicht da.
Lies es von unseren Lippen ab:
Du brauchst keine extra Pointer Variable.
Ja, es ist wirklich so einfach
main.c
******
Fertig. Es ist wirklich ganz einfach.
In einer Datei definierst du eine Variable. In allen anderen Dateien
deklarierst du diese Variable nur noch, in dem du ein 'extern' davor
stellst und ansonsten den Datentyp genau gleich lässt und alle
Initialisierungen entfernst.
Und das volatile brauchst du, damit der Compiler weiß, dass er auf
diesem Array nicht optimieren darf. Wird er wahrscheinlich sowieso nicht
können, aber nur für den Fall.
http://www.mikrocontroller.net/articles/FAQ#Globale_Variablen_.C3.BCber_mehrere_Dateien
Karl Heinz Buchegger schrieb:> Und das volatile brauchst du, damit der Compiler weiß, dass er auf> diesem Array nicht optimieren darf. Wird er wahrscheinlich sowieso nicht> können, aber nur für den Fall.
Da das Array aber eigentlich 'const' ist (zumindest war es das im ersten
Post), ist hier das 'volatile' eher fehl am Platz und der Compiler darf
eigentlich so viel optimieren wie er will und kann.
Also eher:
main.c
******
@Karl Heinz
Antwortest du immer so merkwürdig auf Probleme die schon längst gelöst
sind? Im übrigen empfehle ich dir die Beiträge alle zu lesen und zu
verstehen bevor du antwortest, es ging nämlich um das Fehlerbild und den
bisher verwendeten Code welche im 10. Post stehen, es war nie die Rede
davon dass der Code dort fehlerfrei ist.
depp2 schrieb:> @Karl Heinz> Antwortest du immer so merkwürdig auf Probleme die schon längst gelöst> sind?
Im Gegensatz zu manch anderen hier antwortet Karl Heinz korrekt,
ausführlich und didaktisch wertvoll. Er erklärt auch die Gründe, warum
das so ist, was er da schildert.
depp2 schrieb:> @Karl Heinz> Antwortest du immer so merkwürdig auf Probleme die schon längst gelöst> sind? Im übrigen empfehle ich dir die Beiträge alle zu lesen und zu> verstehen bevor du antwortest, es ging nämlich um das Fehlerbild und den> bisher verwendeten Code welche im 10. Post stehen, es war nie die Rede> davon dass der Code dort fehlerfrei ist.
Du hast NIEMALS geschrieben, dass Deine main() und Deine ISR() in ZWEI
VERSCHIEDENEN Dateien stehen und deshalb überhaupt eine
extern-Deklaration notwendig ist.
GENAU DAS hat Karl Heinz erkannt, wo andere rumrätseln mussten, weil Du
diese wichtige Info (absichtlich?) unterdrückt hast.
Nomen est Omen.
Auch wenns gerade schwer fällt und ich erst mal eine Runde um den PC
gehen musste, ich spare mir eine treffende Antwort, insbesondere auf den
letzten .....räudigen "Kommentar" von Frank M.
Sollte das wirklich gutherzig gemeint gewesen sein, dann entschuldige
Karl Heinz. Das Problem wurde trotzdem soweit ich sehen kann oben im
Post 22 oder so schon richtig in Übereinstimmung mit dem Kommentar von
"..." gelöst.
depp2 schrieb:> Sollte das wirklich gutherzig gemeint gewesen sein, dann entschuldige> Karl Heinz. Das Problem wurde trotzdem soweit ich sehen kann oben im> Post 22 oder so schon richtig in Übereinstimmung mit dem Kommentar von> "..." gelöst.
Du denkst nur an Dich und Deinen armseligen Code. Karl Heinz beantwortet
auch spezielle Fragen meist so allgemeingültig, dass nicht nur der TO
(also DU), sondern auch die anderen Leser diese Forums etwas von der
Lösung haben.
Ausserdem muss Deine konkrete Lösung in "Post 22" nicht unbedingt die
allgemein richtige Lösung sein. Sie mag für Dein konkretes Problem mehr
oder minder gut passen, aber löst Deine Frage nicht allgemeingültig.
Denk einfach mal etwas globaler, dann kannst auch Du mit Antworten von
Karl Heinz etwas anfangen: nämlich die Lösung VERSTEHEN und nicht nur
dumm abtippen.
Auweia depp2 !
Ich befürchte dass es eher umgekehrt laufen wird und in Zukunft Dich
niemand in diesem Forum beachten wird.
Ein Zustand den ich mir nicht wünschen würde da ich ohne dieses Forum
und ohne Beiträge, die die Form und Professionalität von Karl Heinz
Beiträgen haben, NICHTS (was Mikrocontroller und C betrifft) auf die
Kette kriegen würde!
Denk mal drüber nach!
Anmerkung:
Beleidigungen haben hier nichts verloren.
Den entsprechenden Beitrag von "depp" habe ich deswegen entsorgt.
Wenn Du Dir nicht helfen lassen willst, dann frag' hier verdammt noch
mal nicht nach Hilfe.
mikrocontroller.net vom Allerfeinsten...
Wenn euch eine unzureichende Fragestellung stört, warum antwortet ihr
denn dann überhaupt?
Wenn jemand nicht im Bilde ist, was das Problem ist, dann mag man es ihm
vllt. vergeben, dass er nicht sofort alles erwähnt, was er für
"Umgebungsbedingungen" hat (Stichwort Headerdatei). Der TE wird auch
gedacht haben, dass es nicht wichtig ist, dass er beim Coden Kaffee
getrunken hat, darum hat er es auch nicht erwähnt.
Zugegeben, manche Fragen lassen mir auch die Haare zu Berge stehen. Aber
tief durchatmen hilft da manchmal.
Wir haben alle klein angefangen, auch wenn manche das heute nicht mehr
wahr haben wollen...
Volker
Volker G. schrieb:> Wir haben alle klein angefangen, auch wenn manche das heute nicht mehr> wahr haben wollen...
Das ist richtig. Trotzdem kommen hier manchmal "lösungsgeile" Leute
vorbei, die nichts verstehen wollen, sondern nur schnell-schnell die
konkrete Lösung für ihr konkretes Problem haben wollen... und dann
entweder direkt wieder verschwinden oder weitere (hilfreiche!) Antworten
einfach nur noch lapidar-frech mit "was mühst Du Dich für mich ab, ich
hab doch längst die Lösung!!!" kommentieren...
Das Dumme ist nur: ohne Willen zum Verständnis kommen sie einen Tag
später mit einer ähnlichen Frage wieder an, diesmal nicht für die
Variable array[], sondern dann für die Variable xyz. Und dann geht das
Spielchen wieder los.
Ich halte so ein Verhalten einfach nur für ignorant und unangemessen. Es
ist für jeden hier ein Privileg (oder auch ein Geschenk), etwas
schreiben zu dürfen. Diesem Privileg - und auch dem geneigten Leser -
sollte man den zugehörigen Respekt erweisen.
P.S.
Als ich mich vor ein paar Jahren in Mikrocontroller eingearbeitet habe,
habe ich hier erstmal für viele Monate still mitgelesen und alles, was
hier interessantes (weil mikrocontroller-spezifisches) "vorbeigelaufen"
ist, wissbegierig in mich aufgesogen. Dabei lernt man viel effektiver,
gerade die Hürden, Klippen und Fallen, in die man bei µCs tappen könnte,
zu meiden. Wer hier erstmal ein paar Wochen mitliest, bevor er hart
einsteigt, würde niemals das CKDIV8-Fuse- oder JTAG-Abschalt-Problem
haben, nämlich weil es alle naselang hier abgehandelt wird.
Rufus Τ. Firefly schrieb:> Den entsprechenden Beitrag von "depp" habe ich deswegen entsorgt.
Schade, dass ich ihn nicht mehr lesen konnte, ich hätte mich bestimmt
köstlichst amüsiert ;-)
Volker G. schrieb:> Wir haben alle klein angefangen, auch wenn manche das heute nicht mehr wahr
haben wollen...
Wir haben uns aber nicht alle dabei daneben benommen.
(Jetzt erst gesehen, wohin sich das entwickelt hat)
OK, depp2, wenn du noch mitliest. Anhand der IP Adresse kann ich sehen,
dass du der Original-Fragesteller bist.
Dann erklär doch bitte mal ganz konkret, was denn eigentlich hier drann
in main.c
*********
1
volatileconstuint16_tarray[y]={xxxxx,xx,xxxx};
im File mit der ISR
*******************
1
externvolatileuint16_t*array;
falsch ist. Wenns geht sehr ausführlich bis runter auf die Byte Ebene im
Speicher.
Immerhin stand dieses von dir noch ein paar Postings über meinem im
Thread und soweit ich sehen kann, ist auf das dieses Problem, was da in
diesem Fall eigentlich passiert niemand eingegangen. Du bist zwar auf
die richtige Lösung gekommen, aber einigen Kommentaren von dir kann ich
entnehmen, dass du nicht so recht weißt warum sie richtig ist und diese
hier falsch.
Ich höre.
Dann werden wir nämlich ganz schnell sehen, ob deine eigene Medizin bei
dir gewirkt hat
> Im übrigen empfehle ich dir die Beiträge alle zu lesen und zu> verstehen bevor du antwortest, es ging nämlich um das Fehlerbild> und den bisher verwendeten Code
VOn dir hab ich eigentlich nur Meldungen gesehen, wie dämlich doch der
Compiler wäre, wie der Standard da versagt, etc, etc. Das ganze garniert
mit Codeveränderungen, die zeigen, dass du eigentlich nicht wirklich
verstanden hast, was hier alles an Problemkreisen vorliegt.
Aber irgendwie was hilfreiches (ausser falsch eingetippten Code) hab ich
da von dir nicht bemerkt.
Edit: Und denk nicht, dass diese jetzt aufgeworfene Fragestellung nicht
wichtig wäre. Wenn du sie beantworten kannst und genau im Speicher
aufzeigen kannst, was da eigentlich passiert, dann hast du etwas sehr
sehr fundamental Wesentliches im Zusammenhang von Arrays und Pointern
verstanden. ALs Antwort würde mir auch eventuell ein einziger Satz
genügen, wenn es denn der Richtige ist (er besteht aus 5 Wörtern).
Edit 2: Und keine Sorge. Ich kann aus deiner originalen Fragestellung
und dem wie du deinen Code in diesem Thread im Laufe der Zeit verändert
und entwickelt hast, noch mindestens 5 andere Fragestellungen
herausextrahieren, die im Zusammenhang und im Verständnis von C nicht
ganz unwesentlich sind.