Что это значит именно на С? - PullRequest
0 голосов
/ 08 января 2019
#define RegisterX_Address (*((volatile unsigned int*)0x400253FC))

Мне нужно понять, что это за (*((volatile unsigned int*)0x400253FC)) в C, я понимаю, что это указатель, указывающий на адрес одного из регистров, но почему он написан так ???

Ответы [ 4 ]

0 голосов
/ 09 января 2019

Просто попробуйте ...

#define RegisterX_Address (*((volatile unsigned int*)0x400253FC))
unsigned int fun ( void )
{
    return(RegisterX_Address);
}

дает

00000000 <fun>:
   0:   4b01        ldr r3, [pc, #4]    ; (8 <fun+0x8>)
   2:   6818        ldr r0, [r3, #0]
   4:   4770        bx  lr

   8:   400253fc

Проще написать, чем

volatile unsigned int *RegisterX_Address;
RegisterX_Address = (volatile unsigned int *)0x400253FC;
return(*RegisterX_Address);

Вот почему так написано. Плюс, как написано, он не потребляет память как переменную.

0 голосов
/ 08 января 2019

На какой бы платформе это ни было, адрес памяти 0x400253FC содержит данные * 1 int.

Если вы разыменуете 0x400253FC, вы получите это значение.

Это, вероятно, используется для чего-то вроде:

unsigned int GetCPUTemperature()
{
    unsigned int temp;
    temp = RegisterX_Address;
    return temp;
}

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

Ключевое слово volatile сообщает компилятору, что оно не может кэшировать, сохранять или повторно использовать полученное значение. Он должен извлекать значение из памяти при каждом доступе, потому что все, что записывает данные, будет регулярно обновлять значение и выходить за рамки программы.

0 голосов
/ 09 января 2019

Это макрос для доступа к (вероятно) отображенному в памяти выводу ввода / вывода.

Компилятор или само оборудование знает, что определенные адреса памяти имеют дополнительное назначение. Когда ваш исходный код читает этот регистр, он действительно считывает значение с входного контакта, провод подключается непосредственно к процессору. Этот адрес особенный, и подобные вещи обычно связаны исключительно с этим конкретным оборудованием. (Вот почему вам нужна плата разных драйверов для разных устройств, но не все они взаимозаменяемы). Для всего неправильного направления и обобщения, которые выполняют более высокие уровни, в какой-то момент вам необходимо направить чтение и запись на реальное оборудование с реальными адресами.

Внутренний * объявляет его как указатель. Внешний * разыменовывает его. И да, указатели на C - одна из самых запутанных частей языка. Символ * имеет две работы; один во время объявлений, где он описывает кусок данных. И явно приведение - это объявление: (volatile unsigned int*). Это заставляет компилятор обрабатывать шестнадцатеричное значение как указатель на переменное целое число без знака. Во-вторых, во время выполнения при использовании этого макроса: *(myPointer) этот указатель разыменовывается, поэтому вместо использования значения 0x400253FC вы смотрите на данные, которые находятся в памяти по адресу ADDRESS 0x400253FC. Который даже не память, так как он, вероятно, сопоставлен с HW. (Это зависит. В любом случае это все еще называется регистром в ICD. Я думаю, что регистры - это специфические регистры на чипе, какую сборку можно использовать напрямую, а не проходить через MMU. Но все это "регистр" для парней из HW , они используют это, как мы используем "адрес").

И я предполагаю, что это вывод ввода / вывода, потому что он нестабилен. Это инструкция для компилятора не делать предположений при оптимизации, потому что его значение может измениться за его спиной. Например, когда оборудование получает сигнал. Или когда выходная линия автоматически сбрасывается на низкий уровень. Изменчивые переменные также используются для разделяемой памяти между потоками, но на микроконтроллере это обычно ввод / вывод.

0 голосов
/ 08 января 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...