Forum: Mikrocontroller und Digitale Elektronik [ARM] U-Boot: Probleme mit Code-Portierung


von Peter G. (n00b)


Lesenswert?

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
volatile unsigned int golayEncodedSecret[30] = {0x00};
7
8
...
9
10
void func1(void){
11
12
// Do something with golayEncodedSecret
13
14
}
15
16
void func2(void){
17
18
// Do something else with golayEncodedSecret
19
20
}
21
22
int main(){
23
  ...
24
25
  func1();
26
  func2();
27
28
  return 0;
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
volatile unsigned int golayEncodedSecret[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

von Kindergärtner (Gast)


Lesenswert?

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?

von P. E. (philenotfound)


Lesenswert?

Und was spricht gegen ein initiales
1
memset( golayEncodedSecret, 0x00, sizeof(golayEncodedSecret));
?

von Peter G. (n00b)


Lesenswert?

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
volatile unsigned int i,j;
3
4
5
...
6
7
void golayEncode(int bytes[], int counter){
8
  
9
  // Create parity data (+ 12 bits) for every chunk of 12 bits of data
10
  for (i=0; i<12; i++){
11
    aux = 0;
12
    for (j=0; j<12; j++){
13
      aux = aux ^ ( (bytes[0]&y[i])>>j & 0x01);
14
      //printf("\n[D] - Test: aux: %d, bytes[0]: %d, j: %d\n", aux, bytes[0], j);
15
    }
16
    bytes[1] = (bytes[1] << 1) ^ aux;
17
  }
18
  //printf("\t\tc =%03x | %03x\n", bytes[0], bytes[1]);
19
20
  // Fill array with Golay encoded secret
21
  golayEncodedSecret[counter] = bytes[0];
22
  golayEncodedSecret[counter+1] = bytes[1];
23
}

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.

von Peter G. (n00b)


Lesenswert?

Phil E. schrieb:
> Und was spricht gegen ein initiales
>
1
memset( golayEncodedSecret, 0x00, sizeof(golayEncodedSecret));
> ?

Ist dies gute Praxis für jegliche globale Arrays?

von Kindergärtner (Gast)


Lesenswert?

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 (unsigned int i=0; i<12; i++){ 
2
  aux = 0; 
3
  for (unsigned int j=0; j<12; j++){

Phil E. schrieb:
> Und was spricht gegen ein initiales
Dass es nichts mit dem Ziel zu tun hat?

von Kindergärtner (Gast)


Lesenswert?

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.

von Peter G. (n00b)


Lesenswert?

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.

von Kindergärtner (Gast)


Lesenswert?

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.

von Peter G. (n00b)


Lesenswert?

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.

von Kindergärtner (Gast)


Lesenswert?

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.

von P. E. (philenotfound)


Lesenswert?

Peter G. schrieb:
> Phil E. schrieb:
>> Und was spricht gegen ein initiales
>>
1
memset( golayEncodedSecret, 0x00, sizeof(golayEncodedSecret));
>> ?
>
> Ist dies gute Praxis für jegliche globale Arrays?

Ist wahr, hab wohl die Frage nicht aufmerksam genug gelesen, sorry.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.