Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Проблем с имплементация на Ring Buffer
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=17195
Страница 1 от 1

Автор:  lubo_88 [ Нед Мар 22, 2020 5:41 am ]
Заглавие:  Проблем с имплементация на Ring Buffer

Здравейте,
Опитвам се да имплементирам прост ring buffer в MPLAB XC32, но кодът нещо се дъни. Моля, за помощ!!!
Пробвах го в Code Blocks и всичко си работи без проблем, но MPLAB нещо не го харесва. Всъщност кода се компилира без грешка, но при дебъг в симулатора се случват следните проблеми.
1. При извикване на функцията ringbuf_init ме препраща към някакви асемлерски инструкции, файл crt0.S (вижда се на скрийншота). След продължително натискане на Step Into (F7), ме връща към началото на програмата.
2. Ако не извикам функцията ringbuf_init, а директно извикам ringbuf_put() (функция, която пълни буфера), този път асемблерските инструкции (crt0.S) не изскачат, но забелязвам, че на мястото на параметъра item, не влиза стойността, която съм подал (както се вижда от кода, подавам по стойност).
Код:

#define RBUF_SIZE 5                         

typedef struct                             
{
    uint8_t buf[RBUF_SIZE];
    uint8_t head;                           
    uint8_t tail;                           
    uint8_t count;                         
}RingBuffer_t;


void ringbuf_init(RingBuffer_t *buffer);
uint8_t ringbuf_get(RingBuffer_t *buffer);
void ringbuf_put(RingBuffer_t *buffer, uint8_t item);
uint8_t ringbuf_adv(const uint8_t value, const uint8_t max);

void main(void) {
   
    RingBuffer_t buffer;
    ringbuf_init(&buffer);
    ringbuf_put(&buffer, 18);
    while(1);
    return;
}


void ringbuf_put(RingBuffer_t *buffer, uint8_t item)
{
    if(buffer->count < RBUF_SIZE)
    {
        buffer->buf[buffer->head] = item;
        buffer->head = ringbuf_adv(buffer->head, RBUF_SIZE);
        ++buffer->count;
    }
}


uint8_t ringbuf_adv(const uint8_t value, const uint8_t max)
{
    unsigned int index = value + 1;
    if(index >= max)
    {
        index = 0;
    }

    return index;
}


uint8_t ringbuf_get(RingBuffer_t *buffer)
{
    int item;
    if(buffer->count > 0)
    {
        item = buffer->buf[buffer->tail];
        buffer->tail = ringbuf_adv(buffer->tail, RBUF_SIZE);
        --buffer->count;
    }
    else
    {
        item = 0;
    }

    return item;
}


void ringbuf_init(RingBuffer_t *buffer)
{
    buffer->count = 0;
    buffer->head = 0;
    buffer->tail = 0;
   
    uint8_t i;
    for(i=0; i<RBUF_SIZE; i++)
    {
        buffer->buf[i] = 0;
    }
}



Прикачени файлове:
6.png
6.png [ 382.48 KiB | Прегледано 4660 пъти ]
crt0S.png
crt0S.png [ 64.66 KiB | Прегледано 4660 пъти ]

Автор:  stefan63 [ Нед Мар 22, 2020 9:45 am ]
Заглавие:  Re: Проблем с имплементация на Ring Buffer

Бих пробвал да обявя буфера извън main().
Предполагам, че както си го обявил - е законно- но на мен ми е съмнително място.
Обаче...(както аз схващам C-то)...
При тебе - буфера е обявен вътре във функция, тоест би трябвало да е в стека.
В тоя смисъл адресът на буфера е неизвестен при компилация и трябва да се изчисли по време на изпълнение( подаваш го като параметър на други функции). И може би тогава се викат асемблерските функции.
Ако изкараш буфера извън функцията - нещата биха били по-прости за компилатора.

Автор:  TheWizard [ Нед Мар 22, 2020 10:15 am ]
Заглавие:  Re: Проблем с имплементация на Ring Buffer

не се "дъни" ринга...

Прикачени файлове:
Untitled-1.jpg
Untitled-1.jpg [ 229.68 KiB | Прегледано 4634 пъти ]

Автор:  lubo_88 [ Нед Мар 22, 2020 3:47 pm ]
Заглавие:  Re: Проблем с имплементация на Ring Buffer

stefan63 написа:
Бих пробвал да обявя буфера извън main().
Предполагам, че както си го обявил - е законно- но на мен ми е съмнително място.
Обаче...(както аз схващам C-то)...
При тебе - буфера е обявен вътре във функция, тоест би трябвало да е в стека.
В тоя смисъл адресът на буфера е неизвестен при компилация и трябва да се изчисли по време на изпълнение( подаваш го като параметър на други функции). И може би тогава се викат асемблерските функции.
Ако изкараш буфера извън функцията - нещата биха били по-прости за компилатора.

Ако го дефинирам извън main(), няма ли да стане глобален? Аз целя точно обратното.

TheWizard написа:
не се "дъни" ринга...

Създадох нов-чист проект и наистина си работи без проблем. Явно, проблема е някъде в останалта част на кода

Автор:  stefan63 [ Нед Мар 22, 2020 9:17 pm ]
Заглавие:  Re: Проблем с имплементация на Ring Buffer

lubo_88 написа:
Ако го дефинирам извън main(), няма ли да стане глобален? Аз целя точно обратното.


да,,,,ако нaпишеш static в началото на сегашната декларация ...може би ще получиш облегчен достъп и скрити променливи.
Но сигурно няма смисъл, щом вече си "делокализирал" проблема.

Автор:  relsys [ Пет Мар 27, 2020 3:49 am ]
Заглавие:  Re: Проблем с имплементация на Ring Buffer

lubo_88 написа:
Ако го дефинирам извън main(), няма ли да стане глобален? Аз целя точно обратното.


И защо това е целта...?!?

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/