Hallo,
ich muss einen Puffer implementieren fuer eine UART.
Ein UART-Interrupt schreibt Zeichen in diesem Puffer.
Das Main-Programm liest.
Beim Lesen soll der UART RX Interrupt nicht disabled werden.
Angeblich gibt es solche Thread-safe Implementationen.
Wenn der Interrupt nur den Write-Index veraendert, das Main Programm nur
den Read-Index veraendert, sollte nichts passieren.
Bei Wikipedia fand ich dieses Beispiel
1 | #include <stdio.h>
|
2 | #include <string.h>
|
3 |
|
4 | #define BUFFER_SIZE 25
|
5 | #define ERROR_CHAR -1
|
6 |
|
7 | void buffer_char(char c);
|
8 | char unbuffer_char(void);
|
9 |
|
10 | //a buffer with BUFFER_SIZE slots
|
11 | char circular_buffer[BUFFER_SIZE];
|
12 |
|
13 | //integers to index circular_buffer
|
14 | int start, end;
|
15 |
|
16 | int main(int argc, char *argv[])
|
17 | {
|
18 | char sentence[] = {"The quick brown dog jumps over the lazy fox."};
|
19 | int i;
|
20 |
|
21 | //add sentence into the buffer
|
22 | for (i = 0; i < strlen(sentence); i++) {
|
23 | buffer_char(sentence[i]);
|
24 | }
|
25 |
|
26 | //read the contents of the buffer excluding the last element
|
27 | while(start != end) {
|
28 | printf("%c", unbuffer_char());
|
29 | }
|
30 |
|
31 | printf("\n");
|
32 | return 0;
|
33 | }
|
34 |
|
35 | void buffer_char(char c)
|
36 | {
|
37 | //Use modulo as a trick to wrap around the end of the buffer back to the beginning
|
38 | if ((end + 1) % BUFFER_SIZE != start) {
|
39 | circular_buffer[end] = c;
|
40 | end = (end + 1) % BUFFER_SIZE;
|
41 | }
|
42 | //otherwise, the buffer is full; don't do anything. you might want to
|
43 | //return an error code to notify the writing process that the buffer is full.
|
44 | }
|
45 |
|
46 | char unbuffer_char(void)
|
47 | {
|
48 | if (end != start) {
|
49 | char temp = circular_buffer[start];
|
50 | start = (start + 1) % BUFFER_SIZE;
|
51 | return(temp);
|
52 | }
|
53 | //otherwise, the buffer is empty; return an error code
|
54 | return ERROR_CHAR;
|
55 | }
|
Es kann passieren, dass der unbuffer_char-code vom Interrupt
unterbrochen wird und den buffer_char(char c) - code ausfuehrt.
z.B. zwischen den Zeilen
1 | char temp = circular_buffer[start];
|
2 | start = (start + 1) % BUFFER_SIZE;
|
Aber es sollte nichts passieren, da immer ein Slot frei bleibt.
(Puffer ist voll, wenn BUFFER_SIZE-1 Slots belegt)
Kann mir jemand meine Vermutung bestaetigen oder mich korrigieren?
Danke und Gruss,
Johannes