Дальнейший вопрос с интерфейсом с отображением памяти

У меня все еще есть некоторые проблемы с моим кодом C, который имеет дело с устройством с отображением памяти. На данный момент я объявляю адресное пространство для регистров, которые я записываю, как изменчивый указатель, и я записываю в них данные, как показано ниже:

volatile unsigned int *wr_register = (int *) 0x40000000;
volatile unsigned int *c_register =  (int *) 0x40000100;
...

main{

  *wr_register = 0x01234567;

  *c_register = 0x01234567;    
  *(c_register+1) = 0x89abcdef;  

}

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

const unsigned int wr_register = 0x40000000;
const unsigned int c_register  = 0x40000100;

function write_REG(unsigned int address, int offset, int data)
{
    (unsigned int*) (address + offset) = data;
}

main{

  *write_REG(0x40000000, 0, 0x01234567);

  *write_REG(0x40000100, 0, 0x01234567);
  *write_REG(0x40000100, 1, 0x89abcdef);  

}

Я еще не пробовал это, если честно, но мне интересно, может ли кто-нибудь сказать мне, правильный ли это способ сделать это?

РЕДАКТИРОВАТЬ: Может быть, это пригодится кому-то еще, здесь у меня есть моя функция, и они, кажется, работают. Большое спасибо за полезные комментарии!

void reg_write(unsigned int address, int offset, int data)
{
    *((volatile unsigned int*)address + offset) = data;
}

int reg_read(unsigned int address, int offset)
{
    return(*((volatile unsigned int*)address + offset));
}   

Большое спасибо


person Alex12    schedule 12.11.2010    source источник
comment
Я думаю, что у вас есть посторонние «*» перед вызовами функций. Кроме того, я думаю, вы намеревались использовать адреса переменных в своих вызовах функций вместо жестко запрограммированных.   -  person kanaka    schedule 12.11.2010


Ответы (2)


В вашем коде довольно много проблем:

  1. Я предполагаю, что вы имели в виду void, где вы написали function.
  2. Вы также должны сделать указатель внутри функции равным volatile.
  3. Вы должны разыменовать указатель перед записью данных. * должен быть внутри функции, а не на месте вызова (*write_REG), как сейчас — это было бы ошибкой компиляции.
  4. Вы должны добавить смещение к указателю, а не к адресу. Это связано с тем, что смещение 1 означает следующее int, которое может быть, скажем, в 4 байтах, но добавление его к адресу добавит только 1 байт.

Ваша исправленная функция должна выглядеть так:

void write_REG(unsigned int address, int offset, int data)
{
    *((volatile unsigned int*)address + offset) = data;
}

и вы бы назвали это так:

write_REG(0x40000000, 0, 0x01234567);
person casablanca    schedule 12.11.2010
comment
Да, я имел в виду пустоту вместо функции ;). Очень хорошо, что я добавляю смещение к указателю, а не к самому адресу! Большое спасибо! - person Alex12; 12.11.2010

Это было бы нормально ИМХО. Я иногда использую макросы, например:

#define WR_REG     *(volatile unsigned int*)0x40000000

Это позволяет использовать регистры как переменные:

WR_REG = 0x12345678;
person S.C. Madsen    schedule 12.11.2010
comment
Они переменные. Исходный код Постера - это в значительной степени правильный способ сделать что-то, я не знаю, почему она хочет его усложнить. - person Conrad Meyer; 12.11.2010