Разница между (*(volatile unsigned int *) и (volatile unsigned int)?
Я просматривал учебные пособия по программированию STM32 без операционной системы. Я не мог понять назначение приведенного ниже кода
#define RCC_AHB1EN_R (*(volatile unsigned int *)(RCC_BASE + AHB1EN_R_OFFSET))
и почему это отличается от
#define RCC_AHB1EN_R (volatile unsigned int)(RCC_BASE + AHB1EN_R_OFFSET))
Я понимаю, что (volatile unsigned int *)
используется для приведения любых данных к типу, поэтому код получает значение своего адреса, а не сами данные, а затем добавляет (*)
выберет значение данных адреса. Я знаю, почему volatile используется, чтобы запретить оптимизировать этот код для этих данных.
Это мои базовые знания об указателях, если я до сих пор был не прав, поправьте меня.
Итак, мой вопрос:
Почему и какова цель приведения данных к адресу (указателю), а затем использовать его значение?
Почему бы нам не использовать само значение напрямую (конечно, с изменчивым приведением типов), например
#define RCC_AHB1EN_R (изменчивое целое число без знака)(RCC_BASE + AHB1EN_R_OFFSET))
- Если мы можем использовать все, что можем, есть ли преимущества у одного перед другим?
2 ответа
Лучший ответ:
Судя по контексту, RCC_BASE
выглядит как макрос препроцессора.
который расширяется до базового адреса некоторого периферийного устройства, называемого «RCC», и
AHB1EN_R_OFFSET
аналогичный макрос для смещения ввода-вывода AHB1EN_R
зарегистрироваться относительно этого базового адреса. Затем
RCC_BASE + AHB1EN_R_OFFSET
— отображаемый в памяти адрес регистра. Этот адрес просто
число. Если вы приведете его к volatile unsigned int
, вы все равно получите
такое же количество. Если вы хотите получить доступ к регистру ввода-вывода, вы должны сказать
компилятору, что это число на самом деле является адресом (т.е. числовым
значение указателя), а затем получить доступ к шине памяти по этому адресу
(т.е. разыменовать указатель):
(volatile unsigned int *)
преобразует числовое значение в указатель (из-за*
), который указывает наvolatile unsigned int
*
в начале макроса разыменовывает указатель и, таким образом, выполняет фактический доступ к регистру ввода/вывода.
В первой строке RCC_AHB1EN_R — это указатель на местоположение. вы получили это от кастинга.
#define RCC_AHB1EN_R (*(изменчивое целое число без знака *)(RCC_BASE + AHB1EN_R_OFFSET))
Во второй строке RCC_AHB1EN_R содержит базовый адрес, который является целым числом.
#define RCC_AHB1EN_R (изменчивое целое без знака)(RCC_BASE + AHB1EN_R_OFFSET))
надеюсь, это внесет ясность?
- Указатели функций, которые вызывают одну функцию
- распиновка для stm32duino с bluepill
- Почему считается плохой практикой использовать ключевое слово "new" в Arduino?
- Работает с gcc, но не с Arduino. ошибка: taking address of temporary array
- STM32f4 Предупреждение: ядро заблокировано
- Проблемы с преобразованием uint32_t в char*
- ArduinoJSON v6 – передача буфера как параметра функции
- STM32 ST LINK не работает в Linux
Хорошо, пожалуйста, скажи мне, правильно ли я понял.
(*(volatile unsigned int *)(RCC_BASE + AHB1EN_R_OFFSET))
заставит(RCC_BASE + AHB1EN_R_OFFSET)
считаться адресом и получит значение по этому адресу, так как перед ним стоит*
. Но то, что я понимаю из использованияvolatile
, говорит компилятору не оптимизировать значение переменной. Я запутался сvolatile
с указателем. Таким образом, даже в этом случае 'volatile' дается для значения, хранящегося по этому адресу, а не само *значение адреса*?, @Just doin Gods work@JustdoinGodswork: Действительно. Такое объявление, как
TYPE * volatile p;
, сделаетp
изменчивым указателем, тогда какvolatile TYPE *p;
делаетp
указателем на изменчивые данные. Состав, который мы видим здесь, соответствует более позднему объявлению., @Edgar Bonet