Нужна помощь для этого синтаксиса: "#define LEDs (char *) 0x0003010" - PullRequest
0 голосов
/ 10 июня 2010

Я занимаюсь программированием софткорного процессора Nios II от Altera, ниже приведен код в одном из учебных пособий, мне удается заставить работать код, протестировав его на аппаратном обеспечении (плате DE2), однако я мог бы не понимаю код.

#define Switches (volatile char *) 0x0003000
#define LEDs (char *) 0x0003010
void main()
{ while (1)
*LEDs = *Switches;
}

Что я знаю о #define, так это то, что он используется либо для определения константы , либо макроса , но

  1. почему в приведенном выше коде есть приведение типа (char *) 0x0003010 в #define?
  2. почему 2 константы Switches и LEDs действуют как переменные, а не как константы?

Ответы [ 4 ]

4 голосов
/ 10 июня 2010

1) почему в приведенном выше коде есть приведение типа (char *) 0x0003010 в #define?

Макросы препроцессора являются текстовыми заменами. Таким образом, код выглядит как

while (1) {
  *(char *) 0x0003010 = *(volatile char *) 0x0003000
}

, который повторяется, назначает содержимое входа (переключателя), отображаемого в 0x3000, на выход (светодиод), отображаемый в 0x3010.

2) почему 2 константы, переключатели и светодиоды действуют как переменные, а не как постоянные?

Обратите внимание, что это указатель. Таким образом, они всегда указывают на одно и то же место (которое является парой выводов ввода-вывода с отображением в памяти или чем-то подобным), но нет никакой гарантии, что содержимое этих постоянных мест является постоянным, а * перед каждым символом препроцессора появляется оператор разыменования указателя.

4 голосов
/ 10 июня 2010

Похоже, что Switches и LEDs представляют отображение памяти на фактический вход (в случае Switches) и вывод (в случае LEDs).

ТакВаши ответы включают в себя:

  1. Байт для входных переключателей сопоставлен с адресом 0x0003000.Чтобы получить к нему доступ в виде байта, вам нужно сообщить компилятору, что все, что находится по адресу 0x0003000, является char (фактически, вы говорите ему, что значение по этому адресу равно volatile char, так что компилятор неНе оптимизируйте тот факт, что значение по этому адресу может измениться в любое время).

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

Что происходит, так это то, что каждый тактовый цикл (или около того)все, что читается из памяти по адресу 0x0003000, затем записывается по адресу 0x0003010.Это создает иллюзию, что переключатели мгновенно переключают светодиоды.

3 голосов
/ 10 июня 2010

В Си макросы являются простыми заменами.

Каждый раз, когда компилятор видит LEDs в вашем коде, он заменяет его на (char *) 0x0003010.

Таким образом, ваш код фактически одинаковкак это:

void main()
{
    while (1)
        *(char *) 0x0003010 = *(volatile char *) 0x0003000;
}
0 голосов
/ 10 июня 2010

Без приведения типов в #defines они не будут рассматриваться как char * и volatile char *.Что находится на * Переключатели копируется в * Светодиоды.

...