реклама на сайте
подробности

 
 
> __LDREX __STREX в STM32F407
_lexa_
сообщение Jun 4 2017, 13:18
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 23
Регистрация: 23-03-15
Пользователь №: 85 852



Всем доброе время суток!

IDE - IAR+плагин IAR для eclipse+eclipse.
Решил проверить, как работает синхронизация с использованием __LDREX/__STREX. Пишем следующий код
CODE
typedef struct
{
...
volatile unsigned long sync; //переменная для синхонизации доступа к данному элементу
} burst_measur;

burst_measur cur_mes;

void mpu_cfg_test()
{
//настраиваем область внутренней RAM, как разделяемую
__DMB();
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
MPU->CTRL = 0U;

MPU->RNR = 0UL;
MPU->RBAR = 0x20000000UL;
MPU->RASR = (0x10UL << MPU_RASR_SIZE_Pos) | MPU_RASR_C_Msk | MPU_RASR_S_Msk | (0x3 << MPU_RASR_AP_Pos) | MPU_RASR_ENABLE_Msk;

MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk;
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
__DSB();
__ISB();

//выполняем запрос эксклюзивного доступа к переменной cur_mes.sync
DWORD sync=0;
sync = __LDREX(&cur_mes.sync);
__DMB();
soft_int_ini(); //настойка программного прерывания
soft_int_on(); //вызов программного прерывания
__WFI();
}


в обработчике программного прерывания:
CODE
DWORD sync;
do
{
sync = __LDREX(&cur_mes.sync);
sync++;
sync = __STREX(sync, &cur_mes.sync);
}
while (sync);


Т.е. сначала выполняется __LDREX(&cur_mes.sync), потом происходит прерывание и выполняется __LDREX(&cur_mes.sync) + __STREX(sync, &cur_mes.sync).
По всем документациям, как я их понял, __STREX(sync, &cur_mes.sync) должна возвратить "не ноль", однако возвращает "ноль".

Помогите, пожалуйста, разобраться, что я делаю не правильно?

Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Alechek
сообщение Jun 8 2017, 11:54
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882



Цитата(jcxz @ Jun 8 2017, 11:17) *
И правильно! Через DMA и пр. - ЗАЧЕМ???

Импульсивный Вы наш, по делу бы что сказали!

Цитата(AHTOXA @ Jun 8 2017, 11:21) *
Добавьте в ваш список выводов, что монитор может срабатывать на любое изменение уровня прерываний

Добавил, куда можно было. Весь этот раздел A3.4 - сплошные выводы. Читать и читать.

Цитата(AHTOXA @ Jun 8 2017, 11:21) *
ЗЫ. Хотя насчёт DMA - я лично не верю. В этом случае при непрерывно идущих быстрых транзакциях DMA можно наглухо зависнуть в LDREX/STREX.

Мне тоже идея с DMA не очень нравится.
Вроде как не обязательно Store от ядра должно исходить.... В одном месте так написано, в другом - по другому...
Вобщем, все на откуп реализации:
Прикрепленное изображение
Прикрепленное изображение

Опыты, только опыты... Ни в одной докуметации на MCU не видел таких тонкостей.
Go to the top of the page
 
+Quote Post
AVI-crak
сообщение Jun 8 2017, 13:21
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894



Проверять нужно кодом на асме, чтобы gcc не наоптимизировал записи до нуля.
Тестовую запись нужно сбрасывать в память принудительно, с ожиданием завершения физической записи.
Неявная запись (PUSH) - является отложенным событием (как и любая запись кучи регистров), код выполняется параллельно, сбросить физику с подтверждением не получится, но можно немного подождать в пустом цикле или сбросить конвейер.

И наверное главное, давайте указывать явно - какой чип в тесте на данный момент.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 8 2017, 20:32
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(AVI-crak @ Jun 8 2017, 15:21) *
Неявная запись (PUSH) - является отложенным событием (как и любая запись кучи регистров), код выполняется параллельно, сбросить физику с подтверждением не получится, но можно немного подождать

Сколько? Сколько вешать в граммах?

Цитата(AVI-crak @ Jun 8 2017, 15:21) *
в пустом цикле или сбросить конвейер.

Это что такое? И как оно поможет?

Цитата(AVI-crak @ Jun 8 2017, 15:21) *
И наверное главное, давайте указывать явно - какой чип в тесте на данный момент.

DMB/DSB/и прочие B - спасут отца русской демократии laughing.gif

Цитата(LightElf @ Jun 8 2017, 15:44) *
На Cortex-M, которые по определению одноядерные

Вы это расскажите NXP с их линейкой LPC43xx. Про свои определения. cool.gif
Или Ваш мир Cortex-M ограничен STM32?
Курица - не птица, Cortex-M - не STM! Рифма одна-ко. Надо в подпись внести © biggrin.gif
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 9 2017, 07:50
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Коли SVC синхронное и его не получиться использовать нормально в прерываниях (для lockfree решений), то может быть для этой цели подойдет pendSV?

А, чтобы разделить переключатель контекста rtos и юзерские вызовы этого самого pendSV, скажем, в R0 кладем адрес функции, а в остальные регистры ее параметры, а уже внутри pendSV все это разбираем.
Приоритет pendSV самый низкий (ниже лишь systick).
Тогда другой вызов pendSV прервать его не сможет, а лишь поставить в очередь. Т.е. обеспечивается атомарность действий как в прерываниях, так и в основном коде.
Вижу одно ограничение - передавать в такие функции указатели нежелательно, а можно лишь готовые данные (прямо в регистры R1...), т.е. ограничен объем передаваемых данных.
В противном случае нет никакой гарантии, что к моменту вызова соотв. функции (внутри pendSV) данные по указателям будут актуальны.

Или тут есть какие-то подводные камни?
зы. Предположительно вангую грабли со вложенными вызовами (вытесняющие прерывания), где оба обработчика вызывают pendSV...


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 9 2017, 10:33
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Forger @ Jun 9 2017, 09:50) *
зы. Предположительно вангую грабли со вложенными вызовами (вытесняющие прерывания), где оба обработчика вызывают pendSV...

PendSV не "вызывают", а лишь возбуждают запрос на него. В том числе и в ISR-ах, где вход в PendSV будет отложен до завершения всех других ISR, а из фонового процесса - вход в PendSV будет сразу, подобно синхронному SVC.
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 9 2017, 10:58
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(jcxz @ Jun 9 2017, 13:33) *
PendSV не "вызывают" ...
Да, это-то понятно, это все - придирки к словам, а речь о другом:
как сделать так, чтобы pendSV могли вызывать взводить разные обработчики, особенно вложенные друг в друга, но так, чтобы в стеке сформировалась очередь данных, которые позволят этот pendSV обработать несколько раз подряд и не потерять ни одного запроса и не разрушить стек?
Понятно, что pendSV не для этого был задуман, но тем не менее ))

Размышляя вслух дальше - выполняемый в данный момент pendSV может прервать другое более приоритетное прерывание и опять накидать в стек новых данных перед взводом pendSV,
Или использовать внутри pendSV вызов соотв. SVC, который имеет приоритет выше pendSV...
Заумно как-то выходит. Но возможно ли осуществить что-то подобное?
Цель - избежать критических секций с запретом прерываний и "капризного" LDREX/STREX.


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Шаманъ
сообщение Jun 9 2017, 13:02
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839



Цитата(Forger @ Jun 9 2017, 13:58) *
как сделать так, чтобы pendSV могли вызывать взводить разные обработчики, особенно вложенные друг в друга, но так, чтобы в стеке сформировалась очередь данных, которые позволят этот pendSV обработать несколько раз подряд и не потерять ни одного запроса и не разрушить стек?

Очередь данных в стеке не формируется - формируйте ее отдельно, а потом обрабатывайте в PendSV. Но для данной задачи это неэффективно и не имеет смысла - есть LDREX/STREX, если его не хватает, то есть запрет части или всех прерываний.
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 9 2017, 13:20
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Шаманъ @ Jun 9 2017, 16:02) *
Очередь данных в стеке не формируется - формируйте ее отдельно, а потом обрабатывайте в PendSV.
А все равно грабли - процесс формирования очереди должен быть защищен критической секцией, масло масляное (((

Цитата
Но для данной задачи это неэффективно и не имеет смысла - есть LDREX/STREX, если его не хватает, то есть запрет части или всех прерываний.

Согласен, но хочется ведь гипотетического универсального решения, вот и спрашиваю )))

Короче, задача довольно тривиальная:
программная очередь, набиваемая в обработчике (скажем, очередь байтов), там же сигналим счетным семафором, переходим к соотв. задаче, которая это семафор ждет и выгребает из этой же очереди байты.
Нужно защищать указатели (голова/хвост) очереди от прерывания.

Сейчас сделано просто и логично - в конкретном экземпляре очереди запрещаются прерывания лишь от того, кто использует эту самую очередь - от USART.





--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Шаманъ
сообщение Jun 9 2017, 14:14
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839



Цитата(Forger @ Jun 9 2017, 16:20) *
хочется ведь гипотетического универсального решения

Если пишите под GCC, то можно посмотреть на atomic built-in функции https://gcc.gnu.org/onlinedocs/gcc-4.4.3/gc...c-Builtins.html .

Цитата
Короче, задача довольно тривиальная:
программная очередь, набиваемая в обработчике (скажем, очередь байтов), там же сигналим счетным семафором, переходим к соотв. задаче, которая это семафор ждет и выгребает из этой же очереди байты.
Нужно защищать указатели (голова/хвост) очереди от прерывания.

Интересно зачем? Если это что-то типа кольцевого буфера приделанного к UART, то один указатель изменяется только в задаче, а второй только в прерывании. Пересечения между ними не происходит. Семафор это головная боль ОС. Вот и все. У меня сделано похожим образом.
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 9 2017, 14:30
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Шаманъ @ Jun 9 2017, 17:14) *
Интересно зачем? Если это что-то типа кольцевого буфера приделанного к UART, то один указатель изменяется только в задаче, а второй только в прерывании. Пересечения между ними не происходит.

Еще как происходит - я контролирую переполнение и исчерпание очереди (соотв. ловушки/логи)!
Если в задаче в процессе извлечения свежего байта из очереди пришел еще один новый байт,
который нужно быстро положить в ту же очередь, то без соотв. критических секций получим что угодно, обычно получаем HF.
Поэтому эти две вещи нужно изолировать - пока достаем байт из очереди (в задаче), временно запрещаем прерывания от того, кто наполняет эту очередь.

Именно это я и описал выше.
У меня очередь сделана в виде шаблона, всего один параметр - тип данных.
При создании экземпляра очереди ей передается ссылка на класс Interrupt, в котором есть два обязательным метода disable и enable.
Для каждой очереди он может быть свой, поэтому запрещаются лишь те прерывания, которые конфликтуют с конкретным экземпляром очереди.

Цитата
Семафор это головная боль ОС.
При чем тут это?
Я лишь привел пример с осью, как наиболее универсальный.
Но кто не пользуется осью, могут просто поллить некий флажок в основном коде, а в прерываниях его взводить или инкрементировать.
Способ оповещения основного кода в данном случае не имеет никакого значения. Отклоняемся от темы )))


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Шаманъ
сообщение Jun 9 2017, 15:40
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839



Цитата(Forger @ Jun 9 2017, 17:30) *
При чем тут это?
Я лишь привел пример с осью, как наиболее универсальный.
Но кто не пользуется осью, могут просто поллить некий флажок в основном коде, а в прерываниях его взводить или инкрементировать.
Способ оповещения основного кода в данном случае не имеет никакого значения. Отклоняемся от темы )))

Это как раз причина по которой у меня с ОС не происходит, а с "неким флажком" происходит. Поясняю:

Если работа задачи, которая извлекает данные из очереди управляется семафором через ОС, то "недополнения" очереди возникнуть просто не может - задача блокируется и ожидает когда появятся данные. Поэтому указатель "хвоста" в полной безопасности.

Теперь про голову - данные из UART выгребаем в прерывании, в этом же прерывании увеличиваем счетчик семафора и добавляем в очередь. Чтобы избежать переполнения очереди достаточно проверить счетчик семафора. Вот собственно и все. Счетчик семафора это проблема ОС, остальное (очередь и указатели на голову/хвост) в полной безопасности.

Если интересно, как сделана у меня в ОС работа с семафорами, то через те же LDREX/STREX sm.gif Правда это если не касаться вопросов переключения задач и системных вызовов, но то уже точно другая тема.
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 9 2017, 16:27
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Шаманъ @ Jun 9 2017, 18:40) *
Это как раз причина по которой у меня с ОС не происходит, а с "неким флажком" происходит. Поясняю:

Да при чем тут семафор, ось, флажки и т.п.???
Я говорю про совсем другое - манипулирование индексами головы, хвоста и изменяемых данных которые должны меняться в едином непрерывном блоке кода.
Если обработчик прерываний разорвет эту цепочку в самом неподходящем месте, то рано или поздно произойдет HF.


Цитата(AVI-crak @ Jun 9 2017, 17:38) *
Приоритет SVC - 0.
Пользовательские прерывания 1~14.
Системный таймер, и таймер реального времени =15.

Поменять шило на мыло?
По вашей логике получится, что пока этот приоритетный SVC не отработает, ни одно более важное аппаратное прерывание не пройдет.
SVC с таким высоким приоритетом, вызываемые из других менее приоритетных прерываний по сути временно задирает их собственный приоритет, который был "ниже плинтуса", отбирая "право голоса" у более приоритетных прерываний.
На лицо - инверсия приоритетов. С чем боролись на то и напоролись. Ни чем не лучше глобальной критической секции (запрет/разрешение всех прерываний).

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


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Шаманъ
сообщение Jun 9 2017, 17:08
Сообщение #14


Знающий
****

Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839



Цитата(Forger @ Jun 9 2017, 19:27) *
Я говорю про совсем другое - манипулирование индексами головы, хвоста и изменяемых данных которые должны меняться в едином непрерывном блоке кода.
Если обработчик прерываний разорвет эту цепочку в самом неподходящем месте, то рано или поздно произойдет HF.

От же ж...ну как Вам еще объяснить. Читайте внимательно и думайте:
1. Указатель на голову (куда добавляются данные) он используется только в прерывании которое добавляет данные, только там, и больше нигде.
2. Указатель на хвост (откуда вычитываются данные) он используется только в задаче которая читает данные, только там, и больше нигде.

Синхронизация делается семафором, как и защита от переполнения/недополнения. К семафору есть доступ и у задачи, и у прерывания, но он делается через ОС.

Теперь понятно? Если нет, то перечитайте пожалуйста еще раз, ну или несколько раз - не знаю как объяснить иначе...
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 9 2017, 17:23
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Шаманъ @ Jun 9 2017, 20:08) *
От же ж...ну как Вам еще объяснить. Читайте внимательно и думайте:

Я про Фому, а он - про Ерему ...

Ясен пень, что голова и хвост изменяются в разным местах - один в фоне задач, другой - в перрывании, но !
Чтобы проверить переполнение/исчерпание, нужно контроллировать в непрерывном куске кода ОБА указателя/индекса.
Это можно делать только там, где производите изменение этих самых указателей/индексов - в прерывании и в фоне задач.
В прерывании это не проблема - защищать ничего не нужно, достаточно лишь не класть в буфер новые данные и кинуть соотв. сообщение/исключение.
А в фоне задачи нужно защищать обращение к ОБОИМ указателям в некой критической секции, иначе невозможно контроллировать подобные аварийные события.
Если этого не делать, то буфер может быть переполнен/исчерпан так, что об этом невозможно будет узнать.

Также реализуется обратная ситуация - задача кладет данные в буфер, взводит нужное прерывание и уже в соотв. обработчике буфер выгребается и отправляется во вне.
Чтобы положить данные в буфер в фоне задачи, нужно обращаться в непрерывном куске кода к ОБОИМ указателям. Поэтому тут нужна критическая секция или что-то подобное.

Цитата
Синхронизация делается семафором...

Точно, я про Фому, а он - про Ерему )))


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Шаманъ
сообщение Jun 9 2017, 17:40
Сообщение #16


Знающий
****

Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839



Цитата(Forger @ Jun 9 2017, 20:23) *
Чтобы проверить переполнение/исчерпание, нужно контроллировать в непрерывном куске кода ОБА указателя/индекса.

Нет. Достаточно проверить состояние семафора.

Цитата
А в фоне задачи нужно защищать обращение к ОБОИМ указателям в некой критической секции, иначе невозможно контроллировать подобные аварийные события.
Если этого не делать, то буфер может быть переполнен/исчерпан так, что об этом невозможно будет узнать.

Если напрячься и таки подумать, то в задаче буфер переполнен не модет быть вообще, ибо она данные только читает. А исчерпан не может быть т.к. задача синхронизирована семафором значение которого дает кол-во данных в очереди.

Про прерывание Вы и сами написали. Так кто там про Фому laughing.gif

Цитата
Также реализуется обратная ситуация - задача кладет данные в буфер, взводит нужное прерывание и уже в соотв. обработчике буфер выгребается и отправляется во вне.
Чтобы положить данные в буфер в фоне задачи, нужно обращаться в непрерывном куске кода к ОБОИМ указателям. Поэтому тут нужна критическая секция или что-то подобное.

Да не нужно - достаточно семафора.

P.S. Может быть Вы не так понимаете что такое семафор. У меня это объект синхронизации задач, который может принимать значения от 0 до некоторого MAX. Счетчик семафора показывает доступность ресурса (в данном случае кол-во данных в очереди). Задача может запросить конкретное кол-во данных или диапазон (от и до) - если нужное кол-во доступно, то задача получит запрошенное кол-во данных, если нет, то будет приостановлена, пока не будет доступно запрошенное кол-во данных.
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 9 2017, 17:48
Сообщение #17


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Шаманъ @ Jun 9 2017, 20:40) *
Если напрячься и таки подумать, то в задаче буфер переполнен не модет быть вообще, ибо она данные только читает. ...
Не, это - уже бесполезный спор.


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Шаманъ
сообщение Jun 9 2017, 17:56
Сообщение #18


Знающий
****

Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839



Цитата(Forger @ Jun 9 2017, 20:48) *
Не, это - уже бесполезный спор.

Конечно, ибо то, о чем я пишу работает sm.gif

ОК поставим вопрос по-другому, каким образом может быть переполнен буфер в задаче, которая из него только читает?
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 9 2017, 18:04
Сообщение #19


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Шаманъ @ Jun 9 2017, 20:56) *
Конечно, ибо то, о чем я пишу работает sm.gif

И самолеты летают. Но иногда, увы, падают sad.gif

Цитата
ОК поставим вопрос по-другому, каким образом может быть переполнен буфер в задаче, которая из него только читает?

Если она только читает, то буфер со временем просто переполнится, чтобы избежать этого, из буфера нужно не просто читать данные, но и изменять соотв. указатель.
При заполнении буфера (в прерывании) нужно сравнивать ОБА указателя.
Если это прерывание возникнет между чтением данных в задаче и изменением соотв. указателя, то будет беда. Обнаружить ее крайне сложно.


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

Я делал это несколько иначе, использовал счетчик свободного места, вообще не сравнивая указатели. Это получается несколько быстрее, но отъедает немного места в памяти.
Обращение к этому счетчику и изменение соотв. указателей, должно быть непрерывным. Иначе - HF


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 9 2017, 19:37
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Forger @ Jun 9 2017, 20:04) *
Я делал это несколько иначе, использовал счетчик свободного места, вообще не сравнивая указатели. Это получается несколько быстрее, но отъедает немного места в памяти.
Обращение к этому счетчику и изменение соотв. указателей, должно быть непрерывным. Иначе - HF

Вот как раз со счётчиком - это плохая реализация, так как обязательно требует критической секции.
Реализация кольцевого буфера на двух указателях (один - чтения, другой - записи) для своей работы не требует критических секций при условии, что есть только один процесс/ядро- писатель и только один процесс/ядро- читатель. И это справедливо только для этих процессов. Т.е. - не требуется ни для чего - ни для вычисления свободного места ни для вычисления уровня заполнения и т.п.
Если состояние кольца читается 3-ей стороной (процессом/ядром отличным от читателя и писателя), то для этого критическая секция нужна.
А в читателе и писателе - нет. Так как каждый из них модифицирует только один указатель, а второй указатель использует только на чтение.

Цитата(Forger @ Jun 9 2017, 21:18) *
Если в этот момент мы начали сравнивать два указателя (или читать некий счетчик свободного/занятого места), то к моменту сравнения он будет неактуальным - ведь в прерывании выше он уже изменился.

Ну и что что станет неактуальным?
Допустим пишущий процесс считал указатель чтения и, пока он его анализировал, произошло прерывание чтения, которое убавило данных из буфера. Ну и что? От этого работа кольца не разрушится. Просто пишущий процесс в этот момент будет думать что данных в кольце больше чем уже есть. Ну и что? Это не приведёт ни к каким сбоям. Вот если-б он думал что данных меньше чем там есть - вот это бы привело к разрушению работы. Но это невозможно по алгоритму.
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 9 2017, 20:44
Сообщение #21


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(jcxz @ Jun 9 2017, 22:37) *
Допустим пишущий процесс считал указатель чтения и, пока он его анализировал, произошло прерывание чтения, которое убавило данных из буфера.

Все будет хорошо, пока очередь не исчерпается - совпадут указатели головы и хвоста.

Поясню.
Скажем в очереди остался всего один элемент.
Нужно туда положить еще один, он последний в отправляемом пакете.
Кладем его в голову очереди, далее должны сдвинуть указатель головы, но не успели - произошло прерывание передатчика.
В нем мы видим, что очередь непустая (сравнили два указателя), еще есть один элемент. Но всего один.
Отправляем его, сдвигаем хвост. Видим, что хвост и голова совпали - прекращаем передачу и формируем соотв. сообщение.
Возвращаемся из прерывания, сдвигаем голову вперед на один.
Ждем сообщения об окончании всей передачи, в том числе и этого последнего байта.
Успешно его дожидаемся, ведь передача была только что прекращена.
В итоге последний элемент данных не был отправлен.

В следующем пакете он будет отправлен, но он попадет в начало след. пакета.
В пакетных протоколах эта ситуация недопустима - нарушается содержимое пакетов, если, конечно, имеют значения интервалы между пакетами и между элементами данных.
Простой пример - пакетная передача по USART обычными байтами.

Понимаю, ситуация редкая и очень трудноуловимая, но она вполне возможна.
Именно для исключения таких ситуаций запись в очередь и сдвиг соотв. указателя должны быть атомарными.
Если это реализуется атомарно на аппаратном уровне, то действительно никакие критические секции тут ни к чему.


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 9 2017, 20:58
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Forger @ Jun 9 2017, 22:44) *
Понимаю, ситуация редкая и очень трудноуловимая, но она вполне возможна.

Это не редкая ситуация. Это вообще не имеет никакого отношения к работе кольцевого буфера.
Кольцевой буфер - это только кольцевой буфер, а Вы описываете случай его использования для некоей задачи.
Эта задача реализована неправильно. К работе кольца это отношения не имеет.
Так можно предположить что и в процессе передачи вашего пакета, пишущий процесс не успеет дописать достаточно данных в буфер в любом месте, а не только в последнем байте. И в любом месте будет сбой.
Это просто неправильная реализация процесса передачи, а не кольцевого буфера.
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 9 2017, 21:15
Сообщение #23


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(jcxz @ Jun 9 2017, 23:58) *
К работе кольца это отношения не имеет.
Да неужели?
Речь тут как раз про возвожность разорвать атомарную операцию записи в буфер обработчиком, который к этому же очереди и обращается.
Пусть заполнение буфера и передача обращаются к разным указателям, но как минимум факт исчерпания очереди требует чтения обоих указателей.
Поэтому операция записи по указателю и его инкремента должна быть атомарной.
Либо не использовать прерывания.

Цитата
Так можно предположить что и в процессе передачи вашего пакета, пишущий процесс не успеет дописать достаточно данных в буфер в любом месте, а не только в последнем байте. И в любом месте будет сбой.

При чем тут не успеет дописать? В том примере все как раз и успевается и места в буфере полно.
Передача производится одновременно с заполнением буфера новыми данными. Вполне обычная ситуация.
Иначе хватило бы обычного массива, который заранее набивается данными, запускается передача и пока массив не будет весь передан, не будет новой передачи.
Тогда тут действительно нафик не нужен кольцевой буфер.



Цитата(jcxz @ Jun 10 2017, 00:10) *
flush() в читающем процессе: Ring::flush() { rpos = wpos; } - однозначно очистка атомарна без всяких крит. секций

Нет, неатомарна - обычная операция чтение-модификация-запись. Может быть прервана прям посреди.
Или же прервать другое обращением к этим же полям в фоне задач.
Ее нельзя вызывать в фоне задач, пока активно и разрешено соотв. прерывание.

Цитата
"Реальный код" не ограничивается только передачами по каналу связи. И далеко не везде нужен flush(). Даже скорей - редко где нужен. имха

Он нужен лишь при аварийных ситуациях, в штатном коде он действительно не нужен.
Я описал устройство, которое работает долго и без обслуги. Если повиснет и не сможет себя привести в норму самостоятельно, то беда будет (((


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- _lexa_   __LDREX __STREX в STM32F407   Jun 4 2017, 13:18
- - jcxz   Цитата(_lexa_ @ Jun 4 2017, 15:18) что я ...   Jun 4 2017, 17:10
|- - _lexa_   Цитата(jcxz @ Jun 4 2017, 17:10) STREX вс...   Jun 4 2017, 18:39
|- - KnightIgor   Цитата(_lexa_ @ Jun 4 2017, 19:39) Где-то...   Jun 4 2017, 19:34
||- - _lexa_   Цитата(KnightIgor @ Jun 4 2017, 19:34) .....   Jun 4 2017, 20:14
||- - KnightIgor   Цитата(_lexa_ @ Jun 4 2017, 21:14) Интере...   Jun 4 2017, 21:14
||- - AHTOXA   Цитата(KnightIgor @ Jun 5 2017, 02:14) Бл...   Jun 5 2017, 05:38
||- - Forger   Цитата(AHTOXA @ Jun 5 2017, 08:38) А в чё...   Jun 5 2017, 08:17
|||- - AHTOXA   Цитата(Forger @ Jun 5 2017, 13:17) Полага...   Jun 5 2017, 08:22
||||- - Forger   Цитата(AHTOXA @ Jun 5 2017, 11:22) Если, ...   Jun 5 2017, 08:24
||||- - AHTOXA   Цитата(Forger @ Jun 5 2017, 13:24) Почему...   Jun 5 2017, 08:54
|||- - jcxz   Цитата(Forger @ Jun 5 2017, 10:17) Полага...   Jun 5 2017, 08:49
|||- - Forger   Цитата(jcxz @ Jun 5 2017, 11:49) Так обра...   Jun 5 2017, 09:11
|||- - jcxz   Цитата(Forger @ Jun 5 2017, 11:11) Как ра...   Jun 5 2017, 09:37
|||- - Forger   Цитата(jcxz @ Jun 5 2017, 12:37) Вот имен...   Jun 5 2017, 09:49
|||- - jcxz   Цитата(Forger @ Jun 5 2017, 11:49) Выходи...   Jun 5 2017, 10:59
|||- - Forger   Цитата(jcxz @ Jun 5 2017, 13:50) Надо тол...   Jun 5 2017, 11:00
||||- - jcxz   Цитата(Forger @ Jun 5 2017, 13:00) Не пон...   Jun 5 2017, 11:09
||||- - Forger   Цитата(jcxz @ Jun 5 2017, 14:09) Так как ...   Jun 5 2017, 11:18
||||- - Forger   Попался полезный документ по теме: http://infocent...   Jun 5 2017, 12:22
|||||- - _lexa_   Цитата(Forger @ Jun 5 2017, 12:22) Попалс...   Jun 5 2017, 13:55
||||- - jcxz   Цитата(Forger @ Jun 5 2017, 13:18) Речь к...   Jun 5 2017, 13:47
|||- - _lexa_   Цитата(jcxz @ Jun 5 2017, 10:59) А что та...   Jun 5 2017, 13:26
|||- - AHTOXA   Цитата(_lexa_ @ Jun 5 2017, 18:26) В тако...   Jun 5 2017, 13:51
|||- - jcxz   Цитата(_lexa_ @ Jun 5 2017, 15:26) ...   Jun 5 2017, 14:21
|||- - scifi   Цитата(jcxz @ Jun 5 2017, 17:21) Изучать ...   Jun 5 2017, 14:31
||||- - AVI-crak   Начали за упокой, кончили за здравие. Как уже был...   Jun 5 2017, 17:37
||||- - jcxz   Цитата(AVI-crak @ Jun 5 2017, 19:37)...   Jun 5 2017, 21:35
||||- - _lexa_   Цитата(jcxz @ Jun 5 2017, 21:35) Похоже В...   Jun 5 2017, 23:19
||||- - AVI-crak   Цитата(jcxz @ Jun 6 2017, 03:35) Монитор ...   Jun 6 2017, 07:24
|||||- - jcxz   Цитата(AVI-crak @ Jun 6 2017, 09:24)...   Jun 6 2017, 08:20
|||||- - _lexa_   Цитата(jcxz @ Jun 6 2017, 08:20) Открывае...   Jun 6 2017, 20:56
|||||- - Alechek   Цитата(jcxz @ Jun 6 2017, 13:20) Фантазии...   Jun 7 2017, 08:31
|||||- - jcxz   Цитата(Alechek @ Jun 7 2017, 10:31) Опять...   Jun 7 2017, 08:56
||||- - KnightIgor   Цитата(jcxz @ Jun 5 2017, 22:35) Ну навер...   Jun 6 2017, 10:22
||||- - AVI-crak   Цитата(jcxz @ Jun 6 2017, 14:20) 1. зачем...   Jun 6 2017, 11:02
|||||- - KnightIgor   Цитата(AVI-crak @ Jun 6 2017, 12:02)...   Jun 6 2017, 20:34
|||||- - jcxz   Цитата(KnightIgor @ Jun 6 2017, 22:34) Ра...   Jun 6 2017, 21:36
|||||- - LightElf   QUOTE (jcxz @ Jun 7 2017, 00:36) Я писал ...   Jun 7 2017, 11:52
|||||- - Forger   Цитата(LightElf @ Jun 7 2017, 14:52) А пр...   Jun 7 2017, 12:39
|||||- - jcxz   Цитата(Forger @ Jun 7 2017, 14:39) Причем...   Jun 7 2017, 13:13
|||||- - Forger   Цитата(jcxz @ Jun 7 2017, 16:13) чтобы, е...   Jun 7 2017, 13:27
||||- - jcxz   Цитата(KnightIgor @ Jun 6 2017, 12:22) То...   Jun 6 2017, 12:08
|||- - _lexa_   Цитата(jcxz @ Jun 5 2017, 14:21) Видимо э...   Jun 5 2017, 17:40
|||- - AVI-crak   Цитата(_lexa_ @ Jun 5 2017, 23:40) Спасиб...   Jun 5 2017, 18:00
|||- - _lexa_   Цитата(AVI-crak @ Jun 5 2017, 18:00)...   Jun 5 2017, 19:28
||- - KnightIgor   Цитата(AHTOXA @ Jun 5 2017, 06:38) А в чё...   Jun 5 2017, 12:40
||- - jcxz   Цитата(KnightIgor @ Jun 5 2017, 14:40) Ес...   Jun 5 2017, 13:57
|||- - KnightIgor   Цитата(jcxz @ Jun 5 2017, 14:57) У меня ...   Jun 5 2017, 19:42
||- - AHTOXA   Цитата(KnightIgor @ Jun 5 2017, 17:40) Ка...   Jun 5 2017, 13:58
|- - jcxz   Цитата(_lexa_ @ Jun 4 2017, 20:39) Где-то...   Jun 5 2017, 07:49
|- - _lexa_   Цитата(jcxz @ Jun 5 2017, 07:49) Если меж...   Jun 5 2017, 10:17
|- - Alechek   ЦитатаНе тот мануал открываете Ну почему же не тот...   Jun 7 2017, 09:18
|- - jcxz   Цитата(Alechek @ Jun 7 2017, 11:18) Про у...   Jun 7 2017, 09:29
|- - Alechek   Цитата(jcxz @ Jun 7 2017, 14:29) В смысле...   Jun 7 2017, 10:21
|- - scifi   Цитата(Alechek @ Jun 7 2017, 13:21) В смы...   Jun 7 2017, 10:27
|- - jcxz   Цитата(Alechek @ Jun 7 2017, 12:21) В смы...   Jun 7 2017, 11:23
- - Alechek   Цитата(scifi @ Jun 7 2017, 15:27) Это наз...   Jun 7 2017, 12:22
|- - scifi   Цитата(Alechek @ Jun 7 2017, 15:22) Сдела...   Jun 7 2017, 12:50
|- - AHTOXA   Цитата(Alechek @ Jun 7 2017, 17:22) А поп...   Jun 7 2017, 13:30
- - Alechek   AHTOXA, спасибо, ознакомился. Но, опять противореч...   Jun 8 2017, 05:01
|- - jcxz   Цитата(Alechek @ Jun 8 2017, 07:01) - LDR...   Jun 8 2017, 06:17
|- - AHTOXA   Цитата(Alechek @ Jun 8 2017, 10:01) - LDR...   Jun 8 2017, 06:21
|- - LightElf   QUOTE (AHTOXA @ Jun 8 2017, 09:21) Именно...   Jun 8 2017, 13:44
|- - AHTOXA   Цитата(LightElf @ Jun 8 2017, 18:44) Есть...   Jun 8 2017, 14:52
|||- - Шаманъ   Цитата(Forger @ Jun 9 2017, 21:04) И само...   Jun 9 2017, 18:54
|||- - Forger   Цитата(jcxz @ Jun 9 2017, 22:31) Вот как ...   Jun 9 2017, 19:39
||||- - jcxz   Цитата(Forger @ Jun 9 2017, 21:39) Самое ...   Jun 9 2017, 20:27
||||- - jcxz   Цитата(Forger @ Jun 9 2017, 23:15) Пусть ...   Jun 9 2017, 21:20
|||||- - Forger   Цитата(jcxz @ Jun 10 2017, 00:17) Ещё раз...   Jun 9 2017, 21:20
|||||- - Forger   Цитата(jcxz @ Jun 10 2017, 00:20) Да хоть...   Jun 9 2017, 21:27
||||- - jcxz   Цитата(Forger @ Jun 9 2017, 23:15) При че...   Jun 9 2017, 21:24
|||- - Forger   Кстати, при очистке очереди изменяются оба указате...   Jun 9 2017, 20:59
|||- - jcxz   Цитата(Forger @ Jun 9 2017, 22:59) Кстати...   Jun 9 2017, 21:10
||- - jcxz   Цитата(Forger @ Jun 9 2017, 19:23) А в фо...   Jun 9 2017, 19:18
||- - Forger   Цитата(jcxz @ Jun 9 2017, 22:12) И в фоно...   Jun 9 2017, 19:18
|- - AVI-crak   Защищённый режим: стек для потоков psp, стек для п...   Jun 9 2017, 14:38
- - AHTOXA   Цитата(Alechek @ Jun 8 2017, 16:54) Вобще...   Jun 8 2017, 13:39
2 страниц V   1 2 >


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 18:38
Рейтинг@Mail.ru


Страница сгенерированна за 0.02068 секунд с 7
ELECTRONIX ©2004-2016