www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Access to fixed memory locations, head const, ...

reply Kuba Ober <kuba mareimbrium.org> writes:
Hi,

I'm contemplating using D for an embedded project where system 
configuration registers have fixed memory locations.

One way of doing it would be to have a constant pointer to a structure 
with manually aligned members that match the register map, and access 
them like that. This becomes cumbersome, as all accesses look like

struct Regs {
   ...
};

Regs* cfg = cast(Regs*)0xF00;

cfg.reg0 = ...

This is also where D's const-transitivity becomes problematic. Since
the configuration registers are not going anywhere, ideally you'd want
a way of telling the compiler that the *pointer* is constant, but not
the pointed-to stuff.

For a systems language, this seems like a serious drawback. Why can't
I tell the compiler that noone should muck with the cfg pointer's
value? I presume there can be ways around it via delegates, but this
seems like a C++ approach: instead of making it simple, it becomes
convoluted...


OTOH, there's a C hack that allows you to access variables at fixed
memory locations "directly":

#define CFGREG0 (*(unsigned short*)0xBEEF)

I'm an absolute noob to D, and so far I found no way of approximating
this behavior -- of bringing the configuration registers at a fixed
memory location into the scope as an identifier that can be used naked, like

CFGREG0 = 0xFF;
if (CFGREG0 != 3) { ... }


Any hints?

Cheers, Kuba
Nov 27 2009
parent reply wakko <dm liquidstate.eu> writes:
 Hi,
 
 I'm contemplating using D for an embedded project where system 
 configuration registers have fixed memory locations.
 
 One way of doing it would be to have a constant pointer to a structure 
 with manually aligned members that match the register map, and access 
 them like that. This becomes cumbersome, as all accesses look like
 
 struct Regs {
   ...
 };
 
 Regs* cfg = cast(Regs*)0xF00;
 
 cfg.reg0 = ...
 
 This is also where D's const-transitivity becomes problematic. Since
 the configuration registers are not going anywhere, ideally you'd want
 a way of telling the compiler that the *pointer* is constant, but not
 the pointed-to stuff.
 
 For a systems language, this seems like a serious drawback. Why can't
 I tell the compiler that noone should muck with the cfg pointer's
 value? I presume there can be ways around it via delegates, but this
 seems like a C++ approach: instead of making it simple, it becomes
 convoluted...
 
 
 OTOH, there's a C hack that allows you to access variables at fixed
 memory locations "directly":
 
 #define CFGREG0 (*(unsigned short*)0xBEEF)
 
 I'm an absolute noob to D, and so far I found no way of approximating
 this behavior -- of bringing the configuration registers at a fixed
 memory location into the scope as an identifier that can be used naked, 
 like
 
 CFGREG0 = 0xFF;
 if (CFGREG0 != 3) { ... }
 
 
 Any hints?
 
 Cheers, Kuba
Hi Kuba, i think you should be able to do what you want with the linker (ld). i did this one time to fix my page directory address, inserting a symbol at a certain address. . = ALIGN(4K); .data.pd : { _pdpr = .; . = . + 0x1000; } And then doing something like: struct PageDirectory { ... } extern (C) char _pdpr; auto pdtr = cast (PageDirectory*) &_pdpr; This was working... Even if it does not resolve your problem completly maybe you can do something like: extern (C) PageDirectory _pdpr; But i did not test it... tell me if it works. -- AF
Nov 28 2009
parent Kuba Ober <kuba mareimbrium.org> writes:
 I'm contemplating using D for an embedded project where system 
 configuration registers have fixed memory locations.

 One way of doing it would be to have a constant pointer to a structure 
 with manually aligned members that match the register map, and access 
 them like that. This becomes cumbersome, as all accesses look like

 struct Regs {
   ...
 };

 Regs* cfg = cast(Regs*)0xF00;

 cfg.reg0 = ...

 This is also where D's const-transitivity becomes problematic. Since
 the configuration registers are not going anywhere, ideally you'd want
 a way of telling the compiler that the *pointer* is constant, but not
 the pointed-to stuff.

 For a systems language, this seems like a serious drawback. Why can't
 I tell the compiler that noone should muck with the cfg pointer's
 value? I presume there can be ways around it via delegates, but this
 seems like a C++ approach: instead of making it simple, it becomes
 convoluted...


 OTOH, there's a C hack that allows you to access variables at fixed
 memory locations "directly":

 #define CFGREG0 (*(unsigned short*)0xBEEF)

 I'm an absolute noob to D, and so far I found no way of approximating
 this behavior -- of bringing the configuration registers at a fixed
 memory location into the scope as an identifier that can be used 
 naked, like

 CFGREG0 = 0xFF;
 if (CFGREG0 != 3) { ... }
 i think you should be able to do what you want with the linker (ld).
 i did this one time to fix my page directory address, inserting a symbol 
 at a certain address.
 
 . = ALIGN(4K);
 .data.pd :
 {
     _pdpr = .;
     . = . + 0x1000;
 }
 
 And then doing something like:
 
 struct PageDirectory
 {
     ...
 }
 
 extern (C) char _pdpr;
 auto pdtr = cast (PageDirectory*) &_pdpr;
 
 This was working...
 
 Even if it does not resolve your problem completly maybe you can do 
 something like:
 
 extern (C) PageDirectory _pdpr;
The main reason I'm looking at D is to avoid hacks like this. So the short answer is: no, D does not support it "natively", without some extra syntactic sugar. And all I was really after is to avoid needless sugar in the first place... Cheers, Kuba
Nov 30 2009