Question

I'm doing programming of a softcore processor, Nios II from Altera, below is the code in one of the tutorial, I manage to get the code working by testing it on the hardware (DE2 board), however, I could not understand the code.

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

What I know about #define is that, it is either used to define a constant, or a macro, but

  1. why in the above code, there are casting like, (char *) 0x0003010, in #define?
  2. why the 2 constants, Switches and LEDs act like a variable instead of a constant?
Was it helpful?

Solution

1) why in the above code, there are casting like, (char *) 0x0003010, in #define?

Preprocessor macros are textual replacements. So the code comes out as

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

which repeated assigns the contents of the input (switch) mapped at 0x3000 to the output (led) mapped at 0x3010.

2) why the 2 constants, Switches and LEDs act like a variable instead of a constant?

Note that those are pointer. So they always point to the same place (which happens to be a couple of memory mapped IO pins or something similar), but there is no guarantee the the contents of those constant locations are constant, and the * appearing before each preprocessor symbol is the pointer de-reference operator.

OTHER TIPS

It appears that Switches and LEDs represent the memory-mapping to the actual input (in the case of Switches) and output (in the case of LEDs).

So your answers include:

  1. The byte for the input switches is memory-mapped to address 0x0003000. In order to access that as a byte, you need to tell the compiler that whatever is at address 0x0003000 is a char (in fact, you tell it that the value at that address is a volatile char, so that the compiler doesn't optimize away the fact that the value at that address may change at any time).

  2. They are constants, but they are constant pointers. That is to say, the address is constant, but the values contained at those addresses are not constant.

What happens is that every clock cycle (or so), whatever is read from memory address 0x0003000 is then written to address 0x0003010. This gives the illusion that the switches instantly toggle the LEDs.

In C, macros are simple substitutions.

Every time the compiler sees LEDs in your code it will replace it with (char *) 0x0003010.

So your code is effectively the same as this:

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

Without the type casting at the #defines, they wouldn't be treated as char* and volatile char*. What is at *Switches is copied into *LEDs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top