Thread overview
Access to fixed memory locations, head const, ...
Nov 28, 2009
Kuba Ober
Nov 28, 2009
wakko
Nov 30, 2009
Kuba Ober
November 28, 2009
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
November 28, 2009
> 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
November 30, 2009
>> 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