Forum: Mikrocontroller und Digitale Elektronik Dynamisches Array (mit calloc() und realloc()) löst BusFault aus. Wieso?


von Moe E. (moe_espunkt)


Lesenswert?

Hallo Zusammen,

ich versuche nun schon seit einiger Zeit ein dynamisches Array zu 
realisieren.
Folgendes Problem:

Ich habe ein Array mit 32Bit und möchte nun Bitstuffs hinzufügen, also 
wenn 5 mal eine Eins kommt dann muss das nächste Bit eine Null sein 
(also ....111110....). Dadurch ändert sich auch die Arraylänge: bei 
bspw. 3 Bitstuffs hat das Array ja dann 32+3 Felder. Eigentlich kein 
Problem, wenn man es mit calloc() und realloc() realisiert. Aber seit 
dem calloc() und realloc() in meinem C-Code drin habe, löst der 
Controller (nach ca. 10-20 Sekunden) einen BusFault-Interrupt aus! Das 
hat der Controller zuvor nie gemacht! Die Funktion "bit_stuffing()" wird 
zyklisch aufgerufen. Die ersten Aufrufe Funktionen und die Bitstuffs 
werden erfolgreich in das dynamische Array eingefügt aber irgendwann , 
wenn die Funktion "bit_stuffing()" oft genug aufgerufen wird, dann wird 
wieder ein BusFault-Interrupt ausgelöst.

Meine Frage ist nun:
Sowie ich im folgenden Code die Befehle calloc() und realloc() 
verwenden, kann es da zu internen Problemem kommen? Ich habe nämlich die 
Vermutung, dass ich "Adress-Konflikte" erzeuge. Leider kenne ich mich 
nicht mit Assembler aus, sonst hätte ich da mal geschaut...
1
// ----------------------------GLOBALE VARIABLEN-----------------------------------------//
2
int   count = 0,stuffs=0;
3
ULONG nutzdaten[32]={0,0,1,0,1,1......viele Bits......,1,1,1,0,1,1}; //TESTWERTE (NUTZDATEN ÄNDERN SICH STÄNDIG!)
4
ULONG *nutzdaten_bit_stuffing//dynamisches Array
5
// ----------------------------------------------------------------------------------------//
6
7
void bit_stuffing(void) //WIRD ZYKLISCH AUFGERUFEN !!!!
8
{
9
  static int first_passing = 1;
10
  
11
  int i=0,k=0,l=0;
12
  stuffs=0;
13
  
14
  //--------------------------ANZAHL DER BITSTUFFS ERMITTELN-------------------------//
15
  for(i=0;i<32;i++)
16
  {
17
    if nutzdaten[i]==1)
18
    {count++;}
19
    else
20
    {count=0;}
21
    
22
    if(count==5)
23
    {
24
      stuffs++;
25
      count=0;
26
    }  
27
  } 
28
    count=0;
29
    printf("\nAnzahl der Bitstuffs:%d",stuffs);
30
 //-----------------------------------------------------------------------------------//
31
  
32
 
33
//-----------------------------DYNAMISCHES ARRAY ANLEGEN BZW. GRÖßE VERÄNDERN-----------------//
34
    if(first_passing == 1)
35
    { //dynamisches Array festlegen (größe ist abhängig von der Anzahl der Stuffs)
36
      nutzdaten_bit_stuffing= calloc((32+stuffs),sizeof(unsigned long)); 
37
      first_passing = 0;
38
    }
39
    else
40
    { //größe des Arrays ändern, wenn sich Anzahl der Stuffs ändert
41
      nutzdaten_bit_stuffing= realloc(nutzdaten_bit_stuffing,(32+stuffs)*sizeof(unsigned long)); 
42
    }
43
//---------------------------------------------------------------------------------------------//
44
    
45
  
46
    for(i=0;i<32;i++)
47
    {nutzdaten_bit_stuffing[i]=nutzdaten[i];} //TESTWERTE DEM DYNAMISCHEN ARRAY ZUWEISEN
48
49
//-------------------------------------------------BITSTUFFS EINFÜGEN--------------------------------//  
50
    for(i=0;i<(32+stuffs);i++)
51
    {
52
         if(nutzdaten_bit_stuffing[i]==1)
53
            {count++;}        
54
         else
55
            {count=0;}     
56
         
57
         if(count==5)
58
         {
59
            count=0;
60
61
            for(k=(31+bs_merker);k>i;k--)
62
            {nutzdaten_bit_stuffing[k+1] = nutzdaten_bit_stuffing[k];} //OBJEKTE IM ARRAY NACH RECHTS VERSCHIEBEN
63
            
64
            nutzdaten_bit_stuffing[k+1]=0;//EIN BITSTUFF EINFÜGEN
65
            i++;
66
            bs_merker++;
67
         } 
68
    }
69
 //-------------------------------------------------------------------------------------------------//  
70
}

Der Controller ist ein ARM Cortex M3.

Ich bedanke mich recht herzlich für eure Hilfe und würde mich über 
Antworten sehr freuen.

Viele Grüße

von Peter II (Gast)


Lesenswert?

wie wäre es mit einer Fehlerbehandlung?

was ist wenn calloc oder realloc kein Speicher mehr rausgibt?

außerdem ist es so extrem ungünstig wie du es machst. Weil du damit der 
Speicher sehr schnell Fragmentiert. Nimmer einfach gleich 30% mehr 
Speicher und spare dir das ständige vergrößern.

auch kannst du dein calloc  gleich durch realloc  ersetzen, das spart 
dir die if abfrage.

von Moe E. (moe_espunkt)


Lesenswert?

Hallo Peter

vielen Dank für deine Antwort.

Peter II schrieb:
> Nimmer einfach gleich 30% mehr Speicher und spare dir das ständige vergrößern.

Du meinst also, ich soll direkt das Array mit mehr Felden deklarieren? 
Also statt 32 Felder direkt bspw. 50? (also soviel , wie ich halt 
maximal brauche)

von Peter II (Gast)


Lesenswert?

Moe Espunkt schrieb:
> Du meinst also, ich soll direkt das Array mit mehr Felden deklarieren?
> Also statt 32 Felder direkt bspw. 50? (also soviel , wie ich halt
> maximal brauche)

ja.

Oder du machst das stuffing direkt beim Senden, dann musst du überhaupt 
nicht alle Daten mehrfach anfassen. Geht leider nur wenn nicht per DMA 
versendet wird.

von Moe E. (moe_espunkt)


Lesenswert?

ich dachte, ich mach es mal auf eine (für einen Anfänger)"elegante" Art 
und Weise und nutze dynamische Arrays. Aber einfach mehr Felder 
deklarieren oder beim Senden erst Stuffen würde es theoretisch auch 
schon tun.

Ich werd' das mal testen und hoffe, dass es funktioniert.

von Stefan (Gast)


Lesenswert?

Erstmal solltest du wohl ehr eine 8bit breite Variable für ein einzelnes 
Bit nehmen. Gleich 32bit für nur 1 bit zu verwenden, ist etwas 
verschwenderisch.
Wenn du es dir leichter machen willst, kannst du in der Doku deines 
Cortex nachsehen, ob er eine Bitbandingbereich für Speicher hat.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Moe Espunkt schrieb:
> Aber einfach mehr Felder deklarieren oder beim Senden erst Stuffen
> würde es theoretisch auch schon tun.
Du brauchst letztlich sowieso genau die maximale Größe. Dann kannst du 
sie dich gleich reservieren...

Und das ganze "Elegante" und "Geräumige" (long = 1 Bit) kannst du auf 
dem PC machen, der hat Gigabyte Speicher. Aber ein M3 ist ein uC, und 
der braucht die geeignete Programmierung, sonst wird er langsam...

: Bearbeitet durch Moderator
von Georg (Gast)


Lesenswert?

Moe Espunkt schrieb:
> Also statt 32 Felder direkt bspw. 50?

Wozu, es wird ja maximal zu je 5 Einsen eine Null eingefügt, also kann 
das Feld maximal auf 6/5 der ursprünglichen Grösse wachsen.

Georg

von Moe E. (moe_espunkt)


Lesenswert?

Georg schrieb:
> Moe Espunkt schrieb:
>> Also statt 32 Felder direkt bspw. 50?
>
> Wozu, es wird ja maximal zu je 5 Einsen eine Null eingefügt, also kann
> das Feld maximal auf 6/5 der ursprünglichen Grösse wachsen.
>
> Georg

Du hast vollkommen recht. die Zahl 50 war jetzt einfach nur so dahin 
gesagt um zu verdeutlichen was gemeint ist. Dass bei 32Bit nur maximal 
nur 6 Bitstuffs entstehen können ist soweit klar.

Übrigens : es funktioniert in dem ich einfach ein größeres Array 
deklariere (also Array[38]).

würde mich zwar trotzdem interessieren wieso die dynamischen Arrays 
solche Probleme machen bzw. was allgemein zu beachten ist aber solange 
es auch anders funktiniert bin ich glücklich !

Danke für eure Hilfe!

von Peter II (Gast)


Lesenswert?

Moe Espunkt schrieb:
> würde mich zwar trotzdem interessieren wieso die dynamischen Arrays
> solche Probleme machen bzw. was allgemein zu beachten ist aber solange
> es auch anders funktiniert bin ich glücklich !

steht doch schon oben, du braucht eine sinnvolle Fehlerbehandlung. Bei 
dynamischen Speicher kann es passieren das keiner mehr da ist, und das 
prüfst du nicht.

von TriHexagon (Gast)


Lesenswert?

Wie schon Peter angesprochen, fehlt die Fehlerbehandlung und dann musst 
du beachten, dass das ein µC und kein PC mit mehreren GHz/GB ist. Also 
verwende geeignete Datentypen um Speicher zu sparen, kein ULONG um nur 
ein mickriges Bit zu speichern! Und dann sollte man auf einem µC immer 
auf einen Heap verzichten. Die dynamische Speicherverwaltung ist ein 
System das sehr viel Performance benötigt. Also am besten alles statisch 
machen, dann rennt der ARM auch schön.

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.