I still have some issues with my c code that deals with an memory mapped device. At the moment I declare the address space for the registers I write as volatile pointer and I write data to them as shown below:
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;
}
This works more or less fine. However, I would like to have specific read and write functions that interact with the memory mapped registers. So ideally, it w开发者_JS百科ould look something like this:
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);
}
I have not tried it out yet to be honest, but I am wondering if somebody could tell me if this is a proper way to do it?
EDIT: Maybe it is of use for someone else, here I have my function and they seem to work. Many thanks for the helpful comments!
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));
}
Many thanks
There are quite a few problems with your code:
- I assume you meant
void
where you wrotefunction
. - You should make the pointer inside the function to be
volatile
as well. - You should dereference the pointer before writing the data. The
*
should be inside the function, not at the call site (*write_REG
) as it is now - that would be a compile error. - You should add the offset to the pointer, not the address. This is because an offset of 1 is meant to be the next
int
which could be, say, 4 bytes away, but adding it to the address will only add 1 byte.
Your corrected function should look like this:
void write_REG(unsigned int address, int offset, int data)
{
*((volatile unsigned int*)address + offset) = data;
}
and you would call it like:
write_REG(0x40000000, 0, 0x01234567);
That would be just fine IMHO. I sometimes use macros like:
#define WR_REG *(volatile unsigned int*)0x40000000
This allows the registers to be used sort of like variables:
WR_REG = 0x12345678;
精彩评论