books for embedded software development

I'm quite certain I'm not certain ;-)

bgn-quote ar manual:

if

either

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.

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 :-(

Reply to
Alessandro Basili
Loading thread data ...

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.
Reply to
Rob Gaddi

There is usually an option/pragma to make unsigned the default.

-- Les Cargill

Reply to
Les Cargill

There is no such standard. It's a nicety of desktop dev. tools.

-- Les Cargill

Reply to
Les Cargill

On 12/16/2011 10:45 AM, RCIngham wrote: [...]

Thanks for the hint. I'll try that and see if I continue to loose interrupts.

Reply to
Alessandro Basili

[...]
[...]

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.

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.

Reply to
Alessandro Basili

You must either be a stupid anglo-saxon or living in the 1970s.

Why would most of the world care what some ancient 7 bit ASCII can support.

But many less_than or greater_than comparisons may fail.

This is a very (natural) language specific issue. The sort order can vary between applications even within the same language.

Reply to
upsidedown

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.

Reply to
upsidedown

I don't like exposing basic types for "special needs". If, for example, I have "user identifiers", I'd rather have a uid_t that I can map onto rather than deciding uid's "will" fit in a uint8 -- only to discover, later, that I *really* need them to be unsigned shorts (then I have to look at each thing that could be a uid and change its declaration to be "unsigned short").

If, instead, I treat them as "uid_t"s, I just change a typedef.

(I wish C was more strongly typed)

Reply to
Don Y

It's a requirement of all C implementations, hosted or freestanding:

From the C99 standard:

"5.1.2 Execution environments (1) Two execution environments are defined: freestanding and hosted. In both cases, program startup occurs when a designated C function is called by the execution environment. All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified. (...)"

"6.7.8 Initialization (...) (10) If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:

- if it has pointer type, it is initialized to a null pointer;

- if it has arithmetic type, it is initialized to (positive or unsigned) zero;

- if it is an aggregate, every member is initialized (recursively) according to these rules;

- if it is a union, the first named member is initialized (recursively) according to these rules. (...)"

Similar (actually slightly clearer) language exists in the C89 standard, but this was easier to quote.

There is no wiggle room to allow a confirming implementation to avoid initializing what is commonly called BSS storage (aka static objects without explicit initializers). On many, probably most, implementations a simple clear of the area produces the required result.

That there have been buggy implementations, or that some implementations allow you to modify the CRT startup code to avoid clearing BSS storage, is not in question, but in those cases you no longer have a "real" C environment.

Reply to
Robert Wessel

Which unfortunately often breaks many standard libraries and whatnot.

Reply to
Robert Wessel

It still leaves a problem when you manipulate values. What is the resulting type of '2 * x' when x is a uid_t ? And what formatting do you use to printf() a uid_t ?

Or how do you know that 'distance = speed * time' makes sense, given 3 abstract user-defined types ?

Reply to
Arlet Ottens

Hi Alessandro,

With 100% certainty?

Can the instrument "do anything" (dangerous, costly, etc.) if it is "insane" for an indeterminate length of time? (run down the battery, cause a course change, crash into the Sun, etc.) If so, the watchdog offers he potential for reducing this "period of vulnerability".

Understood. But how quickly after "losing its mind" can you detect that fact? I.e., do you (staff) make a conscious decision that it needs to be reset? Posibly after trying to command it to do certan things and then wondeing why it hasn't complied? Or, is that done mechanically/autoatically (*quickly*)?

Why would the main loop need to check the flag? Just stroke the watchdog in the idle() loop.

Rich's point about setting the flag "in the background" is to ensure that the ISR doesn't unilaterally stroke the watchdog. The flag ensures that the "background" is running. (i.e., if something goes wacky, it will hopefully prevent the flag from being set in a timely manner.

The complexity of your watchdog has to take into consideration how the application is *likely* to fail and the consequences of that failure. E.g., in "hostile" environments (i.e., where there are deliberate attempts to subvert your device) it can make sense to add mechanisms that detect those attempts and deliberately shut down the system (assuming this is the "safe" state)

Reply to
Don Y

Yes!

What is the result of 2 * x when x is a __________? I.e., if X is a unint8 but has the current value of

225?

With any type, you have to look at how the values are used in order to ensure the type of the result is appropriate to represent the value.

E.g., my arbitrary precision decimal math library configures itself to exploit the largest integer types available in the target environment. It does this by looking at the sizes of the "standard types" and determining what range of decades can fit into those types. But, also ensures there is a *larger* type that can be use to represent things like MAX+MAX+Carry (as the carryout logic relies on this).

Because you know what those types resolve to and reflect the uses to which you apply those types back to the type definition process.

E.g., I have a driver for a touchpad that implements fractional fixed point math (10b integer, 6 bit fraction). I have to be keenly aware of this representation whenever I apply arithmetic operations between these data types (C++ would have been nicer syntax as I could redefine the arithmetic operators instead of having to bend the code accordingly).

Reply to
Don Y

Which means that you have to be aware of the underlying type when you look at the code, which kind of defeats the purpose of having user-defined types in the first place.

When x=225, and represented as an 'int', I know that 2*x = 450. If it's defined as 'uint8_t', I know it will overflow. When it's a 'uid_t', I have no idea.

It also means you can't just change the 'typedef' without carefully checking the code to see if nothing breaks.

Reply to
Arlet Ottens
[%X--- Some stuff about Watchdogs --- ]

[%X]

Phil Koopman's and Jack Ganssle's books both have sections on proper considerations of watchdogs. Preference is for the kick to be in a part of the code that will only be reached if everything is running properly. Never, ever in a Timer ISR.

I like to hang a Pulse Maintained Relay onto one digital output. This output gets to change state only when all the sanity checks are completed in the back end of the idle task. If there are detectable errors (CRC failures or Memory Test Failures) Interrupt hogs or hanging loops, the relay will de- energise. If there is a single component fault within the Pulse Maintained Relay circuit the relay is de-energised. One of the relay contacts can be used to disable output power, another could kick-off the reset function.

--
********************************************************************
Paul E. Bennett...............
 Click to see the full signature
Reply to
Paul E. Bennett

You always have to be aware of what a type's capabilities are. Even standard types. You can't perform arbitrary operations on arbitrary types and hope the results are representable in that type.

Why have enums? Why not just use special constants? Why have ints instead of just using floats everywhere?

But that's only because you know what a uint8_t is. If you knew what a uid_t was, you'd have the same confidence in your answer as with that uint8. Do you think there are no bugs related to overflow with longs? :>

Do you *consciously* think about the resuts of every computation that you make to ensure the result, in ALL possible cases, fits? How often do you *reduce* types to get a "tighter fit" to the data? I.e., chances are, you use types that are "MORE than adequate" for the data you are representing.

You have to check your code when you replace a long with a short. The same applies.

C++ makes these sorts of things a lot nicer, syntactically. But, that makes costs of implementing the types *safely* too costly.

The same issue has been around forever. E.g., I've implemented

12b data (packed two per three bytes), 24b math libraries, 2048b math libraries (!) -- even a bit-wide memory subsystem, etc.
Reply to
Don Y

I was just thinking of the focal distance from the lens (or mirrors?) to the CCD, the point where the optical axis meets the CCD, and radial distortion. Also, if the focus isn't set well, you won't get good star images. I think it's pretty hard to automatically analyze star fields without knowing the above things, but since you are downloading the data and analyzing it offline, you might do OK.

Good luck to you!

Steve

Reply to
Steve B

As the Laconians so famously put it: "If."

So why not use the appropriate cross-ar? Wherever that ld21k came from you're practically guaranteed to find a matching ar21k, too. If all else fails, you can always try building your own binutils from source.

So what? Use it, and be done with it.

Reply to
Hans-Bernhard Bröker

Hi Hans-Bernhard,

I wasn't offering my disabling of this as an example of an implementation failing to do so. Rather, I mentioned it to illustrate how clearing uninitialized memory is a bad practice. That I force all memory to beinintilized explicitly.

You missed the ".runonce"

Are you "wastefully" clearing the contents of stack space? The heap? All string buffers?

Any uninitialized variable that you wouldn't *explicitly* "set to zero" is wastefully being *set* to zero -- only to later be set to its *correct* initial value. I.e., if the *first* reference to that variable isn't a *read*, then you've wastefully cleared it.

"Gazillions"? Just how much static memory do you declare in your applications?

YMMV, but the devices *I* design ten to have to run (effectively) "forever". I.e., many iterations and REinitializations. So, there *is* an explicit initialization step somewhere.

I.e., you *could* have:

int iterator; //uninitialized! ... do { // application } while (count < NUMBER); ... // otherstuff

But, if you ever want to do that *again* (without reseting your device), somewhere in "otherstuff" you will have to explicitly REinitialize "iterator".

Otherwise, you hear, "Hmmm... why isn't it working? Try unplugging it and see if THAT 'fixes' it."

What's "considerably more code"? Just hw big are these chunks of memory hat you *want* to have an *initial* value (i.e., first run-time access will be a READ) of "zero"? How much are you "saving"?

Does your device turn itself OFF -- having performed its duty -- when it has run through that do-while (since it can't run through it AGAIN)?

In your code reviews, how do you indicate which "uninitialized variable" warnings SHOULD be there (as "OPTIMIZATIONS"!) and which are signs of potential errors?

How do you discipline yourself to remember to initialize auto variables (i.e. taking that existing code and wrapping "functionname(){ ... }" around it suddenly makes your "optimzation stategy" useless)?

Startup clearing of uninitialized variables has no place in the reliable design of software. Just like failing to check the return value from malloc ("Aw, there's *plenty* of memory... no need to be WASTEFUL and *verify* that fact!") or verifying a string will *fit* into a buffer before blindly copying it there ("Heck, NO ONE could possibly have a surname with more than 20 characters so lastname[20+1] never needs protection!")

You are free to adopt whatever coding techniques fit your market. I don't like chasing down mysterious bugs that I can avoid through better discipline.

Reply to
Don Y

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.