Hallo, I must create a memory for a display lcd. This is part of a microcontroller based on microblaze.
I thought to do it using a variable, a matrix: display[X][Y] (the software video memory).
This variable should exaclty stay into microblaze address space where I have mapped a blockram (the hardware video memory) from 0x77200000 to 0x7720FFFF.
In this way, working with my variable I could edit hardware video memory.
Hi Marco, I'm far from being good at C, but I have some hobby-interest in MicroBlaze and C in general... What you are trying to do is not specifically MicroBlaze related - try the same code in a linux gcc compiler, for example, and you will get the same error.
What I think you are trying to say is "I want a pointer to a 2-D array, which has a base address of 0x77200000"
But the compiler sees this as an attempt to initalize the contents of the memory - and says "invalid initalizer"
In order to memory map a perpherial, I have used my own simple hack which is the following:
volatile unsigned char *ptr_to_mem;
int main() { ptr_to_mem = (unsigned char *) 0x77200000;
ptr_to_mem[address] = data;
}
This is a simple and vaild way to access byte-wise any memory starting at the base address shown abloe. you delcare the pointer as just a pointer to memory, and you access successive bytes by using it as an array. (Note: the volaitle is important - as it forces the memory access to occur) (Note: If you try this on a linux machine, it will have a segmentation fault, as it doesn't want you to assign the memory addesses!! - works fine in a microblaze without an OS though)
To implement a 2-D array, it can be done as anohter poster suggested, by having a power of 2 width, hardware barrel shifter, and calculating the address from that, and using a single-subscripted array.
This is probably far from the recommended way to do this but it works! - maybe for the real answer it might be worth checking out some C related newsgroups?
Cheers, John
--
***********************************************************************
/ /\/ John McGrath
There is a lot of confusion here about pointers and arrays in C.
The declaration: unsigned char *display[HEIGHT][WIDTH]; ...means "display is a two-dimensional array with elements of type 'pointer to character'."
Similarly: unsigned char *display[HEIGHT*WIDTH]; ...means "display is a one-dimensional array with elements of type 'pointer to character'."
Consequently, trying to initialize either of these "display" variables with an 'unsigned char *', that is, a 'pointer to character', will not work because the types of the variable and the initializer are different.
Now, a variable of pointer type in C can be initialized to point somewhere (like to the 1,998,585,856th location in memory, in this example), but an array (of any dimension) cannot. Your best bet is to make "display" into a variable of type "pointer to a two-dimensional array of characters", which is probably what you were trying to do in the first place. The syntax for this is:
unsigned char (*display)[HEIGHT][WIDTH];
Note that the brackets are vital, because [] has higher precedence than * (see K&R p53).
To initialize this variable "display" to point to the screen buffer, do this (I'm omitting 'unsigned' from now on for brevity):
As a previous poster pointer out, you might be better off with a one-dimensional array. For a start, you'll probably get more efficient code than for the multiple indirection above.
As an aside: you can dispense with the [HEIGHT] part if you like, and just write:
the addresses and sequential addreesses are, in example (decimals -> hex):
Those hex values don't correspond to those decimal values at all.
0x77202580 is 1998595456 in decimal.
If the value of the pointer "display" is 0x77200000, then the address of the element (0,0) is &((*display)[0][0]) and will also be 0x77200000. The address of the "next" element is &((*display)[0][1]) and will be 0x77200001.
The address of the element (1, 0) is &((*display)[1][0]) and will be 0x77200000 + WIDTH. If the hex values you gave above are correct, the difference between the two addresses is 9600 - a "nice" number which is probably not an accident. Is this one of your screen dimensions, by any chance?
That is a little surprising. I would triple-check your hardware is all connected up correctly. If you have some other data memory region in your design, try this test: allocate the display memory there (by changing 0x77200000 to something else) and see if you can read and write the first element succesfully.
Another thing to do is declare your array as "volatile":
volatile unsigned char (*display)[Y][X];
This will force the compiler never to optimize away reads and writes of this array. Otherwise, it may think they have no effect and not bother to perform them.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.