EmbeddedRelated.com
Forums

books for embedded software development

Started by Alessandro Basili December 12, 2011
Hi Hans-Bernhard,

On 12/16/2011 3:50 PM, Hans-Bernhard Br�ker wrote:
> On 16.12.2011 22:57, Don Y wrote: > >> Note that some implementations fail to clear that memory on startup! > > Such implementations would have to be classified as spectacularly > broken. You would need a pretty strong excuse for using any such > toolchain despite such failures.
I *deliberately* remove that activity from crt0.s I want to see an explicit initialization for each variable. (this is c.a.e not desktop.applications.runonce) Consider what happens when you restart a task. Those variables don't get reinitiaized. So, the second time a process runs, it uses whatever bit patterns happen to reside in those memory locations. "Gee, it worked LAST TIME; why is it broken, now?" (of course, if you have a really flush OS that can load processes and initialize their environments (like a desktop) then you don't face this problem) So, if you are going to explicitly initialize all variables and structs, its wasted effort to also do it on startup. (I like being able to examine memory contents on startup "before" initialization in post-mortem analysis... it doesn't do me much good to have memory cleared before any useful code can examine it!)
>> I.e., "0x27" is just as likely to be an uninitialized value. > > No. It's possible, but nowhere near as likely. > > You can make some implementations not intialize the .bss region (or > meddle with the startup to that end), but the ones where that happens by > accident are certainly _far_ outnumbered by the standard-conforming ones.
On 17.12.2011 00:34, Don Y wrote:
> On 12/16/2011 3:50 PM, Hans-Bernhard Br�ker wrote: >> On 16.12.2011 22:57, Don Y wrote: >> >>> Note that some implementations fail to clear that memory on startup! >> >> Such implementations would have to be classified as spectacularly >> broken. You would need a pretty strong excuse for using any such >> toolchain despite such failures. > > I *deliberately* remove that activity from crt0.s
In that case it's not "the implementation" that fails to clear that memory. It's you. There's a difference.
> (this is c.a.e not desktop.applications.runonce)
I consider that remark deliberately misleading. Embedded vs. desktop has nothing to do with this. Since when did embedded become synonymous with "wasteful"? Static variable initialization at startup, and particularly the part of it commonly known as "bss", is an optimization strategy. You disable that at a cost to code size and start-up speed which can be significant. You'll be calling gazillions of individual memcpy() and memset() equivalents, where a single one of each might have sufficed.
> Consider what happens when you restart a task.
Consider what happens if you don't.
> So, if you are going to explicitly initialize all > variables and structs, its wasted effort to also > do it on startup.
And if you initialize them all explicitly, even though re-initialization wasn't actually needed, you'll generate considerably more code for that particular job than if you had allowed the linker to help you with it.
On 12/16/2011 8:34 PM, Hans-Bernhard Br�ker wrote:
> On 16.12.2011 03:13, Alessandro Basili wrote: > >> The only missing piece is the archiver (the /ar/ utility does >> not support the COFF format!) > > I'm quite certain you got that wrong. 'ar' doesn't even care about > object file formats at all unless you try to use the 's' modifier. And > I've been using ar with COFF format file for about a decade --- it's > what the DOS port of of GNU tools has been using forever.
I'm quite certain I'm not certain ;-) bgn-quote ar manual:
> s Write an object-file index into the archive, or update an existing one, even if > no other change is made to the archive. You may use this modifier flag either > with any operation, or alone. Running ar s on an archive is equivalent to > running ranlib on it.
end-quote. Indeed if /ar/ doesn't understand COFF format it cannot create the index. Given the fact the ld21k (cross-linker for the 21k architecture) is looking for an index table, that means that I cannot use the /ar/ for linking. I can still use it simply to create an archive, but I don't see the use of it.
> > You may need to use a target-specific build of 'ar', though. I.e. > g21-whatever-ld and g21-whatever-gcc are meant to go with g21-whatever-ar. >
That is exactly the point. A 'target-specific' build of /ar/ *is* needed to support COFF format, in order for the cross-linker to use it. I had a conversation with Gregory McGarry (see magic data for file command) who told me that on NetBSD 1.5 the object format is ECOFF and the binutils is fully supporting it (objcopy/objdump/nm...). Unfortunately I failed to install it on my box :-(
On Fri, 16 Dec 2011 15:45:58 -0700, Don Y wrote:

> Where signedness is a real issue is when you try to use chars as "really > small ints" -- short shorts! There, it is best to define a type to > make this usage more visible (e.g., "small_counter") and, in that > typedef, you can make the signedness explicit.
Isn't this why God and ISO have given us stdint.h? So that you can distinguish between an int8_t, a uint8_t, and a char? -- Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix.
Simon Clubley wrote:
> On 2011-12-16, Don Y<not.to.be@seen.com> wrote: >> >> Using unsigned's for counts (can you have a negative number >> of items?). Using relative measurements instead of absolutes >> (e.g., "worksurface is 23 inches from reference; position of >> actuator is 3.2 inches from edge of worksurface" contrast with >> "worksurface is at 23.0, actuator is at 22.5 -- oops!") >> > > I strongly agree about the unsigned int issue. _Every_ integer I > declare in C is unsigned unless I actually need a signed integer. > > I find that the number of unsigned integers in my code is _vastly_ > greater overall than the number of signed integers. > > Personally, I think C should have made unsigned integers the default. >
There is usually an option/pragma to make unsigned the default.
> BTW, on a related data representation note, another thing I like to do is > when I build something like a state machine is to start the numbers > assigned to the state symbols at value 1, instead of value 0 so that I > stand a greater chance of catching uninitialised state variables. > > Simon. >
-- Les Cargill
Hans-Bernhard Br&#4294967295;ker wrote:
> On 16.12.2011 22:57, Don Y wrote: > >> Note that some implementations fail to clear that memory on startup! > > Such implementations would have to be classified as spectacularly > broken. You would need a pretty strong excuse for using any such > toolchain despite such failures. > >> I.e., "0x27" is just as likely to be an uninitialized value. > > No. It's possible, but nowhere near as likely. > > You can make some implementations not intialize the .bss region (or > meddle with the startup to that end), but the ones where that happens by > accident are certainly _far_ outnumbered by the standard-conforming ones.
There is no such standard. It's a nicety of desktop dev. tools. -- Les Cargill
On 12/16/2011 10:45 AM, RCIngham wrote:
[...]
> > Level-sensitive interrupts could be the answer here, if you are not already > using them. From memory (and it is quite a long time since I designed one > in), the ADSP-21k series allow(ed) you to specifiy interrupts as either > edge- or level-sensitive. >
Thanks for the hint. I'll try that and see if I continue to loose interrupts.
> > > --------------------------------------- > Posted through http://www.EmbeddedRelated.com
On 12/16/2011 3:22 PM, Rich Webb wrote:
> On Fri, 16 Dec 2011 08:58:18 -0500, Mel Wilson <mwilson@the-wire.com>
[...]
>> (I realize this is just a sidebar in a much more interesting post.) The >> motivation would have been: you should reset the watchdog in some very high >> level process that truly reflects that the processing is being done. >> Resetting the watchdog on, say, a timer interrupt keeps the watchdog happy >> even if the only facilities working are the timer and the interrupts. The >> rest of the processing could have completely fallen off the rails, and the >> watchdog wouldn't reset the system.
[...]
> > True. If one is stuck in an endless loop in the main process but the > watchdog kick occurs in a timer interrupt then one can get hung without > the watchdog reset occurring. >
Understood. Well, what is not actually clear to me was the choice of the watchdog in the first place. Our systems have all what we call "loader" which is a very primitive, i.e. simple, i.e. hopefully reliable, program that automatically boots on reset. Once this loader is running the system is waiting an external telecommand to load the "main" program. On top of it all the units have a hardware decoded reset telecommand, i.e. we can remotely reset the unit anytime is needed. In this scheme I actually fail to understand the reason for a watchdog. Assume the system doesn't have a watchdog and it hangs. At this point we have to send an external command to reset the system and then (after the small time required to load the loader) load the main application. The watchdog only saves an additional external reset command, it does not restore full functionality but just partial.
> One way to avoid that is to have the main loop set a permissive flag and > the timer interrupt test for and reset the flag and then kick the dog. >
> Of course, if the bit of code in the main loop that sets the flag is > included in the stuck endless loop, one still ends up with a broken > system. A defense against that is to use multiple flags or, perhaps, a > multi-valued flag: set to 1 at the top of the main loop; somewhere > inside a must-run portion, if flag is 1 then flag is 2; possibly > additional if/then levels; and finally have a periodic interrupt test > for the terminal value. Kick the dog only if all intermediate steps have > occurred. >
I actually like the idea of having it the other way around: - in the ISR set the flag that the dog needs to be kicked. - in the main loop check the flag and kick the dog accordingly. This should reduce the complexity of the ISR, which is only asserting a flag, and keeps the watchdog functionality in place.
On Fri, 16 Dec 2011 15:45:58 -0700, Don Y <not.to.be@seen.com> wrote:

>Hi Simon, > >On 12/16/2011 3:24 PM, Simon Clubley wrote: >>> The signedness of bare chars is implemented defined, presumably to allow >>> the compiler to pick whatever is easier to implement on the target. >> >> Interesting. >> >> That's something I'd forgotten about as I always declare them in full. >> Many years ago, before I started doing that, it seemed that every compiler >> I used treated a bare char declaration as signed. >> >> Is there literature somewhere online which compares what the current major >> compilers do on various architectures/operating systems about implementation >> defined issues like this ? I had a look before posting, but I couldn't find >> anything. >> >> BTW, that's a major argument for the position that the programmer should >> be required to explicitly declare the variable as signed or unsigned. > >For most folks, signedness of chars isn't an issue -- *if* you >are using them as "characters".
You must either be a stupid anglo-saxon or living in the 1970s.
>E.g., 7b ASCII doesnt care.
Why would most of the world care what some ancient 7 bit ASCII can support.
>Even 8b encodings still let you do many simple arithmetic >operations on chars without concern for sign. For example, >'2'++ is '3', regardless of encoding.
But many less_than or greater_than comparisons may fail.
>However, ordering arbitrary characters an vary based on >implementation.
This is a very (natural) language specific issue. The sort order can vary between applications even within the same language.
On Fri, 16 Dec 2011 21:26:03 +0000 (UTC), Simon Clubley
<clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:

>They aren't in my view (at least in C). As chars are assumed, like ints, >to be signed unless declared otherwise my mental model of a C bare char >declaration is a 8 bit signed integer so my comments also apply to char >declarations.
I had assumed that the C language data type "char" had something to do with the word "character" :-). For those still living in the Teletype era, the char signed/unsigned thing is not an issue, since no character codes had the most significant bit set. However, for most of the world, this sign issue is real when storing characters.