EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Language feature selection

Started by Don Y March 5, 2017
On 3/8/2017 7:48 PM, Walter Banks wrote:
> On 2017-03-08 12:48 AM, Don Y wrote: >> On 3/7/2017 9:10 PM, 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. >> >> I assume you mean the "address of" operator? I.e., "where is >> 'foo'?" >> >>> It is language independent and very easy to add to compilers >>> without changing the basic form of the language. >> >> But, by itself, it is of little use. So, you know *where* something >> is. But, if you can't dereference the address (pointer), you can't >> affect any changes to the environment around it (the >> pointer/referenced object). > > 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.
<frown> I'm not sure I link doing that sort of binding in the source code. It ties it too intimately to the target implementation. I like letting the linkage editor do that work along with the (runtime) loader. What's to stop the developer from specifying a "bad" address? Or, overlooking such a declaration embedded in some source file? At least the linkage editor gives the developer a hint as to where to look for such bindings...
Walter Banks <walter@bytecraft.com> writes:
> Far less complex. A simple way to declare a variable at a specific > physical address. Every other variable attribute remains untouched.
Can I ask why you'd want to do that? If it's to point to a memory mapped i/o register, there are a lot of optimizations that the compiler has to be careful not to make, and it's quite hard to get that right. The best way to implement volatile variable operations in C seems to be to treat them like external function calls. If it's for some other reason like having the value show up at a predictable place in crash dumps, I think we've mostly moved past that style of debugging ;-).
On 09/03/17 03:33, 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.
Far and away the most common reason to need variables at specific addresses is to access hardware registers. In such cases, the C "constant pointer kludge" is perfectly good, and decent compilers will generate solid code for it. (Often they will be able to generate more optimal code than if you use alternatives such as symbols in assembly or linker-defined addresses.) It is true that the variable is not a normal variable available for symbolic debugging - but you don't /want/ it to be available in the debugger like a normal variable, because it is /not/ a normal variable. With normal variables, you want to be able to hover your mouse over the variable "nextCharacter" in your code and have the debugger show you the value. But you absolutely do not want that to happen when you hover over "UART_DATA_REG", because reading it could trigger a move from a FIFO, setting a CTS signal, or whatever. An IDE for embedded development will usually have a window for "registers" or "IO registers" - /that/ is where you want to see this sort of thing, because that window and the software behind it should be aware of details about what can be read or written in different ways.
> > uint8_t REG @ 0x1234; is just as viable a declaration without the volatile.
But what use is that?
> > Many if not most non open source compilers for embedded systems some > form @.
No, they don't. /Some/ have a type of "@" syntax. /Some/ have other extensions to declare something as an I/O register at a fixed address. And other compilers have nothing of the sort, but rely on standard&sup1; C and/or linker scripts. The "@" form is most common in compilers for brain-dead 8-bit CISC architectures, which are rapidly becoming a thing of the past. With more modern cpu architectures, it is usually more efficient to access peripherals as structs with a base address, rather than a series of explicit addresses. In many compliers, the "@" syntax or other special I/O register syntax is tightly tied to fundamental types - you can use it for uint8_t, uint16_t and perhaps uint32_t, but not for "struct uart_t". It is certainly possible that compilers for modern cpus /could/ have a "@" syntax that works on structs, arrays, and other types. But there is /nothing/ that could be done with that syntax that could not also be done perfectly well with the "constant pointer kludge". And since these definitions are almost always buried inside an automatically generated chip-specific header file, "ugly" is of little relevance. &sup1; I say "standard C", with the proviso that the C standards say that "what constitutes a volatile access is implementation dependent".
> > The concept as I have found is just as useful in many languages I have > used. >
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?
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). -- Grant Edwards grant.b.edwards Yow! I'm using my X-RAY at VISION to obtain a rare gmail.com glimpse of the INNER WORKINGS of this POTATO!!
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). -Britt
On 09/03/17 16:04, Britt 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). >
I only know a little Ada, and haven't used it for anything serious, but I remember having seen something like that. So no need for an "@" extension there. I don't feel there is much wrong with the standard C method of making constant pointers such as I described. Walter called it a "kludge" - I specifically use quotation marks because I don't see it as a kludge. The only problem I see is that it defines the names as macros which don't obey scope.
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). 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.
On 2017-03-09, David Brown <david.brown@hesbynett.no> wrote:

> I don't feel there is much wrong with the standard C method of making > constant pointers such as I described. Walter called it a "kludge" - I > specifically use quotation marks because I don't see it as a kludge. > The only problem I see is that it defines the names as macros which > don't obey scope.
Agreed. Apart from the scope issue, I don't see any problems with the standard C "kludge". -- Grant Edwards grant.b.edwards Yow! Do you have exactly at what I want in a plaid gmail.com poindexter bar bat??
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. -- Grant Edwards grant.b.edwards Yow! Are you mentally here at at Pizza Hut?? gmail.com
On 2017-03-09 9:36 AM, David Brown wrote:
> Walter called it a "kludge" - I specifically use quotation marks > because I don't see it as a kludge. The only problem I see is that it > defines the names as macros which don't obey scope.
I referred it it as a kludge because it declares a variable as a pointer to an address expecting the compiler to optimize it as an address reference and in many compilers/linkers fails to provide the source level debugging support I would like. I wasn't using "kludge" as an insult but as a less than optimal way of describing what is desired. w..

Memfault Beyond the Launch