Hallo zusammen,
ich bin noch recht neu in der Programmierung für Mikroprozessoren und
stoße auf unerwartete Probleme. Ich bin dabei in den Code des U-Boot
Bootloaders eine erweiterte Funktionalität einzubauen.
Den zusätzlichen Code habe ich auf meinem PC entwickelt und dieser läuft
außerhalb von U-Boot ohne Probleme. Wenn ich diesen jedoch in U-Boot
integriere und ihn auf meinem PandaBoard (OMAP4460 SoC) laufen lasse,
kommt es zu unerwarteten Effekten. Einer dieser Effekte betrifft z.B.
(char) arrays:
Wenn ich sie aus meinem getesten Code so übernehme:
1
#include ....
2
3
...
4
...
5
6
volatileunsignedintgolayEncodedSecret[30]={0x00};
7
8
...
9
10
voidfunc1(void){
11
12
// Do something with golayEncodedSecret
13
14
}
15
16
voidfunc2(void){
17
18
// Do something else with golayEncodedSecret
19
20
}
21
22
intmain(){
23
...
24
25
func1();
26
func2();
27
28
return0;
29
30
}
Dann ist das Array im gesamten Programm komplett leer, selbst wenn ich
es vorher gefüllt bzw. in irgendeiner Weise verarbeitet habe.
Wenn ich es jedoch folgendermaßen deklariere (also mit einem Wert !=
0x00), dann verhält sich das Programm wie gewünscht:
1
volatileunsignedintgolayEncodedSecret[30]={0xaa};
Ich habe ja bereits in der FAQ den Sachverhalt bezüglich volatile
gelesen. Jedoch erscheinen mir noch weitere Effekte, deren Ursprung ich
nicht kenne. Daher "programmiere ich wie im Nebel" und muss immer
umständlich Trial&Error-mäßig debuggen, anstatt mich schon während des
Programmierens an gewisse Regeln zu halten.
Beste Grüße,
Peter
Peter G. schrieb:> Dann ist das Array im gesamten Programm komplett leer,
C-Arrays können niemals "leer" sein. Es stehen immer 30 char's drin.
Und woher weißt du wie das array aussieht?
Kindergärtner schrieb:> C-Arrays können niemals "leer" sein. Es stehen immer 30 char's drin.
Meine Formulierung war wohl etwas falsch: der Inhalt des Arrays ist in
jeder "Zelle des Arrays" 0x00.
> Und woher weißt du wie das array aussieht?
Nun, ich gebe das komplette Array an einigen Stellen mit printf aus,
daher sehe ich, dass dort überall 0x00 drin steht. Weiterhin stimmen
manche Berechnungen nicht, die auf dem Inhalt des Arrays aufbauen.
Noch ein Effekt, der mir gerade aufgefallen ist und vllt. etwas
einfacher zu erklären ist:
1
...
2
volatileunsignedinti,j;
3
4
5
...
6
7
voidgolayEncode(intbytes[],intcounter){
8
9
// Create parity data (+ 12 bits) for every chunk of 12 bits of data
Diese Funktion läuft auf meinem PC ohne Problem. Auf dem PandaBoard wird
j nicht inkrementiert (habe dazu die printf Anweisungen eingebaut um
dies zu überprüfen), sodass der Bootloader in einer Endlosschleife
hängt.
Peter G. schrieb:> Nun, ich gebe das komplette Array an einigen Stellen mit printf aus,> daher sehe ich, dass dort überall 0x00 drin steht
Selbst nach explizitem beschreiben, ja? Sicher dass dieser printf-Code
korrekt ist?
Peter G. schrieb:> volatile unsigned int i,j;> for (i=0; i<12; i++){
WTF?? Du deklarierst Schleifenzähler als globale Variablen mit auch noch
den Namen "i","j"?! Was spricht gegen das klassische
1
for(unsignedinti=0;i<12;i++){
2
aux=0;
3
for(unsignedintj=0;j<12;j++){
Phil E. schrieb:> Und was spricht gegen ein initiales
Dass es nichts mit dem Ziel zu tun hat?
Peter G. schrieb:> Ist dies gute Praxis für jegliche globale Arrays?
Nein, das bringt gar nichts, da globale integer(-Arrays) grundsätzlich
automatisch auf 0 intialisiert werden. Wenn man andere Werte will,
sollte man sie so wie du es schon richtig gemacht hattest,
initialisieren.
Kindergärtner schrieb:> Peter G. schrieb:> Selbst nach explizitem beschreiben, ja? Sicher dass dieser printf-Code> korrekt ist?
Ja, das Array wird definitiv beschrieben und der printf Code scheint mir
auch korrekt.
> WTF?? Du deklarierst Schleifenzähler als globale Variablen mit auch noch> den Namen "i","j"?! Was spricht gegen das klassische for (unsigned int> i=0; i<12; i++){> aux = 0;> for (unsigned int j=0; j<12; j++){
Mir ist bewusst, dass dies kein schöner Code ist, jedoch sollte er doch
trotzdem funktionieren. Und das tut er nicht. Und ich würde gerne die
Mechanismen dahinter verstehen. Natürlich ist es eine Möglichkeit dies
lokal zu machen, allerdings lerne ich dann nicht warum die andere
Variante nicht funktioniert.
Peter G. schrieb:> jedoch sollte er doch> trotzdem funktionieren.
Klar, wenn du absolut sicherstellen kannst, dass i,j nirgendwo im
gesamten Code verändert werden. Und selbst wenn es funktioniert, wäre
es immernoch extrem ineffizient.
Peter G. schrieb:> allerdings lerne ich dann nicht warum die andere> Variante nicht funktioniert.
Weil du vermutlich versehentlich von irgendwo drauf zugreifst, denn
Variablen namens "i" und "j" verwendet man praktisch überall.
Peter G. schrieb:> Ja, das Array wird definitiv beschrieben und der printf Code scheint mir> auch korrekt.
Dann funktioniert ja alles.
Kindergärtner schrieb:> Klar, wenn du absolut sicherstellen kannst, dass i,j nirgendwo im> gesamten Code verändert werden. Und selbst wenn es funktioniert, wäre> es immernoch extrem ineffizient.> Weil du vermutlich versehentlich von irgendwo drauf zugreifst, denn> Variablen namens "i" und "j" verwendet man praktisch überall.
Dann müsste ja der externe Zugriff auf i bzw. j noch innerhalb der for
Schleife passieren und die Variable immer auf 0 zurück setzen. In der
for-Schleife wird i bzw. j nicht inkrementiert und bleibt 0. Das scheint
doch eigenartig selbst wenn von extern darauf zugegriffen wird.
> Peter G. schrieb:>> Ja, das Array wird definitiv beschrieben und der printf Code scheint mir>> auch korrekt.> Dann funktioniert ja alles.
Nein eher nicht, siehe oberen Post. Das Array wird zwischendurch
definitiv beschrieben und der Inhalt ist trotzdem in jeder Zelle 0x00.
Peter G. schrieb:> Dann müsste ja der externe Zugriff auf i bzw. j noch innerhalb der for> Schleife passieren und die Variable immer auf 0 zurück setzen.
ISR's, andere Threads, (indirekte) Funktionsaufrufe...?
Peter G. schrieb:>> Dann funktioniert ja alles.> Nein eher nicht, siehe oberen Post. Das Array wird zwischendurch> definitiv beschrieben und der Inhalt ist trotzdem in jeder Zelle 0x00.
Dann muss es wohl kosmische Strahlung sein, wenn du genau weißt dass
alles (inkl. dem printf) funktioniert...! Es bleiben noch
Speicherfehler, setze mal im Debugger einen Data Watchpoint auf das
Array und schau von wo aus es wieder auf 0 gesetzt wird.