This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

differences of absolute locations

I want an instance of a structure to be put at a specific address in xdata. What is the difference between these declarations:

#define tSetupPacket (* (tDEVICE_REQUEST xdata *)0xFF00)

tDEVICE_REQUEST xdata tSetupPacket _at_ 0xFF00;
It seems that the second behaves incorrectly.
There is also an opportunity to declare a structure at absolute locaiton by #pragma memory segments (supported by non-Keil C or Keil linker).
What is the best choice?

Parents
  • Some more random opinions:

    The macro form is the most portable. As Jon points out, you'll need to be sure that nothing actually links there. Typically, I'd see this sort of thing for memory-mapped hardware, and the linker would be configured to reserve the upper memory range for a whole series of registers. The other use I'm accustomed to is memory area shared between separately linked programs (e.g., boot loader and application code).

    The second form is convenient, but depends on Keil-specific language extensions. Tools other than the compiler (such as lint or your syntax-coloring IDE) will have to be taught how to deal with the non-standard syntax in your source. Portability goes down.

    The third form (linker spec) requires the variable to live in its own segment, which for Keil essentially means its own file. Every linker will have a different way to control segment positioning, so this method is in practice not very portable -- though at least there's nothing in the source code that will cause compiler errors. I also tend to avoid this approach because it puts the (important!) information about the variable address in a relatively obscure place. You probably want to know when browsing the C source that this variable is special and represents an absolute address. This method is more tempting to me for a shared memory area than for defining hardware registers.

Reply
  • Some more random opinions:

    The macro form is the most portable. As Jon points out, you'll need to be sure that nothing actually links there. Typically, I'd see this sort of thing for memory-mapped hardware, and the linker would be configured to reserve the upper memory range for a whole series of registers. The other use I'm accustomed to is memory area shared between separately linked programs (e.g., boot loader and application code).

    The second form is convenient, but depends on Keil-specific language extensions. Tools other than the compiler (such as lint or your syntax-coloring IDE) will have to be taught how to deal with the non-standard syntax in your source. Portability goes down.

    The third form (linker spec) requires the variable to live in its own segment, which for Keil essentially means its own file. Every linker will have a different way to control segment positioning, so this method is in practice not very portable -- though at least there's nothing in the source code that will cause compiler errors. I also tend to avoid this approach because it puts the (important!) information about the variable address in a relatively obscure place. You probably want to know when browsing the C source that this variable is special and represents an absolute address. This method is more tempting to me for a shared memory area than for defining hardware registers.

Children
No data