Программист читая регистр знает, что должно генериться прерывание, возможно именно для этого он его и читает, а без volatile результат непредсказуем...
это программист. программист всеми силами стремится в ногу не стрелять. опасность подстерегает "не совсем программиста" который может думать, что бессмысленное чтение ни на что не влияет.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Что-то у меня подозрение, что в мою сторону камни. Но я там был именно за понимание всего механизма работы с volatile, опциями оптимизатора, для чего, почему и как. А не за бездумное использование.
лично я никаких камней не кидаю. volatile мешает оптимизатору. помогает ли программиступисателю программ - это вопрос другой.
например, постоянно можно услышать, что все переменные, изменяемые в прерываниях, должны быть volatile... это не так. НЕ ВСЕ, а только те, которые в том нуждаются. просто надо понимать, какие нуждаются, а какие нет. если не выжимать до последнего байта всю память, то можно ставить volatile бездумно, попасть на "предсказанный" мной вариант ошибки будет редким "везением"...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Да и вообще, почему что-то быть именно должно? я вот не очень командный игрок, чаще один. Внутри команды да, есть соглашения, их все придерживаются, единый стиль, это тоже удобно. Но когда один работаю с 8-битными мк, у меня идет смесь Си с ассемблером. Ну, привычка такая, мне раньше часто доставалось от ошибок оптимизатора (да, именно его ошибок, которые впоследствии официально признавались и фиксились, а не от того, что я недоволатилил), да и мне нравится эдакое соревнование, могу ли изначально слепить оптимальный код, который оптимизатор не сможет оптимизировать. На простых задачах это не отнимает много времени и доставляет удовольствие. Поэтому, я против догм. Да, программист обязан знать все тонкости volatile и если глянуть на ссылку, что я приводил в той ветке и на первый пост этой ветки а так же замечаний ARV, ну никак не обойтись короткой фразой. Но применение не должно быть догмой, предложение о применении необходимо сопровождать разъяснением, почему. Потому что "оптимизатор всегда вкл" тоже не обязано быть догмой. И это мы вообще рассуждаем о фундаментальном сферическом, а вот в частном случае с частным компилятором вообще всё может быть не так. Тоже чтение регистров, например. У меня вот компилятор космика не выкидывает "пустое в никуда" неволатильное чтение регистра. Хотя, глядя на код, мне хочется его выкинуть самому. Ну вот какая-то такая мысль. Извините, если сумбурно - малость с похмелья.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
volatile мешает оптимизатору. помогает ли программиступисателю программ - это вопрос другой.
volatile не мешает оптимизатору. Он просто делает обращение к конкретной ячейке памяти предсказуемыми. И только.
Да, помогает. Но для этого пИсатель программ должен знать к какой ячейке надо обращаться особо (регистр там или в прерывании задействована), а какая просто ячейка, которую можно отдать на откуп оптимизатору.
Применение volatile, равно как и других инструментов, не отменяет необходимости думать головой. Это главное правило. Компилятор думать за программиста не будет.
Добавлено after 1 hour 21 minute 23 seconds: кстати, кому не нравится volatile, то вот способ обхода. Пишите две функции (пример для байтовой ячейки) в виде отдельной библиотеки.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Компилятор такое и не компилирует, по крайней мере gcc
Замечательно комплирует. Сейчас проверил. Там почемуто амперсанды лишние из редактора копирнулись. Убрал. Если функции делать в виде отдельной либы - то работает всё именно как задумано.
Адепты мантры - «а у меня и так работает» - часто нарываются на очень неожиданное поведение кода в самый неподходящий момент времени. Удачи им в скачке по граблям.
вот именно, что "эмм"... в стандарте полно мест, которые "на усмотрение реализаторов компилятора" к тому же мало кто видел этот стандарт на русском языке...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Я на AVR Си не применяю, но вот любопытная ситуация произошла. На родственном форуме у студента возникла прооблема с точками "остановки". Я по доброте душевной , хоть в этом и не шибко секу, посоветовал ему обратить взор на volatile - не исключено, что компилятор оптимизнул - выбросил этот бессмысленный с его точки зрения фрагмент. СпойлерНужна помощь! При составление программы на языке С+ возникает проблема с точками остановки. Может кто подскажет что я делаю не так. Код: #include "compiler.h" #include <avr/interrupt.h> #include "conf_example.h"
// Only use Pin Change Interrupt handler for devices supporting this. #ifdef EXAMPLE_PCINT_vect
ISR(EXAMPLE_PCINT_vect) {
PIND = (1 << PIND0); }
#endif
int main(void) {
uint8_t val;
DDRD = 0xff;
// Set output levels high. Will turn off STK600 LEDs. PORTD = 0xff;
// Set output levels low. Will turn on STK600 LEDs. PORTD = 0;
PORTB = 0xff;
val = PINB;
while (1) { PORTD |= (1 << PORTD0);
PORTD &= ~(1 << PORTD0); } } А мне стало интересно: как "заволатилить" порт?
Так что моя версия - ошибочная ? А как же тогда в примере SfS (от 16.01) из-за UDR произошёл такой казус? Ведь UDR - это тоже регистр. Хотя чисто по логике, может, не в volatile дело? Загрузив байт в UDR, следовало бы дождаться флага готовности перед загрузкой следующего. Ну а стьюденьт тоже зря лил слёзы. Загрузил в Студию hex - и всё видно, что оно там накомпиляло. ---------- СпойлерПравильно говорит мне мой кот Мурзик: "Не занимайся фигнёй. Хочешь написать для AVR - ну ты же на асме - как на родном
Я на AVR Си не применяю, но вот любопытная ситуация произошла. На родственном форуме у студента возникла прооблема с точками "остановки". Я по доброте душевной , хоть в этом и не шибко секу, посоветовал ему обратить взор на volatile - не исключено, что компилятор оптимизнул - выбросил этот бессмысленный с его точки зрения фрагмент. СпойлерНужна помощь! При составление программы на языке С+ возникает проблема с точками остановки. Может кто подскажет что я делаю не так. Код: #include "compiler.h" #include <avr/interrupt.h> #include "conf_example.h"
// Only use Pin Change Interrupt handler for devices supporting this. #ifdef EXAMPLE_PCINT_vect
ISR(EXAMPLE_PCINT_vect) {
PIND = (1 << PIND0); }
#endif
int main(void) {
uint8_t val;
DDRD = 0xff;
// Set output levels high. Will turn off STK600 LEDs. PORTD = 0xff;
// Set output levels low. Will turn on STK600 LEDs. PORTD = 0;
PORTB = 0xff;
val = PINB;
while (1) { PORTD |= (1 << PORTD0);
PORTD &= ~(1 << PORTD0); } } А мне стало интересно: как "заволатилить" порт?
Не очень понятно о каком именно фрагменте речь.
val - обычная переменная и компилер может её выбрасить, как неиспользуемую. Всё по правилам.
PORTx и PINx - волатильные. Их не должен выбросить.
Так что моя версия - ошибочная ? А как же тогда в примере SfS (от 16.01) из-за UDR произошёл такой казус? Ведь UDR - это тоже регистр. Хотя чисто по логике, может, не в volatile дело? Загрузив байт в UDR, следовало бы дождаться флага готовности перед загрузкой следующего.
Мои примеры - абстрактные - НЕ ДЛЯ AVR. И там оговорено, что UDR - это регистр записи-чтения FIFO-буфера.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 30
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения