Hallo, ich versuche einen Ringbuffer auf einem Cortex M0 (kl25z board)
zu implementieren, wie er in der angehängten Datei nachzulesen ist.
Bei der Ausführung von malloc, springt der Prozessor aber in den
HardFault_Handler. Woran kann das liegen. Habe im Startup File versucht
die Heapsize einzustellen, hat aber nix gebracht.
1
;<h>StackConfiguration
2
;<o>StackSize(inBytes)<0x0-0xFFFFFFFF:8>
3
;</h>
4
5
Stack_SizeEQU0x00000800
6
7
AREASTACK,NOINIT,READWRITE,ALIGN=3
8
Stack_MemSPACEStack_Size
9
__initial_spEQU0x20002ff8
10
11
12
;<h>HeapConfiguration
13
;<o>HeapSize(inBytes)<0x0-0xFFFFFFFF:8>
14
;</h>
15
16
Heap_SizeEQU0x00000400
17
18
19
AREAHEAP,NOINIT,READWRITE,ALIGN=3
20
__heap_base
21
Heap_MemSPACEHeap_Size
22
__heap_limit
Und wie muss man sich das mit
extern uint32_t HEAP$$Base;
extern uint32_t HEAP$$Limit;
uint32_t __HEAP_START = (uint32_t)&HEAP$$Base;
uint32_t __HEAP_END = (uint32_t)&HEAP$$Limit;
vorstellen, irgendwo muss ja in einem anderen File HEAP$$Base und
HEAP$$Limit definiert sein. Mir fehlt einfach das Verständnis, was da
wirklich vorgeht und was gemacht werden muss damit es richtig ist.
Vielleicht kann man es ja auch ohne malloc lösen.Hoffe auf Anregungen
und Tipps,Danke.
Bei 16kB RAM ist malloc so eine Sache. Versuche es ganz zu vermeiden.
Musst du unbedingt während das Programm läuft verschiedene Ringbuffer
zuvor unbekannter Größe anlegen und wieder löschen? Wenn nicht, legst du
alle Ringbuffer fix mit bekannter Größe an (zB als globale Variablen)
und sparst dir das malloc-Zeug komplett. zB so:
Hallo, danke für die schnelle Antwort, also ich will per UART senden und
empfangen also reichen zwei Ringbuffer. Die Größe ist auch bekannt. ich
möchte auch alle Daten in Strukturen ablegen, um diese einfacher zu
verarbeiten.
zb soll
struct nam {
int size;
char nname[20];
} data;
in den TX_buffer geschrieben werden. dann soll das ganze rausgeschickt
werden.
Wie willst du nur mit einer Variable size wissen wo das erste Byte zum
Lesen ist und wo das erste freie Byte zum Schreiben?
Wie soll diese Funktion
void ringBufferWrite (RingBuffer* b, char* data, size_t size);
funktionieren?
Jo die Implementation braucht natürlich noch Schreibpointer+Füllstand
oder so im struct. Ich hatte nur die für die Fragestellung relevanten
Dinge, nämlich Array-Pointer+Größe, hineingeschrieben.
Udo Schmitt schrieb:> Wie soll diese Funktion funktionieren
Sie schreibt "size" bytes aus "data" in den Ringbuffer.
Ja, habs jetzt sowie im folgenden Link gemacht,
http://www.tschallener.net/AVR/intr_usart.pdf
was mir noch unklar ist, wie ich ein Struct in den Buffer
reingeschaufelt bekomme, wahrscheinlich ist es nix wildes, habe halt
noch keine Jahrelange Programmiererfahrung
avr avr schrieb:> zb soll>> struct nam {> int size;> char nname[20];>> } data;>> in den TX_buffer geschrieben werden.
HÄ?
Was soll denn das? Wenn du irgendwas per UART senden willst, dann gewiß
Chars und keine Structs, gelle?
Also, mal ganz von vorne:
Ein Ringpuffer ist ein Speicherbereich, der von zwei unterschiedliche
Instanzen benutzt wird: die eine schreibt hinein und die andere liest
heraus (ok, Computerdeutsch..). Dazu gibt's 2 Zeiger. Die Zeiger lesen
dürfen beide Instanzen, schreiben darf aber nur jede Instanz ihren
eigenen Zeiger.
Beispiel:
1
#define buffersize 128
2
charBuffer[buffersize];// das ist der Ringpuffer
3
intrdz,wrz;// das sind die Zeiger
4
5
voidInitBuffer(void)
6
{wrz=rdz=0;}
7
8
boolIsBufferFull(void)
9
{inti;
10
i=(wrz+1)%buffersize;
11
return(i==rdz);
12
}
13
14
voidPutIntoBuffer(charc)
15
{inti;
16
i=(wrz+1)%buffersize;
17
if(i==rdz)
18
{tja,Pufferistvoll,alsowasangemesseneshiertun}
19
Buffer[wrz]=c;
20
wrz=i;
21
}
Das aufrufende Programm braucht nur die Funktionen zu kennen, nicht aber
den eigentlichen Puffer und die Zeiger. Modulintern muß es natürlich
noch ne Funktion geben, die den Krempel dann auch wieder aus dem Puffer
abholt und verarbeitet. Ins Headerfile gehören also nur
1
2
externvoidInitBuffer(void);
3
externboolIsBufferFull(void);
4
externvoidPutIntoBuffer(charc);
Beide Instanzen müssen dabei logischerweise mit dem gleichen Datentyp
arbeiten, also wenn du nen char Buffer[..] kreierst, dann passen da nur
Char's rein, wenn du nen verrückten struct Buffer[..] hernimmst, dann
passen da eben nur verrückte struct's rein. (Deine Idee mit dem struct
ist Mist)
Dr. Sommer schrieb:> Wenn nicht, legst du> alle Ringbuffer fix mit bekannter Größe an (zB als globale Variablen)> und sparst dir das malloc-Zeug komplett. zB so:> struct RingBuffer [> char* data;> size_t size;> };
Den Sinn deines "RingPuffer"s sehe ich überhaupt nicht ein, wozu diesen
unnützen struct, der nicht mal ein wirklicher Ringpuffer ist? Und den
auch noch in globale Variablen? Zum Aufblähen des Codes? Zum Züchten von
Bugs? Zum Verwirren von Anfängern?
Gute Programme erkennt man daran, daß sie Funktionalität sinnvoll
kapseln.
Das hier ist das Gegenteil davon:
> char rb1Data [1024];> char rb2Data [64];> RingBuffer buffer1 = { rb1Data, 1024 };> RingBuffer buffer2 = { rb2Data, 64 };>> void ringBufferInit (RingBuffer* b);> void ringBufferWrite (RingBuffer* b, char* data, size_t size);> void ringBufferRead (RingBuffer* b, char* data, size_t size);
.. mal abgesehen davon, daß dir immer noch die wichtigsten Teile das
Ringpuffers fehlen.
W.S.
Structs können Structs beinhalten gelle.
ließ mal den Code im Link, da ists mit lese und schreibzeiger, der
Ringpuffer soll auch kein Struct sein, im Programm wird mit Structs
gearbeitet und somit sollen die Bytes der Struktur in ein Ringpuffer,
damit man man die Daten raussenden kann. Ich möchte also eine Funktion
die den Buffer mit Inhalten aus dem Struct füllt.
W.S. schrieb:>> struct RingBuffer [>> char* data;>> size_t size;>> };>> Den Sinn deines "RingPuffer"s sehe ich überhaupt nicht ein, wozu diesen> unnützen struct, der nicht mal ein wirklicher Ringpuffer ist? Und den> auch noch in globale Variablen? Zum Aufblähen des Codes? Zum Züchten von> Bugs? Zum Verwirren von Anfängern?>> Gute Programme erkennt man daran, daß sie Funktionalität sinnvoll> kapseln.> Das hier ist das Gegenteil davon:>> char rb1Data [1024];>> char rb2Data [64];>> RingBuffer buffer1 = { rb1Data, 1024 };>> RingBuffer buffer2 = { rb2Data, 64 };>>>> void ringBufferInit (RingBuffer* b);>> void ringBufferWrite (RingBuffer* b, char* data, size_t size);>> void ringBufferRead (RingBuffer* b, char* data, size_t size);> .. mal abgesehen davon, daß dir immer noch die wichtigsten Teile das> Ringpuffers fehlen.>
Die Idee (wenn auch nicht komplett durchgezogen, die Schreib- Lesezeiger
fehlen), dürfte gewesen sein, mehrere Ringbuffer mit unterschiedlichen
Größen instatiieren zu können. Daher die struct für den Ringbuffer
selbst, daher die Übergabe einer derartigen Struktur an die Funktionen.
> W.S.