|
|
  |
volatile указатель |
|
|
|
Jan 16 2014, 09:44
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045

|
Вы немного перепутали: - указатель на переменную типа volatile - volatile unsigned int *ptr; - volatile указатель - unsigned int * volatile ptr; Что у вас изменяется вне программы? Указатель на регистр или значение регистра? Полезное чтиво по чтению объявлений переменных -> http://www.unixwiz.net/techtips/reading-cdecl.html
|
|
|
|
|
Jan 16 2014, 11:33
|
Частый гость
 
Группа: Участник
Сообщений: 181
Регистрация: 26-07-10
Пользователь №: 58 606

|
Цитата(msalov @ Jan 16 2014, 12:44)  Вы немного перепутали: ... Да, согласен. По Вашей ссылке посмотрю описание. Я читал вот эту статью - volatile_for_chainiks.pdf. И, если я правильно понял, автор советует всегда использовать в качестве аргумента функции указатель на volatile переменную. При этом сама переменная представляет собой регистр аппаратуры, который объявлен как volatile. Функция должна сделать некоторые действия над содержимым аппаратного регистра (почитать, модифицировать, записать), может вернуть его значение. Для того, что бы все действия функции над содержимым аппаратного регистра не оптимизировались компилятором мы и должны использовать в качестве аргумента указатель на volatile переменную. При вызове функции просто передается адрес и никаких действий над ним в других модулях программы не предполагается. Например делаем конфигурацию различных каналов UART.
|
|
|
|
|
Jan 16 2014, 11:58
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(skyv @ Jan 16 2014, 13:33)  И, если я правильно понял, автор советует всегда использовать в качестве аргумента функции указатель на volatile переменную. "всегда" тут неуместно. Или вы не поняли, или мы вас. Если вы хотите передавать указатель на переменную, которая является volatile - вы должны параметр функции объявить как "указатель на volatile-переменную" (volatile int * param или int volatile * param, что одно и то же). Если же вы хотите передавать указатель на обычную переменную - вы должны передавать указатель на обычную переменную. Не нужно считать компилятор дурнее себя - в подавляющем большинстве случаев оказыается наоборот. Цитата(skyv @ Jan 16 2014, 13:33)  Функция должна сделать некоторые действия над содержимым аппаратного регистра (почитать, модифицировать, записать), может вернуть его значение. В этом случае да. Но! Обычно в подобную функцию передается указатель на структуру, описывающую все регистры модуля периферии. И каждый из регитров описан как volatile. Вот в этом случае указатель на структуру не нужно объявлять как volatile - ибо сама структура не является volatile. Члены ее - да, а сама она - нет.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 16 2014, 13:48
|
Частый гость
 
Группа: Участник
Сообщений: 181
Регистрация: 26-07-10
Пользователь №: 58 606

|
Цитата(Сергей Борщ @ Jan 16 2014, 14:58)  "всегда" тут неуместно. ... Применительно к моему исходному вопросу я однозначно указал, что рассматриваю работу функции с регистром аппаратуры, который объявлен как volatile. По крайней хотел рассмотреть только этот вариант. По поводу применения указателей на структуру это, на мой взгляд, однозначно зависит от того как объявлены регистры аппаратуры в h файле на CPU. Так, к примеру, для различных ARMов регистры той или иной аппаратуры контроллера упакованы в соответствующие структуры, а вот если посмотреть на объявления для dsPIC, то там такого добра нет. В этом случае и приходится работать не через указатели на структуры, а через указатели на регистры.
|
|
|
|
|
Jan 16 2014, 14:57
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(skyv @ Jan 16 2014, 15:48)  Применительно к моему исходному вопросу я однозначно указал, что рассматриваю работу функции с регистром аппаратуры, который объявлен как volatile. Вот ваше сообщение: Цитата(skyv @ Jan 16 2014, 13:33)  И, если я правильно понял, автор советует всегда использовать в качестве аргумента функции указатель на volatile переменную. В конце стоит точка. Предложение (=мысль) закончилось. А вот если объединить со следующим предложением: Цитата(skyv @ Jan 16 2014, 13:33)  При этом сама переменная представляет собой регистр аппаратуры, который объявлен как volatile. то смысл пропадает совсем. Компилятор не позволит вам без грязных хаков (явных приведений типов) присвоить адрес volatile-переменной указателю на обычную (не-volatile) переменную. Что же тогда советует автор? Не нарушать правила языка? Так это очевидно, для этого не нужно статьи писать.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 16 2014, 15:27
|
Частый гость
 
Группа: Участник
Сообщений: 181
Регистрация: 26-07-10
Пользователь №: 58 606

|
Цитата(Сергей Борщ @ Jan 16 2014, 18:57)  ... Компилятор не позволит вам без грязных хаков (явных приведений типов) присвоить адрес volatile-переменной указателю на обычную (не-volatile) переменную. Что же тогда советует автор? Не нарушать правила языка? Так это очевидно, для этого не нужно статьи писать. Вот именно в этом и вопрос, что же советует автор в своей статье в п. 2.1.4. Аргумент функции.
|
|
|
|
|
Jan 16 2014, 18:05
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(skyv @ Jan 16 2014, 17:27)  Вот именно в этом и вопрос, что же советует автор в своей статье в п. 2.1.4. Аргумент функции. Кто ж его знает... Хотя... Проверил - Си допускает неявное приведение, но выдает предупреждение: Код volatile int A; main() { int * ptr = &A; }
main.c: In function 'main': main.c:6:17: warning: initialization discards 'volatile' qualifier from pointer target type [enabled by default] int * ptr = &A; Плюсы в этом смысле более строги: Код main.cpp: In function 'int main()': main.cpp:7:17: error: invalid conversion from 'volatile int*' to 'int*' [-fpermissive] int * ptr = &A;
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 17 2014, 10:45
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Tarbal @ Jan 17 2014, 02:06)  Поскольку параметры функции не будут оптимизироваться подобным образом, то писать volatile для параметра не обязательно. Сам параметр (в этой дискуссии - указатель на переменную) меняться не будет, безусловно. И поэтому не "необязательно", а "не нужно совсем" - чтобы не плодить большие медленные программы. А вот та переменная, на которую указатель указывает (в этой дискуссии - регистр специального назначения, SFR), измениться может. И об этом компилятору надо сообщить. Поэтому такой параметр должен быть указателем на volatile-переменную. Цитата(Rst7 @ Jan 17 2014, 12:09)  Например регистр, содержащий адрес пересылки DMA, и есть такой volatile-указатель. Но в Си такой регистр нельзя передать как параметр в функцию. Можно или передать его значение на момент вызова функции, либо указатель на него. При этом такой указатель будет все время указывать на регистр адреса пересылки DMA, т.е. не изменится. В Си с плюсами регистр можно передать в функцию в виде ссылки и вот тут да, это будет чистый и честный volatile-указатель. Однако в плюсах компилятор не даст потерять volatile при объявлении ссылки, то есть предмет споров пропадает.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|