Перейти к содержанию
    

USART и RTOS

Добрый день

 

У меня кольцевой буфер, прерывание пишет в конец, функция чтения берет из начала. Размер буфера кратен 2, на индекс накладывается маска (размер-1), все стандартно.

Нужно из функции чтения выходить как по приему байта, так и по тайм-ауту.

 

Когда-то в примерах Keil RTX видел такой прием:

если буфер пустой, в спец.переменную заносим ID задачи, из которой выполняемся и ждем сигнала или тайм-аута

в прерывании по при приеме байта, если переменная содержит ID, отправляем сигнал

 

Так вот какая-то фигня получается, что иногда у меня начало буфера опережает конец и все рушится к едрене фене.

 

Как правильно организовать сей процесс?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ничего не понял. Приняли сообщение (или байт) - создали событие (Event) для задачи. Она и запустится, если ничто более приоритетное не помешает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ничего не понял. Приняли сообщение (или байт) - создали событие (Event) для задачи. Она и запустится, если ничто более приоритетное не помешает.

ну я тоже так разумею. Приняли событие - значит в буфере гарантированно есть байт. Его и вычитываем оттуда

но иногда, по каким-то неведомым обстоятельствам, у меня получается, что я вычитал больше, чем там есть

индексы буфера более нигде не модифицируются, только в прерывании (конец буфера) и при чтении (начало)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может, неправильно сравниваются индексы записи и чтения? Они ж там по кругу бегают.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может, неправильно сравниваются индексы записи и чтения? Они ж там по кругу бегают.

да вроде все нормально, первым делом проверял.

 

если делаю что-то типа такого:

    time = os_time_get();
    while ((COM->start_in == COM->end_in) && ((time + timeout) > os_time_get()));
    
    if (COM->start_in == COM->end_in)
    {
        return USART_GET_CHAR_TIMEOUT;
    }

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а, извиняюсь, обращение к COM->start_in и COM->end_in у Вас атомарное? ну на всякий случай, вдруг это int32_t на avr :)

ну и ещё: "в прерывании по при приеме байта, если переменная содержит ID, отправляем сигнал" - ID потом очищается? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а, извиняюсь, обращение к COM->start_in и COM->end_in у Вас атомарное? ну на всякий случай, вдруг это int32_t на avr :)

STM32F0

 

ну и ещё: "в прерывании по при приеме байта, если переменная содержит ID, отправляем сигнал" - ID потом очищается? :)

конечно, сразу после приема события или тайм-аута. Хотя... надо попробовать в прерывании это делать

 

Хотя... надо попробовать в прерывании это делать

ну едрёна кочерыжка... вот где собака порылась :)

и все зашевелилось

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...