Отговори на тема  [ 6 мнения ] 
Проблем с имплементация на Ring Buffer 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Сря Яну 09, 2019 8:13 pm
Мнения: 19
Мнение Проблем с имплементация на 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 | Прегледано 3533 пъти ]
crt0S.png
crt0S.png [ 64.66 KiB | Прегледано 3533 пъти ]
Нед Мар 22, 2020 4:41 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 10:22 pm
Мнения: 3074
Мнение Re: Проблем с имплементация на Ring Buffer
Бих пробвал да обявя буфера извън main().
Предполагам, че както си го обявил - е законно- но на мен ми е съмнително място.
Обаче...(както аз схващам C-то)...
При тебе - буфера е обявен вътре във функция, тоест би трябвало да е в стека.
В тоя смисъл адресът на буфера е неизвестен при компилация и трябва да се изчисли по време на изпълнение( подаваш го като параметър на други функции). И може би тогава се викат асемблерските функции.
Ако изкараш буфера извън функцията - нещата биха били по-прости за компилатора.


Нед Мар 22, 2020 8:45 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 27, 2005 11:48 am
Мнения: 4671
Мнение Re: Проблем с имплементация на Ring Buffer
не се "дъни" ринга...


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

_________________
main[-1u]={1};
Нед Мар 22, 2020 9:15 am
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Сря Яну 09, 2019 8:13 pm
Мнения: 19
Мнение Re: Проблем с имплементация на Ring Buffer
stefan63 написа:
Бих пробвал да обявя буфера извън main().
Предполагам, че както си го обявил - е законно- но на мен ми е съмнително място.
Обаче...(както аз схващам C-то)...
При тебе - буфера е обявен вътре във функция, тоест би трябвало да е в стека.
В тоя смисъл адресът на буфера е неизвестен при компилация и трябва да се изчисли по време на изпълнение( подаваш го като параметър на други функции). И може би тогава се викат асемблерските функции.
Ако изкараш буфера извън функцията - нещата биха били по-прости за компилатора.

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

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

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


Нед Мар 22, 2020 2:47 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 10:22 pm
Мнения: 3074
Мнение Re: Проблем с имплементация на Ring Buffer
lubo_88 написа:
Ако го дефинирам извън main(), няма ли да стане глобален? Аз целя точно обратното.


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


Нед Мар 22, 2020 8:17 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 25, 2005 10:41 am
Мнения: 1657
Мнение Re: Проблем с имплементация на Ring Buffer
lubo_88 написа:
Ако го дефинирам извън main(), няма ли да стане глобален? Аз целя точно обратното.


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


Пет Мар 27, 2020 2:49 am
Профил ICQ WWW
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 6 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни