toweroff 0 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба Добрый день У меня кольцевой буфер, прерывание пишет в конец, функция чтения берет из начала. Размер буфера кратен 2, на индекс накладывается маска (размер-1), все стандартно. Нужно из функции чтения выходить как по приему байта, так и по тайм-ауту. Когда-то в примерах Keil RTX видел такой прием: если буфер пустой, в спец.переменную заносим ID задачи, из которой выполняемся и ждем сигнала или тайм-аута в прерывании по при приеме байта, если переменная содержит ID, отправляем сигнал Так вот какая-то фигня получается, что иногда у меня начало буфера опережает конец и все рушится к едрене фене. Как правильно организовать сей процесс? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба Ничего не понял. Приняли сообщение (или байт) - создали событие (Event) для задачи. Она и запустится, если ничто более приоритетное не помешает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 0 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба Ничего не понял. Приняли сообщение (или байт) - создали событие (Event) для задачи. Она и запустится, если ничто более приоритетное не помешает. ну я тоже так разумею. Приняли событие - значит в буфере гарантированно есть байт. Его и вычитываем оттуда но иногда, по каким-то неведомым обстоятельствам, у меня получается, что я вычитал больше, чем там есть индексы буфера более нигде не модифицируются, только в прерывании (конец буфера) и при чтении (начало) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба Может, неправильно сравниваются индексы записи и чтения? Они ж там по кругу бегают. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 0 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба Может, неправильно сравниваются индексы записи и чтения? Они ж там по кругу бегают. да вроде все нормально, первым делом проверял. если делаю что-то типа такого: 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; } то все в порядке. Но некошерно ведь, по идее задача должна замереть и отдать процессору время, а не тупо бегать в цикле Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RabidRabbit 0 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба а, извиняюсь, обращение к COM->start_in и COM->end_in у Вас атомарное? ну на всякий случай, вдруг это int32_t на avr :) ну и ещё: "в прерывании по при приеме байта, если переменная содержит ID, отправляем сигнал" - ID потом очищается? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 0 7 февраля, 2017 Опубликовано 7 февраля, 2017 · Жалоба а, извиняюсь, обращение к COM->start_in и COM->end_in у Вас атомарное? ну на всякий случай, вдруг это int32_t на avr :) STM32F0 ну и ещё: "в прерывании по при приеме байта, если переменная содержит ID, отправляем сигнал" - ID потом очищается? :) конечно, сразу после приема события или тайм-аута. Хотя... надо попробовать в прерывании это делать Хотя... надо попробовать в прерывании это делать ну едрёна кочерыжка... вот где собака порылась :) и все зашевелилось Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться