-
- Переполнения буфера быть не должно, переполнение означает порчу
данных. А так, я не вижу, в чём засада. При обмене используются два
кольцевых буфера, один на приём, другой на выдачу. В каждом три
волятильных параметра, голова, хвост и счётчик. По голове буфер
набивается, по хвосту очищается. Допустим, буфер 500 байт, набилось
100, можно передавать. Передаём длину "100" и байты, после
контрольную сумму. Приемник сообщил, что в пакете ошибка. Хорошо,
повторим. Смотрим на vpv.vpv(282 знак., 31.01.2023 07:48)
- формат пакета менять нельзя, и назначение буфера комбинированное - приёмный, и одновременно передающий. Заголовок формируется на лету, часть пакета из других данных, потом к нему приаттачивается этот буфер, и в конце контрольная сумма. Если было переполнение буфера (на самом деле контрольная точка за полсотни байт до конца), - формируется и передаётся заголовок с излишней длиной пакета, блок данных (в сумме около 40+ байт), а потом уже начинает передаваться кольцевой Adept(231 знак., 01.02.2023 12:05)
- Если платформа не поддерживает атомарный increment, то счётчик зло.
Число байт в буфере можно посчитать по голове, хвосту и размеру
кольцевого буфера. - пpocтoвacя(31.01.2023 07:53)
- Я ещё не встречал ни одной платформы, которая бы не поддерживала
атомарный инкремент. Просто надо не забывать его использовать.
Потому и написАл - три волятильных параметра. А динамический подсчёт байт в буфере.. наверное, можно
замутить, но я не вижу в этом смысла. - vpv.vpv(31.01.2023 08:36)
- А что дает волятильность? - register(31.01.2023 17:31, )
- Если писать на ассемблере самому, или на Си с выключеной
оптимизацией, - то волятильность ничего не даёт. Иначе компилятор
наоптимизирует так, что программа может перестать работать.
Например, объявлены две переменные, им присвоены значения, после
эти переменные проверяются, по результатам модифицируются порты.
Текст на Си: vpv.vpv(1347 знак., 01.02.2023 06:53)
- Выкинул и правильно сделал, потому что ваш пример неудачный. Вот
вам лучше пример, переделайте под ваш проц/компилятор/среду. И
давайте смотреть, что будет выкинуто С ОПТИМИЗАЦИЕЙ. Costic(284 знак., 01.02.2023 14:07)
- Будет выкинуто ровно то же самое. Я не поленился, даже скриншоты
сделал (для пущей достоверности :-)))) vpv.vpv(385 знак., 02.02.2023 09:21, картинка, картинка)
- Вот volatile работает, внутри while(1) постоянно загружают
переменную vol_c из памяти. А вы утверждали: "Если писать ...на Си
с выключеной оптимизацией, - то волятильность ничего не даёт." ДАЁТ
ЖЕ! - Costic(02.02.2023 14:38)
- Волатильность "не даёт", если нет оптимизаццыи. Когда оптимизация,
то "даёт". Со всем уважэнием. Именно это вам и показывают. - mse homjak(02.02.2023 21:14)
- Именно так. С выключенной оптимизацией компилятор IAR становится максимально тупым (превращается в "компилятор для полных идиотов" :-))), ему всё равно, волятильна переменная или нет, всё равно, что значение уже есть в регистре - он всякий раз заново её пишет в регистр перед отправкой в порт. Вот листинг того же самого с ВЫКЛЮЧЕННОЙ оптимизацией: vpv.vpv(1 знак., 03.02.2023 08:24, картинка)
- У меня есть компилятор, в котором даже "оптимизация" такая, что ей
эта волатильность по барабану. Туповат он по сегодняшним меркам, но
всё равно хороший :-) - SciFi(02.02.2023 21:25)
- Ну, как грица, "это не ваше умение, это наша недоработка"(С) А мог бы и бритвой по лицу... - mse homjak(02.02.2023 21:33)
- Волатильность "не даёт", если нет оптимизаццыи. Когда оптимизация,
то "даёт". Со всем уважэнием. Именно это вам и показывают. - mse homjak(02.02.2023 21:14)
- Вот volatile работает, внутри while(1) постоянно загружают
переменную vol_c из памяти. А вы утверждали: "Если писать ...на Си
с выключеной оптимизацией, - то волятильность ничего не даёт." ДАЁТ
ЖЕ! - Costic(02.02.2023 14:38)
- Будет выкинуто ровно то же самое. Я не поленился, даже скриншоты
сделал (для пущей достоверности :-)))) vpv.vpv(385 знак., 02.02.2023 09:21, картинка, картинка)
- Выкинул и правильно сделал, потому что ваш пример неудачный. Вот
вам лучше пример, переделайте под ваш проц/компилятор/среду. И
давайте смотреть, что будет выкинуто С ОПТИМИЗАЦИЕЙ. Costic(284 знак., 01.02.2023 14:07)
- Гарантию того, что переменная не будет в регистре размещаться и
всегда будет содержать актуальное значение, что важно, например, во
время прерываний. - Costic(31.01.2023 17:59)
- все ли 8-ми битники гарантируют атомарное чтение/запись
многобайтовых переменных, если во время операции произойдёт
прерывание? - пpocтoвacя(01.02.2023 08:30, )
- Про все - не знаю. А вот у Силабса команда (любая) должна закончить выполнение (не важно сколько тактов): Costic(172 знак., 01.02.2023 14:20)
- Ни один не гарантирует. - vpv.vpv(01.02.2023 13:42)
- все ли 8-ми битники гарантируют атомарное чтение/запись
многобайтовых переменных, если во время операции произойдёт
прерывание? - пpocтoвacя(01.02.2023 08:30, )
- Если писать на ассемблере самому, или на Си с выключеной
оптимизацией, - то волятильность ничего не даёт. Иначе компилятор
наоптимизирует так, что программа может перестать работать.
Например, объявлены две переменные, им присвоены значения, после
эти переменные проверяются, по результатам модифицируются порты.
Текст на Си: vpv.vpv(1347 знак., 01.02.2023 06:53)
- По моему на всех актуальных платформах инкремент делается через
чтение-модификацию-запись, то есть не атомарно по определению. Но
применительно к очереди в большинстве реализаций инкременты хвоста
и головы происходят в очень разных местах и споткнуться о
неатомарность не получится. - Nikolay801_(31.01.2023 10:00)
- Споткнуться очень получится. Например, я выгреб из буфера 10 байт,
и хочу уменьшить счётчик. Он равен 15. Читаю его, отнимаю 10,
получаю 5, и... В этот момент, проц отвлекается на прерывание, в
котором принимается байт и счётчик увеличивается на 1, становится
16. После возврата из П/П я пишу в него 5. Или двухбайтная голова,
к примеру, равна 0x00FF. Читаю младший байт, 0xFF. В этот момент
летит прерывание, и голова становится равной 0x0100. Читаю старший
байт, он уже 0x01. В vpv.vpv(119 знак., 31.01.2023 12:11)
- Не надо использовать счетчик, и двухбайтные индексы head/tail на
8-битнике не надо использовать. И все получится. - LightElf(31.01.2023 13:56 - 15:39)
- Это значит буфер не более 256 байт и тот в начале страницы
размещать. Тут у автора 500 байт. - Costic(31.01.2023 18:02)
- Пусть использует 10-битник - LightElf(01.02.2023 13:57)
- Если знать аппаратную часть процессора, как он устроен, и как
работает, то получится всё, что угодно. )) - vpv.vpv(31.01.2023 14:18)
- Все описанные вами проблемы имеют многократно проверенные решения
без критических секций. Но вольному - воля. - LightElf(31.01.2023 15:39)
- Многократно проверенные решения - это какие конкретно? Примеры
есть? Или это "Не использовать 8-ми битники"? :))) - vpv.vpv(01.02.2023 07:01)
- вот, образовывайтесь >>> SciFi(1 знак., 01.02.2023 08:46, ссылка)
- А, это... )) Да, известный трюк. Тут есть накладные расходы,
операции сравнивания, при КАЖДОМ обращении к переменной. Прерывание
внутрь атомарной операции может попасть в вероятностью 1/1000,
скажем. Здесь же будут постоянные тормоза, в 100% случаев. - vpv.vpv(01.02.2023 13:41)
- Тормоза? Вы куда-то опаздываете? - SciFi(01.02.2023 13:46)
- When how. Иногда от куска программы требуется и быстродействие
тоже. - vpv.vpv(02.02.2023 09:48)
- Бывает и такое. Но крайне редко. - SciFi(02.02.2023 09:52)
- When how. Иногда от куска программы требуется и быстродействие
тоже. - vpv.vpv(02.02.2023 09:48)
- Тормоза? Вы куда-то опаздываете? - SciFi(01.02.2023 13:46)
- А, это... )) Да, известный трюк. Тут есть накладные расходы,
операции сравнивания, при КАЖДОМ обращении к переменной. Прерывание
внутрь атомарной операции может попасть в вероятностью 1/1000,
скажем. Здесь же будут постоянные тормоза, в 100% случаев. - vpv.vpv(01.02.2023 13:41)
- многобитники тоже не гарантируют атомарность доступа к памяти,
например если переменная не выровнена. - вacяпpocтo(01.02.2023 08:36, )
- Есть множество способов выстрелить себе в ногу. Один из них - вмешиваться в выравнивание переменных. - LightElf(01.02.2023 13:59)
- вот, образовывайтесь >>> SciFi(1 знак., 01.02.2023 08:46, ссылка)
- Многократно проверенные решения - это какие конкретно? Примеры
есть? Или это "Не использовать 8-ми битники"? :))) - vpv.vpv(01.02.2023 07:01)
- Да, но жизнь скучна без риска! - SciFi(31.01.2023 14:19)
- Все описанные вами проблемы имеют многократно проверенные решения
без критических секций. Но вольному - воля. - LightElf(31.01.2023 15:39)
- Это значит буфер не более 256 байт и тот в начале страницы
размещать. Тут у автора 500 байт. - Costic(31.01.2023 18:02)
- Не надо использовать счетчик, и двухбайтные индексы head/tail на
8-битнике не надо использовать. И все получится. - LightElf(31.01.2023 13:56 - 15:39)
- Споткнуться очень получится. Например, я выгреб из буфера 10 байт,
и хочу уменьшить счётчик. Он равен 15. Читаю его, отнимаю 10,
получаю 5, и... В этот момент, проц отвлекается на прерывание, в
котором принимается байт и счётчик увеличивается на 1, становится
16. После возврата из П/П я пишу в него 5. Или двухбайтная голова,
к примеру, равна 0x00FF. Читаю младший байт, 0xFF. В этот момент
летит прерывание, и голова становится равной 0x0100. Читаю старший
байт, он уже 0x01. В vpv.vpv(119 знак., 31.01.2023 12:11)
- Пример: в потоке изменяешь голову, изменяешь счётчик, и в
прерывании изменяешь хвост, изменяешь счётчик, что может пойти не
так? пpocтoвacя(276 знак., 31.01.2023 09:42)
- Выше подробно расписал, что может случится. Я с этими кольцевыми
буферами уже 30 лет периодически сталкиваюсь, начиная с i8080.
:-)))) - vpv.vpv(31.01.2023 12:17)
- Заслуженный FIFOлог. Бывают ещё FILOлоги. - mr-x(31.01.2023 17:06)
- Ещё космические лучи могут залететь и вызвать сбой. Первым делом
свинцовую плиту сверху надо надвинуть. - SciFi(31.01.2023 09:49)
- фобос в грунт - ваше всё! - пpocтoвacя(31.01.2023 10:09)
- Выше подробно расписал, что может случится. Я с этими кольцевыми
буферами уже 30 лет периодически сталкиваюсь, начиная с i8080.
:-)))) - vpv.vpv(31.01.2023 12:17)
- А что дает волятильность? - register(31.01.2023 17:31, )
- Я ещё не встречал ни одной платформы, которая бы не поддерживала
атомарный инкремент. Просто надо не забывать его использовать.
Потому и написАл - три волятильных параметра. А динамический подсчёт байт в буфере.. наверное, можно
замутить, но я не вижу в этом смысла. - vpv.vpv(31.01.2023 08:36)
- Переполнения буфера быть не должно, переполнение означает порчу
данных. А так, я не вижу, в чём засада. При обмене используются два
кольцевых буфера, один на приём, другой на выдачу. В каждом три
волятильных параметра, голова, хвост и счётчик. По голове буфер
набивается, по хвосту очищается. Допустим, буфер 500 байт, набилось
100, можно передавать. Передаём длину "100" и байты, после
контрольную сумму. Приемник сообщил, что в пакете ошибка. Хорошо,
повторим. Смотрим на vpv.vpv(282 знак., 31.01.2023 07:48)