EmbeddedRelated.com
Forums
Memfault State of IoT Report

Language feature selection

Started by Don Y March 5, 2017
Am 09.03.2017 um 16:36 schrieb David Brown:

> I don't feel there is much wrong with the standard C method of making > constant pointers such as I described.
Well, here is one detail: it's not entirely standard, because it involves the explicitly implementation-defined conversion of an integer constant to a pointer. I.e. in principle the same construct on two different C compilers could yield different results.
> The only problem I see is that it defines the names as macros which > don't obey scope.
And given the fact that a hardware register, pretty much by definition, _is_ an entirely scope-less, global object, that's not much of an obstacle, either. If one were truly worried about scope, it would always be possible to encapsulate all accesses in an accessor module --- at the likely cost of at least one function call overhead.
On 2017-03-09, Britt <britt.snodgrass@gmail.com> wrote:
> On Thursday, March 9, 2017 at 5:08:35 AM UTC-5, David Brown wrote: > >> Other languages that don't have something equivalent to the "C constant >> pointer kludge" may need an extension of some sort to efficiently access >> I/O registers. But which languages would that be, and are they actually >> used in embedded programming? > > In Ada (actually used in embedded programming), it is always as simple as this: > > Some_IO_Reg : Some_IO_Reg_Type; -- type defined as appropriate > > for Some_IO_Reg'Address use 16#0000_0800#; -- or whatever value is needed > > so no kludge is required anywhere. Register types are easily and clearly > described using bit level record representation clauses. In fact, pointers > are almost never needed (and that is a very good thing). >
Since Don asked for new useful features, there's new Ada functionality in this area currently working it's way through the Ada standards committee and currently looks like it might be ratified for the next version of Ada. Representing register bitfields as Ada bitfields currently has one major limitation in that you cannot directly update multiple register bitfields in Ada in a single R-M-W sequence without either using a temporary variable or resorting to C style bitmasks. In my original proposal, which is currently working it's way through the ARG, you would be able to specify multiple bitfields to be updated as part of a single assignment statement which would be translated into a single R-M-W sequence by the compiler. No C style bitmasks or temporary variables required. See http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0127-1.txt?rev=1.10&raw=N for details. If the formal language at the beginning puts you off, then skip down to the appendix section which contains my original proposal. Simon. -- Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP Microsoft: Bringing you 1980s technology to a 21st century world
On 09/03/17 17:15, Grant Edwards wrote:
> On 2017-03-09, David Brown <david.brown@hesbynett.no> wrote: >> On 09/03/17 15:47, Grant Edwards wrote: >>> On 2017-03-09, Walter Banks <walter@bytecraft.com> wrote: >>> >>>> Far less complex. A simple way to declare a variable at a specific >>>> physical address. >>>> >>>> Every other variable attribute remains untouched. It is in the >>>> symbol table, debug data and can be referenced like any other >>>> variable. You can do address of, set a pointer to it assign and read >>>> it. >>> >>> I leave the dermination of physical addresses up to the linker. If I >>> want "real variables" at specific addresses, that belongs in the >>> linker script (IMO). >> >> That's okay, if you don't mind the extra overhead because the compiler >> can't see the address at compile time, and you are happy to declare your >> registers twice (once in a header for C, and once in the linker file). > > Ah, I thought we were talking about variables, not registers. I think > conflating the two is a grave mistake.
Well, Walter did say "declare a /variable/ at a specific physical address" - but far and away the most common need for something at a fixed address is a hardware register. It is very rare that you would want a normal variable at a fixed address (interfacing between separately compiled and linked code, such as a bootloader and a main program, is about the only case I can think of). For a variable, I agree that a linker script might be a way to handle it. More likely, I'd use C extensions to put the variable in a specific named section, and use linker scripts or commands to put the section at a specific address.
> >> Of course, this is rarely an issue in practice because in most >> cases, people use ready-made chip header files from the device >> manufacturers, and for most processors and compilers these will use >> casted pointers to volatiles. > > Again, that's for accessing HW registers, which (IMO) should not be > conflated with variables. Thinking that HW registes are "normal > variables" is an excellent way to loose a foot. > > This, of course, raises the question why you would _need_ to place > _variables_ at specific addresses when it's not for accessing HW > registers. That need seems to me to be rare enough that adding a > language feature to support it is foolish. >
Agreed.
On 09/03/17 19:26, Hans-Bernhard Br&ouml;ker wrote:
> Am 09.03.2017 um 16:36 schrieb David Brown: > >> I don't feel there is much wrong with the standard C method of making >> constant pointers such as I described. > > Well, here is one detail: it's not entirely standard, because it > involves the explicitly implementation-defined conversion of an integer > constant to a pointer. I.e. in principle the same construct on two > different C compilers could yield different results. >
That's true (and I have been a bit imprecision about distinguishing between "standard C method" meaning "the method used by most people in C" and "standard C" meaning "fully defined by the C standards"). But any "sane" compiler will, in practice, implement these things in the same way - so it is a much more portable solution than an @ extension.
>> The only problem I see is that it defines the names as macros which >> don't obey scope. > > And given the fact that a hardware register, pretty much by definition, > _is_ an entirely scope-less, global object, that's not much of an > obstacle, either. If one were truly worried about scope, it would > always be possible to encapsulate all accesses in an accessor module --- > at the likely cost of at least one function call overhead.
Yes.
On 3/9/2017 12:04 PM, Simon Clubley wrote:
> On 2017-03-09, Britt <britt.snodgrass@gmail.com> wrote: >> On Thursday, March 9, 2017 at 5:08:35 AM UTC-5, David Brown wrote: >> >>> Other languages that don't have something equivalent to the "C constant >>> pointer kludge" may need an extension of some sort to efficiently access >>> I/O registers. But which languages would that be, and are they actually >>> used in embedded programming? >> >> In Ada (actually used in embedded programming), it is always as simple as this: >> >> Some_IO_Reg : Some_IO_Reg_Type; -- type defined as appropriate >> >> for Some_IO_Reg'Address use 16#0000_0800#; -- or whatever value is needed >> >> so no kludge is required anywhere. Register types are easily and clearly >> described using bit level record representation clauses. In fact, pointers >> are almost never needed (and that is a very good thing). > > Since Don asked for new useful features, there's new Ada functionality > in this area currently working it's way through the Ada standards > committee and currently looks like it might be ratified for the next > version of Ada.
I use "new" only in the sense of something that was *new* (for you) when you were exposed to it. My interest is more on *value* than newness and/or novelty. E.g., replacing the i4004's JMS/BBL with the i8008's CALL/RET was a yawn... stack depth was still severely constrained (though doubled!). OTOH, the 8080's addition of PUSH/POP was *hugely* (YUGELY?) valuable as it made a pronounced difference in what was suddenly "realistic" in terms of managing application implementation complexity. "You mean I can push *any* register (pair)? And, as many as I want ALONG WITH subroutine invocations??"
> Representing register bitfields as Ada bitfields currently has one > major limitation in that you cannot directly update multiple > register bitfields in Ada in a single R-M-W sequence without either > using a temporary variable or resorting to C style bitmasks.
But, does that really buy you much -- unless you are sorely resource (time/space) constrained? (Granted, this can be seen as a different case of the PUSH/POP issue, above -- e.g., building a synchronization primitive to wrap a set of *discrete* accesses, etc.) [One of my gripes about Ada is that it's too "big" of a language] One can always come up with new "features" that can have some merit in some cases. What I'm looking for are the "wow" moments when some feature made a radical difference in how you approach(ed) problems. Like moving from the 8's JMS to the 11's JSR opening the door for recursive routines. Or, having direct access to the "status word" allowing a multitasking executive to restore the *entire* machine state, etc.
> In my original proposal, which is currently working it's way through > the ARG, you would be able to specify multiple bitfields to be updated > as part of a single assignment statement which would be translated into > a single R-M-W sequence by the compiler. No C style bitmasks or > temporary variables required. > > See http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0127-1.txt?rev=1.10&raw=N > for details. If the formal language at the beginning puts you off, then > skip down to the appendix section which contains my original proposal.
This looks like you are trying to tackle atomic updates on a larger (wider) scale than just bitfields (?). If not, then you seem to be creating a huge bias (in the mind of the developer) to opt for a "set of bitfields" representation of certain structures that might inadvertently lead to a sort of premature optimization ("Damn! If I let the individual fields grow 'just a tad', then I lose the value of this feature, here...") [Disclaimer: I've not looked at Ada for more than 15 years... :< ]
On 3/9/2017 3:34 PM, Don Y wrote:
>> See >> http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0127-1.txt?rev=1.10&raw=N >> for details. If the formal language at the beginning puts you off, then >> skip down to the appendix section which contains my original proposal. > > This looks like you are trying to tackle atomic updates on a larger (wider) > scale than just bitfields (?).
Sorry, in concentrating on the "meat" of the examples, I glossed over the _aggregates_ reference. <:-(
Walter Banks wrote:
> On 2017-03-05 5:03 PM, Don Y wrote: >> A quick/informal/UNSCIENTIFIC poll: >> >> What *single* (non-traditional) language feature do you find most >> valuable in developing code? (and, applicable language if unique to >> *a* language or class of languages) > > The @ in various forms to tie a physical address to a symbolic variable. > This construct more that any other single thing allows many high level > languages have the ability broaden the range of potential applications > from high level to close to the machine. >
Hi Walter! No offense, but... This is utterly 1) inappropriate and 2) unnecessary. It's a *terrible* extension to ( I presume C, where I have seen it ). Even back on Borland, Microsoft, Tektronix and ... another VAX C compiler 30ish years ago, you'd use a linker/locater to put specific structures at specific locations. The source code itself doesn't need to know about where variables go[1]. Its part of the responsibility of tools that are invoked later in the build cycle. [1] think of a shared module that's a "driver" for an FPGA and is common to three projects, but all three targets have a different base addresses for said FPGA. Now, all that being said - for some kinds of debugging, it's darn handy to have the same variables at the same locations. It's just better done in the linker or with a locater.
> It is language independent and very easy to add to compilers without > changing the basic form of the language. >
it very nearly destroys the portability of code that uses it...
> w.. > >
-- Les Cargill
Grant Edwards wrote:
> On 2017-03-09, David Brown <david.brown@hesbynett.no> wrote: >> On 09/03/17 15:47, Grant Edwards wrote: >>> On 2017-03-09, Walter Banks <walter@bytecraft.com> wrote: >>> >>>> Far less complex. A simple way to declare a variable at a specific >>>> physical address. >>>> >>>> Every other variable attribute remains untouched. It is in the >>>> symbol table, debug data and can be referenced like any other >>>> variable. You can do address of, set a pointer to it assign and read >>>> it. >>> >>> I leave the dermination of physical addresses up to the linker. If I >>> want "real variables" at specific addresses, that belongs in the >>> linker script (IMO). >> >> That's okay, if you don't mind the extra overhead because the compiler >> can't see the address at compile time, and you are happy to declare your >> registers twice (once in a header for C, and once in the linker file). > > Ah, I thought we were talking about variables, not registers. I think > conflating the two is a grave mistake. > >> Of course, this is rarely an issue in practice because in most >> cases, people use ready-made chip header files from the device >> manufacturers, and for most processors and compilers these will use >> casted pointers to volatiles. > > Again, that's for accessing HW registers, which (IMO) should not be > conflated with variables. Thinking that HW registes are "normal > variables" is an excellent way to loose a foot. > > This, of course, raises the question why you would _need_ to place > _variables_ at specific addresses when it's not for accessing HW > registers. That need seems to me to be rare enough that adding a > language feature to support it is foolish. >
One need only go back to the '80s/'90s to find Paradigm Locate, which took Borland C/C++ objects and fixed certain .SEGMENTS[1] at certain locations for this sort of thing. [1] like .BSS, .CODE, .DATA, whatever... -- Les Cargill
Walter Banks wrote:
> On 2017-03-08 3:46 AM, David Brown wrote: >> On 08/03/17 05:10, Walter Banks wrote: >>> On 2017-03-05 5:03 PM, Don Y wrote: >>>> A quick/informal/UNSCIENTIFIC poll: >>>> >>>> What *single* (non-traditional) language feature do you find >>>> most valuable in developing code? (and, applicable language if >>>> unique to *a* language or class of languages) >>> >>> The @ in various forms to tie a physical address to a symbolic >>> variable. This construct more that any other single thing allows >>> many high level languages have the ability broaden the range of >>> potential applications from high level to close to the machine. >>> >>> It is language independent and very easy to add to compilers >>> without changing the basic form of the language. >>> >> >> Do you mean having a compiler extension for: >> >> volatile uint8_t REG @ 0x1234; >> >> rather than the standard C: >> >> #define REG (*((volatile uint8_t*) 0x1234)) >> >> Certainly the "@" syntax is neater, and certainly it is nice if >> means "REG" turns up in the linker map file and debugging data. But >> it is hardly a breakthrough, and does not allow anything that cannot >> be done in normal C syntax just as efficiently (assuming the >> compiler implementation is sane). >> >> Most embedded compilers don't have anything equivalent to the "@" >> syntax - yet people seem to manage to use them perfectly well for >> "close to the machine" programming. > > > I saw it as an abstract question. My comment was a clean simple way to > directly interface to the machine completely separate from the language > proper. Developers in a surprising number of languages have found some > round about way to accomplish this demonstrating its need. > > The C constant pointer Kludge although functionally similar generally > misses out having proper symbolic debugging support. >
That's kind of not what const is for in 'C', although it's a way.
> uint8_t REG @ 0x1234; is just as viable a declaration without
> the volatile.
>
So what you really want is for the toolchain to assign these values at address fixup time - in the linker or later. You use #pragmas to assign a block in a seperate segment, then the linker fixes it up for you. That way if he FPGA decodes at a different address for different projects, you're covered and don't have to maintain seperate copies of that source code.
> Many if not most non open source compilers for embedded systems some > form @. > > The concept as I have found is just as useful in many languages I have > used. > > w.. > >
- Les Cargill
On 2017-03-09 5:54 PM, Les Cargill wrote:
> > Hi Walter! No offense, but... > > This is utterly 1) inappropriate and 2) unnecessary. It's a > *terrible* extension.
Maybe "terrible" but a lot cleaner than a pointer to constant that is expected to be optimized by a compiler to a simple load store.
> it very nearly destroys the portability of code that uses it...
and I assume that constant pointer doesn't destroy portability. C specifically rarely has portable applications. Better that applications be completely contained and either have include files to define application specific information. The original role of linkers was to be able to compiler large programs on small computers. The current state of especially open source compilers is an awful lot of duplication between the compiler and linkers in the tool sets. Better that a lot of the linker information be processed much earlier to develop compile strategies. This is even more true in some of the more interesting ISA that are currently being developed. I am working on a project that can have hundreds or potentially thousands of heterogeneous processors being compiled to from a single application. Address setting from application/processor specific header files allows compilers to be written with far more flexibility and that is far less computationally intensive. w..

Memfault State of IoT Report