On Sunday, 28 August 2016 at 13:26:37 UTC, Johannes Pfau wrote:
Am Sun, 28 Aug 2016 09:28:24 +0000
schrieb Timo Sintonen <t.sinto...@luukku.com>:

I just translated my sample program and everything seems to work in my limited tests. Here is a simplified example of an uart:

alias uarttype = uartreg*;
enum uarttype uart1=cast (uarttype)0x40011000;
enum uarttype uart2=cast (uarttype)0x40004400;


That's a clever solution. AFAICS it works because D supports
the '.' operator on pointers. With this solution you can't directly
assign the complete value:

uart1 = uart2; // can't be valid, assigning pointers
*uart1 = *uart2; // should work, though IIRC there could be a DMDFE bug

IIRC you also cant use operator overloading:

uart1 += 49; // can't be valid, assigning the pointer
*uart1 += 49; // might work? (not sure if dereferencing
              // and overloads work in same statement)


And you can't use the & operator to get the address, but as uart1 already is a pointer that's not really a problem.

One reason I like D is that enums can have type. I can write functions that take that type as an argument. Having these as compile time constant means less indirection: no need to take an address of a variable that holds the pointer to the struct. Peripherals are always in fixed addresses and have fixed names. There is no need to create a struct of this type or address them in different places or use pointers in calculations.



In your example this isn't really a restriction. But it could be more annoying if you don't have related fields with contiguous addresses. Consider a single 8 bit counter value:

alias CtrType = (Volatile!ubyte)*; enum CtrType ctrA=cast (CtrType)0x40011000;

*ctrA += 3;
*ctrA = 42;


Addressing single locations is more difficult. Pointers are not the preferred way in D. Individual registers are quite rare in microcontrollers and it is always possible to have a struct with only one volatile member.


Reply via email to