Перейти к содержанию
    

6 hours ago, Darth Vader said:

забить на предупреждение компилятора

Считаю, что это недопустимо. Я даже в IAR проектах добавляю опцию --warnings_are_errors, когда все предупреждения компилятор трактует как ошибки и не даёт возможность скомпилировать проект.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, artemkad сказал:

аргумент как - "никто кроме функции её не поменяет".

А вот таких квалификаторов я не знаю. Это что-то новое.

Аргумент типа указатель на константу в объявлении (прототипе) функции значит, что "эта функция его не изменяет" (причем не аргумент-указатель, а объект, на который он указывает). Не более того. О константности и неизменности аргумента вне тела этой функции он не говорит ничего. Он может быть как константным, так и нет, и изменяться вне тела функции сколько угодно много раз.

 

Изменено пользователем Darth Vader

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Darth Vader сказал:

А вот таких квалификаторов я не знаю. 

Это относится ко всем переменным не имеющим квалификатора volatile. Внутри функции они сами не меняются. Нет никакого прерывания DMA или другого потока который может внутри кода функции такую переменную изменить без её ведома.

ЗЫ. Кстати, че-то мне кажется что в CV (const char *p) это указатель на константу размещенную во флеше, а ему пытаются подсунуть указатель на переменную в оперативке... Куда этот указатель будет указывать - хз.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 часов назад, artemkad сказал:

а аргумент как - "никто кроме функции её не поменяет".

Вообще-то аргумент означает: "функция не меняет значение, адресуемое данным указателем". Почувствуйте разницу!

 

1 час назад, artemkad сказал:

Нет никакого прерывания DMA или другого потока который может внутри кода функции такую переменную изменить без её ведома.

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

Это про все переменные, порядок доступа к которым нельзя оптимизировать (изменить).

Например: Даже если регистры какой-то периферии используются только одной задачей, то их всё равно следует объявлять с volatile. Чтобы, например, если идёт работа с регистрами, чувствительными к чтению, оптимизатор не мог поменять порядок доступа к регистрам, нарушив таким образом алгоритм работы программы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, jcxz сказал:

Например: Даже если регистры какой-то периферии используются только одной задачей, то их всё равно следует объявлять с volatile.

Регистры периферии так-же могут меняться в любой момент без ведома этой задачи. Эти регистры меняются исходя из логики работы контроллера или внешних событий, а не только из логики программы. Потому и volatile.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 минут назад, artemkad сказал:

Регистры периферии так-же могут меняться в любой момент без ведома этой задачи. Эти регистры меняются исходя из логики работы контроллера или внешних событий, а не только из логики программы. Потому и volatile.

Ещё раз: volatile не только потому что регистры где-то ещё или кем-то меняются.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 минут назад, jcxz сказал:

Ещё раз: volatile не только потому что регистры где-то ещё или кем-то меняются.

Только потому.

9 минут назад, jcxz сказал:

А потому, что результат их чтения зависит от порядка этого чтения.

Это и есть "регистры меняются исходя из логики работы контроллера" о которой компилятор в общем случае ничего знать не может.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, artemkad сказал:

Это и есть "регистры меняются исходя из логики работы контроллера" о которой компилятор в общем случае ничего знать не может.

Пример: FIFO передатчика в любой периферии (UART/SPI/etc.) - данные в FIFO записываем, а никакие регистры при этом не меняются. Значит, следуя вашей логике, можно убрать volatile из описания регистра FIFO?

Тогда оптимизатор вправе поменять порядок записи в регистры FIFO как считает нужным. И логика работы программы нарушится. :unknw:

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 минут назад, jcxz сказал:

Пример: FIFO передатчика в любой периферии (UART/SPI/etc.) - данные в FIFO записываем, а никакие регистры при этом не меняются.

Как это - меняются регистры FIFO. Причем как они меняются компилятору создающему код ничего не известно. И их содержимое зависит не только от того, что туда записано, но и от внешних событий изымающих содержимое очереди и создателей этого самого FIFO и/или UART/SPI/etc. Естественно туда обязателен volatile именно из-за этого.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, artemkad сказал:

Как это - меняются регистры FIFO. Причем как они меняются компилятору создающему код ничего не известно.

В смысле - "неизвестно"? :wacko2: Они меняются в соответствии с записываемыми данными - что туда функция запишет, то там и будет. FIFO - это просто область ОЗУ, находящаяся в периферии.

1 час назад, artemkad сказал:

И их содержимое зависит не только от того, что туда записано, но и от внешних событий изымающих содержимое очереди и создателей этого самого FIFO и/или UART/SPI/etc.

Не обязательно. Передатчик может быть выключен во время записи. И ничто не "изымается". Но порядок записи всё равно важен.

1 час назад, artemkad сказал:

Естественно туда обязателен volatile именно из-за этого.

Так значит и для любой переменной вообще в ОЗУ нужен volatile? Если следовать вашей логике. Пишем в ОЗУ - значит её содержимое ведь меняется, значит нужен volatile, так что-ли?  :shok:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

31 минуту назад, jcxz сказал:

В смысле - "неизвестно"? 

Неизвестно компилятору. Например, ты сам-то сможешь однозначно сказать что получишь в ответ если прочитаешь только что записанный регистр FIFO?

31 минуту назад, jcxz сказал:

FIFO - это просто область ОЗУ,

 FIFO  это совсем не просто область ОЗУ, а область ОЗУ с кучей собственной логики работы которая, в частности, приводит к тому, что читаемые программой данные не совпадают  только что записанными. Т.е. с точки зрения компилятора это вообще не ОЗУ.

31 минуту назад, jcxz сказал:

Не обязательно. Передатчик может быть выключен во время записи. И ничто не "изымается".

Конечно обязательно. Даже если ничего не изымается чтение только что записанного в результате дает нечто совсем другое и зачастую даже из другого FIFO. Т.е. содержимое ячейки меняется самостоятельно по независимым от компилятора законам.

 

31 минуту назад, jcxz сказал:

Если следовать вашей логике. Пишем в ОЗУ - значит её содержимое ведь меняется, значит нужен , так что-ли? 

Это где-ж я такое написал? Пока содержимое ОЗУ зависит исключительно от логики программы - это обычные переменные. Такие переменные можно хоть в вечный цикл засунуть - они не поменяются пока контроллер не стукнуть чем ни будь тяжелым(например снятием питания). Как только они начинают зависеть от внешних факторов, событий или логики периферии контроллера о которых компилятор ничего не знает, эти уже volatile.

ЗЫ. Впрочем - volatile много не бывает ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, artemkad сказал:

Неизвестно компилятору. Например, ты сам-то сможешь однозначно сказать что получишь в ответ если прочитаешь только что записанный регистр FIFO?

TX-FIFO обычно недоступно для чтения программой.

Цитата

 FIFO  это совсем не просто область ОЗУ, а область ОЗУ с кучей собственной логики работы которая, в частности, приводит к тому, что читаемые программой данные не совпадают  только что записанными. Т.е. с точки зрения компилятора это вообще не ОЗУ.

Если часть ОЗУ запретить на чтение или на запись через MPU, оно перестанет быть ОЗУ??? :wacko2:  Ведь в этом случае также как FIFO его нельзя будет прочитать/записать или результат будет отличаться.

Если в ОЗУ контроллера имеется аппаратный контроль чётности например (или другой способ контроля содержимого) - это тоже по вашей логике не ОЗУ получается?  :biggrin:

Странная у вас какая-то логика....  :unknw:

Цитата

Конечно обязательно. Даже если ничего не изымается чтение только что записанного в результате дает нечто совсем другое и зачастую даже из другого FIFO. Т.е. содержимое ячейки меняется самостоятельно по независимым от компилятора законам.

Не понимаю о каком чтении TX-FIFO говорите? В большинстве МК какие знаю - TX-FIFO недоступно для чтения. Вообще недоступно! Откройте мануал на любой МК с серьёзной периферией - просветитесь.

Цитата

Это где-ж я такое написал? Пока содержимое ОЗУ зависит исключительно от логики программы - это обычные переменные.

Если исходить из этого "определения", то ОЗУ во многих ARM-ах вообще не существует. :biggrin: Так как у них есть MPU, есть MMU, есть контроллеры динамической памяти, есть ОЗУ с контролем чётности и от всего этого там зависит содержимое ОЗУ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 minutes ago, jcxz said:

TX-FIFO обычно недоступно для чтения программой.

Наоборот, очень часто доступно. Встречал два поведения:

1) Всегда читаются нули

2) одни и те же адреса используются в качестве интерфейса TX FIFO (при записи в эти адреса) и RX FIFO (при чтении по этим же адресам)

 

15 minutes ago, jcxz said:

Если часть ОЗУ запретить на чтение или на запись через MPU, оно перестанет быть ОЗУ???

В большинстве случаев лучше считать, что ОЗУ вообще не существует. Есть процессор (с его системой команд, регистрами общего назначения, SFR, прерываниями)  и память. Просто память. Если нужно эту память как-то делить, это уже какая-то экзотика. Вы запретите запись через MPU? Нет, вы не запретите, запись исполнится процессором, но, в зависимости от настроек MPU (которая - периферия отображённая в память, т.е. с точки зрения процессора - опять же просто область памяти), результат этой записи может быть разным. И обработка таких событий опять же ограничивается обращениями в память и прерываниями.

Изменено пользователем one_eight_seven

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 минут назад, one_eight_seven сказал:

Наоборот, очень часто доступно. Встречал два поведения:

1) Всегда читаются нули

2) одни и те же адреса используются в качестве интерфейса TX FIFO (при записи в эти адреса) и RX FIFO (при чтении по этим же адресам)

Это и есть - недоступно. Если его нельзя прочитать, значит - недоступно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Just now, jcxz said:

Это и есть - недоступно. Если его нельзя прочитать, значит - недоступно.

Нет. Это значит доступно и исполняется. Недоступно - это если оно BusFault или HardFault вызовет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...