Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Пн янв 17, 2022 21:48:57
Reflector писал(а): Программист читая регистр знает, что должно генериться прерывание, возможно именно для этого он его и читает, а без volatile результат непредсказуем...
это программист. программист всеми силами стремится в ногу не стрелять. опасность подстерегает "не совсем программиста"
который может думать, что бессмысленное чтение ни на что не влияет.
Пн янв 17, 2022 22:00:45
Что-то у меня подозрение, что в мою сторону камни. Но я там был именно за понимание всего механизма работы с volatile, опциями оптимизатора, для чего, почему и как. А не за бездумное использование.
Пн янв 17, 2022 22:10:45
лично я никаких камней не кидаю.
volatile мешает оптимизатору.
помогает ли программиступисателю программ - это вопрос другой.
например, постоянно можно услышать, что все переменные, изменяемые в прерываниях, должны быть volatile... это не так. НЕ ВСЕ, а только те, которые в том нуждаются. просто надо понимать, какие нуждаются, а какие нет. если не выжимать до последнего байта всю память, то можно ставить volatile бездумно, попасть на "предсказанный" мной вариант ошибки будет редким "везением"...
Пн янв 17, 2022 23:39:06
Да и вообще, почему что-то быть именно должно? я вот не очень командный игрок, чаще один. Внутри команды да, есть соглашения, их все придерживаются, единый стиль, это тоже удобно. Но когда один работаю с 8-битными мк, у меня идет смесь Си с ассемблером. Ну, привычка такая, мне раньше часто доставалось от ошибок оптимизатора (да, именно его ошибок, которые впоследствии официально признавались и фиксились, а не от того, что я недоволатилил), да и мне нравится эдакое соревнование, могу ли изначально слепить оптимальный код, который оптимизатор не сможет оптимизировать.
На простых задачах это не отнимает много времени и доставляет удовольствие.
Поэтому, я против догм. Да, программист обязан знать все тонкости volatile и если глянуть на ссылку, что я приводил в той ветке и на первый пост этой ветки а так же замечаний ARV, ну никак не обойтись короткой фразой. Но применение не должно быть догмой, предложение о применении необходимо сопровождать разъяснением, почему. Потому что "оптимизатор всегда вкл" тоже не обязано быть догмой. И это мы вообще рассуждаем о фундаментальном сферическом, а вот в частном случае с частным компилятором вообще всё может быть не так. Тоже чтение регистров, например. У меня вот компилятор космика не выкидывает "пустое в никуда" неволатильное чтение регистра. Хотя, глядя на код, мне хочется его выкинуть самому.
Ну вот какая-то такая мысль. Извините, если сумбурно - малость с похмелья.
Вт янв 18, 2022 14:29:06
volatile мешает оптимизатору.
помогает ли программиступисателю программ - это вопрос другой.
volatile не мешает оптимизатору. Он просто делает обращение к конкретной ячейке памяти предсказуемыми. И только.
Да, помогает. Но для этого пИсатель программ должен знать к какой ячейке надо обращаться особо (регистр там или в прерывании задействована), а какая просто ячейка, которую можно отдать на откуп оптимизатору.
Применение volatile, равно как и других инструментов, не отменяет необходимости думать головой. Это главное правило. Компилятор думать за программиста не будет.
Добавлено after 1 hour 21 minute 23 seconds:кстати, кому не нравится volatile, то вот способ обхода. Пишите две функции (пример для байтовой ячейки) в виде отдельной библиотеки.
- Код:
#include <stdint.h>
uint8_t getByte(void* adr) {
return *((uint8_t*)adr);
}
void setByte(void* adr, uint8_t byte) {
*((uint8_t*)adr) = byte;
}
Использовать соответственно:
- Код:
a=getByte((void*)0xABCD); // Чтение из ячейки памяти с адресом 0xABCD
setByte((void*)0xABCD, 0xFE); // Запись байта 0xFE по адресу 0xABCD
Компилятор такое не оптимизирует. Но это для извратов:)
Последний раз редактировалось
SfS Вт янв 18, 2022 15:54:16, всего редактировалось 1 раз.
Вт янв 18, 2022 14:42:08
Компилятор такое не оптимизирует.
Компилятор такое и не компилирует, по крайней мере gcc
А если имелось в виду:
- Код:
*((uint8_t*)adr) = byte;
то такое замечательно оптимизируется.
Вт янв 18, 2022 16:08:20
Компилятор такое не оптимизирует.
Компилятор такое и не компилирует, по крайней мере gcc
Замечательно комплирует. Сейчас проверил. Там почемуто амперсанды лишние из редактора копирнулись. Убрал.
Если функции делать в
виде отдельной либы - то работает всё именно как задумано.
Но volatile - проще и правильней:)
Вт янв 18, 2022 16:22:10
Если функции делать в виде отдельной либы - то работает всё именно как задумано.
Проверяем, пишу:
- Код:
setByte((void*)&GPIOB->ODR, 0x55);
setByte((void*)&GPIOB->ODR, 0xAA);
При этом setByte() находится в другом .cpp файле. Получаем вполне ожидаемый результат:
- Код:
ldr r3, [pc, #516]
movs r2, #170 ; 0xaa
strb r2, [r3, #20]
Вт янв 18, 2022 16:31:40
Reflector писал(а):Получаем вполне ожидаемый результат
LTO?
Вт янв 18, 2022 16:37:15
Естественно LTO.
Вт янв 18, 2022 17:29:27
Я в виде двух объектных файлов скомпилил тоже под арм. И там в асме прекрасно сработало.
Отдельная библиотека это вообще архив объектников. Там можно и секции лишние стрипнуть.
Добавлено after 31 second:
Другое дело, чтов реальном проекте я так делать не буду:)
Вт янв 18, 2022 17:45:50
кстати, кому не нравится volatile
Чего??? Сегодня кому-то volatile не нравится, завтра const нелюб будет, а послезавтра что следующее?
Добавлено after 9 minutes 26 seconds:Адепты мантры - «а у меня и так работает» - часто нарываются на очень неожиданное поведение кода в самый неподходящий момент времени. Удачи им в скачке по граблям.
И там в асме прекрасно сработало.
А как дышал, как дышал
Вт янв 18, 2022 17:57:42
И там в асме прекрасно сработало.
А как дышал, как дышал
А как дышал?
Дышал ровно и выступал за стандарты:)
Но привел пример извращения. Почему не привести ради прикола и для оживления темы?
Но выше товарищи правы, с lto компилерами без отключения оного lto не прокатит. А я както и не написал об этом.
Ср янв 19, 2022 04:49:39
"Си — инструмент, острый, как бритва: с его помощью можно создать и элегантную программу, и кровавое месиво". © Керниган.
RTFM. Все остальное - на совести издателей конкретного компилятора. Дьявол всегда кроется в деталях (мелочах). Разговор ни о чем, IMHO.
Чт янв 20, 2022 09:38:52
RTFM. Все остальное - на совести издателей конкретного компилятора.
Ну почему?) Используйте стандарты) Они так.. эмм.. стандартны. И работают в любом компиляторе:)
Чт янв 20, 2022 11:32:37
SfS писал(а):Они так.. эмм.. стандартны
вот именно, что "эмм"... в стандарте полно мест, которые "на усмотрение реализаторов компилятора"
к тому же мало кто видел этот стандарт на русском языке...
Чт янв 20, 2022 14:46:24
Я на 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);
}
} А мне стало интересно: как "заволатилить" порт?
Чт янв 20, 2022 14:52:24
Jack_A писал(а):как "заволатилить" порт?
порт уже заволатилен
Чт янв 20, 2022 15:06:39
Так что моя версия - ошибочная ? А как же тогда в примере
SfS (от 16.01) из-за UDR произошёл такой казус? Ведь UDR - это тоже регистр. Хотя чисто по логике, может, не в volatile дело? Загрузив байт в UDR, следовало бы дождаться флага готовности перед загрузкой следующего.
Ну а стьюденьт тоже зря лил слёзы. Загрузил в Студию hex - и всё видно, что
оно там накомпиляло.
----------
Спойлер
Правильно говорит мне мой кот Мурзик: "Не занимайся фигнёй. Хочешь написать для AVR - ну ты же на асме - как на родном
Вс янв 23, 2022 06:33:57
Я на 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 - волатильные. Их не должен выбросить.
Добавлено after 2 minutes 4 seconds:Так что моя версия - ошибочная ? А как же тогда в примере SfS (от 16.01) из-за UDR произошёл такой казус? Ведь UDR - это тоже регистр. Хотя чисто по логике, может, не в volatile дело? Загрузив байт в UDR, следовало бы дождаться флага готовности перед загрузкой следующего.
Мои примеры - абстрактные - НЕ ДЛЯ AVR. И там оговорено, что UDR - это регистр записи-чтения FIFO-буфера.
Powered by phpBB © phpBB Group.
phpBB Mobile / SEO by Artodia.