2016-04-26 4 views
0

Я хочу установить несколько переменных в моей программе (предназначенных для интегрированного ядра ARC в SoC) для определенного адреса. Я использую этот синтаксис:Сопоставление переменных по определенному адресу в C

#define PORTBASE 0x00C07F00 

volatile Uint32* Ptr = (Uint32*)PORTBASE; //Uint32 is defined elsewhere 
*Ptr = 0xA5A5A5A5; 

* Uint определение:

typedef unsigned long Uint32; 

Однако данные A5 не записываются 0x00C0_7F00. Вместо этого ядро ​​пытается записать на этот адрес: 0x00C0_DC00, что вызывает прерывание, так как это не поддерживаемый адрес. 0x00C07F00 представляет собой определенный регистр, сопоставленный этому адресу.

Может ли кто-нибудь подумать о причине изменения адреса?

+0

никогда не пробовал это раньше, но мне интересно - если вы измените PORTBASE? будет ли процессор пытаться писать с тем же сдвигом? возможно, адреса указателей автоматически изменяются, чтобы соответствовать внутри диапазона. – sagivd

+0

1) Используйте стандартные типы для фиксированной ширины бита, а не для какого-либо материала доморощенного. 2) Использование промежуточной переменной бесполезно. 3) см. [Ask]. – Olaf

+1

В стандарте указано, что «Целое число может быть преобразовано в любой тип указателя. За исключением того, что указано ранее, результат определяется реализацией, может быть неправильно выровнен, может не указывать на объект ссылочного типа и может быть ловушкой представление "(C2011 6.3.2.3/5). В принципе, это означает, что вам нужно проконсультироваться с документами для своего компилятора, какой результат ожидать от такого преобразования, как вы выполняете, и как получить желаемый результат, если это вообще возможно. И если компилятор соответствует, то его документы * будут * говорить. –

ответ

0

Какая у вас среда (Bare-Metal, Linux, Windows, ...)?

Если вы используете ОС как Linux, адрес должен быть относительно вашего указателя процесса. В Linux вы можете использовать mmap, чтобы перевести свой адрес.

Простым примером является devmem.

В качестве приложения Bare-Metal используются фиксированные стандартные типы, как упоминалось ранее в комментариях.

+0

Ваша ссылка на 'mmap()' немного не-sequitur. То, что делает пример, с которым вы связаны, - это устройство '/ dev/mem' Linux; 'mmap()' просто делает это более удобным для работы. Поэтому, поскольку '/ dev/mem' является средством ОС, а не средством C, несколько сомнительно назвать это решением C. –

+0

Окружающая среда - голый металл –

0

Немного поработав, я нашел обходное решение, хотя я точно не знаю, почему это сработало: Вместо того, чтобы пытаться указать адрес так, как он определен. Я сначала назначаю его переменной const, а затем я передал эту переменную в качестве указателя:

#define PORTBASE 0x00C07F00 
const Uint32 PortOpCodeAddr = PORTBASE; 
Uint32* volatile const PortOpCode = (Uint32*)PortOpCodeAddr; 
Смежные вопросы