User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

c:fifo-readline [2018-02-02 13:31] (current)
Line 1: Line 1:
 +
 +=====FIFO buffer with readline=====
 +
 +I wrote this code for Atmel microprocessor line parser.
 +
 +<code c hello.c>
 +//#include <​avr/​io.h>​
 +//#include <​util/​delay.h>​
 +
 +#include <​stddef.h>​
 +#include <​stdbool.h>​
 +#include <​stdint.h>​
 +#include <​stdio.h>​
 +#include <​string.h>​
 +#include <​unistd.h>​
 +
 +struct fifo_t {
 +    volatile unsigned head;
 +    volatile unsigned tail;
 +    volatile uint8_t *buffer;
 +    unsigned buffer_len;
 +};
 +
 +typedef struct fifo_t FIFO;
 +
 +uint8_t fifo_count(const FIFO *b) {
 +    if (b) {
 +        return (b->head - b->​tail);​
 +    }
 +    return 0;
 +}
 +
 +static bool fifo_full(const FIFO *b) {
 +    if (b) {
 +        return (fifo_count(b) == b->​buffer_len);​
 +    }
 +    return true;
 +}
 +
 +bool fifo_empty(const FIFO *b) {
 +    if (b) {
 +        return (fifo_count(b) == 0);
 +    }
 +    return true;
 +}
 +
 +uint8_t fifo_peek(const FIFO *b) {
 +    if (b) {
 +        return (b->​buffer[b->​tail % b->​buffer_len]);​
 +    }
 +    return 0;
 +}
 +
 +uint8_t fifo_getc(FIFO *b) {
 +    uint8_t data = 0;
 +    if (!fifo_empty(b)) {
 +        data = b->​buffer[b->​tail % b->​buffer_len];​
 +        b->​tail++;​
 +    }
 +    return data;
 +}
 +
 +bool fifo_putc(FIFO *b, uint8_t data) {
 +    bool status = false;
 +    if (b) {
 +        if (!fifo_full(b)) {
 +            b->​buffer[b->​head % b->​buffer_len] = data;
 +            b->​head++;​
 +            status = true;
 +        }
 +    }
 +    return status;
 +}
 +
 +void fifo_init(FIFO *b, volatile uint8_t *buffer, unsigned buffer_len) {
 +    if (b) {
 +        b->​buffer_len = buffer_len;
 +        b->​buffer = buffer;
 +        b->head = 0;
 +        b->tail = 0;
 +    }
 +    return;
 +}
 +
 +uint8_t fifo_puts(FIFO *b, char *string) {
 +    if (b) {
 +        for (uint8_t i = 0; i < strlen(string);​ i++) {
 +            if (!fifo_putc(b,​ string[i])) return i;
 +        }
 +    }
 +}
 +
 +bool fifo_scanc(FIFO *b, uint8_t c) {
 +    if (b) {
 +        if (!fifo_empty(b)) {
 +            uint8_t tail = b->tail;
 +            for (uint8_t i = 0; i < fifo_count(b);​ i++) {
 +                uint8_t data = b->​buffer[tail % b->​buffer_len];​
 +                if (data == c) { return true; }
 +                tail++;
 +            }
 +        }
 +        return false;
 +    }
 +}
 +
 +#define LINE_TERM '​\n'​
 +
 +uint8_t fifo_readline(FIFO *b, uint8_t *str, uint8_t len) {
 +    if (b) {
 +        memset((void *)str, 0, len);
 +        // str[0] = 0;
 +        if (fifo_scanc(b,​ LINE_TERM) && str) {
 +            uint8_t i = 0, c = 0;
 +            while ((c = fifo_getc(b)) != 0) {
 +                if (c == LINE_TERM) break;
 +                str[i] = c;
 +                i++;
 +            }
 +            return i;
 +        }
 +        return 0;
 +    }
 +}
 +
 +#define FIFO_BUFFER_SIZE 256
 +#define MAX_LINE_LEN 64
 +
 +
 +void main(void) {
 +
 +    FIFO fifo;
 +
 +    volatile uint8_t store[FIFO_BUFFER_SIZE + 1];
 +    memset((void *)store, 0, FIFO_BUFFER_SIZE + 1);
 +
 +    fifo_init(&​fifo,​ store, sizeof(store));​
 +
 +    fifo_puts(&​fifo,​ "​CMD123\nCMD456\nCMD90\n"​);​
 +
 +    // if (fifo_scanc(&​fifo,​ '​\n'​)) puts("​fifo have newine"​);​
 +    // printf("​count=%d\n",​ fifo_count(&​fifo));​
 +
 +    uint8_t line[MAX_LINE_LEN+1];​
 +    memset((void *)line, 0, MAX_LINE_LEN+1);​
 +
 +    uint8_t count;
 +
 +    while((count = fifo_readline(&​fifo,​ line, MAX_LINE_LEN)) > 0) {
 +
 +        // if (fifo_scanc(&​fifo,​ '​\n'​)) puts("​fifo have newine"​);​
 +        // printf("​fifo count=%d\n",​ fifo_count(&​fifo));​
 +        printf("​readline:​ count=%d out=%s\n",​ count, line);
 +    }
 +
 +}
 +
 +//EOF
 +</​code>​
 +
 +===Out===
 +
 +<​code>​
 +readline: count=6 out=CMD123
 +readline: count=6 out=CMD456
 +readline: count=5 out=CMD90
 +</​code>​