Genius ..

Official FreeEMS vanilla firmware development, the heart and soul of the system!
User avatar
EssEss
LQFP112 - Up with the play
Posts: 244
Joined: Thu Sep 10, 2009 9:23 am
Location: Dayton, OH

Genius ..

Post by EssEss »

I'd just like to say that this:

Code: Select all

00076 #else
00077         /* let us know if we are being untidy with headers */
00078         #warning "Header file FUELANDIGNITIONCALCS_H seen before, sort it out!"
00079 /* end of the wrapper ifdef from the very top */
00080 #endif
... is genius. I usually walk through my code manually to pick out this scenario and I never, ever once thought about even considering automating it like this.
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: Genius ..

Post by Fred »

I'd like to take credit, but it's just std eclipse/gcc generated stuff polished a little till I liked it ;-)

Please bear in mind that Until Jan 08 I did not know C at all, so go easy on me, but suggest and question absolutely anything and everything.

I have a long list of things that I know need work, but I'm more than happy to hear them again from the outside. Esp after being away from it so much.

I should be posting some code again in the next few days, the first time in months. Hopefully I'll post it with some interesting video too :-)

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
MotoFab
1N4001 - Signed up
Posts: 307
Joined: Thu May 29, 2008 1:23 am
Location: Long Beach CA

Re: Genius ..

Post by MotoFab »

Fred wrote:Please bear in mind that Until Jan 08 I did not know C at all...
Go on, rub it in for us learned-assembly-by-default guys. :D. Just envious of course, I wish I had the time to devote to it.
User avatar
EssEss
LQFP112 - Up with the play
Posts: 244
Joined: Thu Sep 10, 2009 9:23 am
Location: Dayton, OH

Re: Genius ..

Post by EssEss »

nothing stands out immediately except for:
# when declaring a pointer make it (type* name) not (type *name)
# Never use int, always char, short or long
I disagree w/#1 because:

Code: Select all

int* pThing1, Thing2;
vs:

Code: Select all

int *pThing1, Thing2, *pThing3;
granted, I can't even remember that last time I did that, but I've seen others nailed by it multiple times.

I disagree w/#2 because the standard says that int is described as the most efficient native type for that platform. by restricting that you lose portability by making people aware of their platform. Along with #2, I recommend we use stdint.h and stdbool.h if you would like to enforce types - at least this would be in a more portable manner.

I think that you're working towards some kind of HAL, and the 5554 guys are actually depending on that. Thats the only reason I'm pushing on portability. As an experiment (if you need more convincing) use the compiler - observe the generated code when you force types and compare them side by side, the native type should show up as the most efficient. After that, the next problem you should run into is 'bounding' issues where your algorithims may inadvertantly depend on the 'width' of that type -- thats where something like units tests can help .. I enjoy CUnit

There are times when I disregard portability for the sake of readability by using struct bitfields, but usually only if it's 'deep enough' that it's not going to be very portable anyways - there is also usually a very hard spec in place too (like the serial comms, etc.). C is suprisingly portable if architected nicely - I commonly proto things out in msvc before even pushing it into my platforms.

This may give some ideas on how I can help out with the code base ?
User avatar
jbelanger
LQFP144 - On Top Of The Game
Posts: 387
Joined: Sat Feb 23, 2008 8:58 pm
Contact:

Re: Genius ..

Post by jbelanger »

EssEss wrote:nothing stands out immediately except for:
# when declaring a pointer make it (type* name) not (type *name)
# Never use int, always char, short or long
I disagree w/#1 because:

Code: Select all

int* pThing1, Thing2;
vs:

Code: Select all

int *pThing1, Thing2, *pThing3;
granted, I can't even remember that last time I did that, but I've seen others nailed by it multiple times.
I don't agree that you should have this type of declaration with a mix of pointers and values. It is effectively a good way of getting mixed up with variable types. Having said that, both can work and it's mainly a question of agreeing on a convention and respecting it. Having a convention (such as what you show) where the name indicates if it's a pointer helps reduce errors due to mix ups.
EssEss wrote:I disagree w/#2 because the standard says that int is described as the most efficient native type for that platform. by restricting that you lose portability by making people aware of their platform. Along with #2, I recommend we use stdint.h and stdbool.h if you would like to enforce types - at least this would be in a more portable manner.
I disagree with this because you will use the length of data needed for the variable and perform computations accordingly. In any case, you won't be able to port blindly and you will always need to check data size and computation overflows (or undeflows). But not using ints simplifies that because it will always result in what was intended. Once you have a working setup then you may want to optimise for the platform you're using (if needed) but that will give a non-portable code.
EssEss wrote:I think that you're working towards some kind of HAL, and the 5554 guys are actually depending on that. Thats the only reason I'm pushing on portability. As an experiment (if you need more convincing) use the compiler - observe the generated code when you force types and compare them side by side, the native type should show up as the most efficient. After that, the next problem you should run into is 'bounding' issues where your algorithims may inadvertantly depend on the 'width' of that type -- thats where something like units tests can help .. I enjoy CUnit
As I said, efficiency is good but correctness is better and necessary first. And the bounding issue you mention is not the exception but the rule, at least from my own experience and understanding. That is where most of the efficiency will come (both in memory allocation and execution speed). I'm not saying that this is an absolute but I think it applies here. And I'll have to look at your link more closely.
EssEss wrote:There are times when I disregard portability for the sake of readability by using struct bitfields, but usually only if it's 'deep enough' that it's not going to be very portable anyways - there is also usually a very hard spec in place too (like the serial comms, etc.). C is suprisingly portable if architected nicely - I commonly proto things out in msvc before even pushing it into my platforms.

This may give some ideas on how I can help out with the code base ?
I'm sure you can help with the code base. And even if we don't initially agree on the points above, doesn't mean it can't change. And in any case, Fred is the one who has to agree since he's the one who's done the coding work (amongst other things) and any work you do on the code will be more than what I've done. I'm just sharing my view on this based on my experience.

Jean
User avatar
EssEss
LQFP112 - Up with the play
Posts: 244
Joined: Thu Sep 10, 2009 9:23 am
Location: Dayton, OH

Re: Genius ..

Post by EssEss »

Jean wrote:I'm just sharing my view on this based on my experience.
This is exactly why I'm here, I truly am thankful for your perspective.

I really have no problem with adhereing to the rules at all. I've traditionally attacked #2 as you state by being very rigid in my choices and very aware of my platform, but picking up Python a few years ago has really turned around how I view my own embedded code. Which is why I lean on automated testing and less on static typing. I must admit that it has taken my code to 'the next level' - and of course everyones context is different. I am appreciative that Fred's guidelines and just that - I've had the most success with this style. Peer review usually degenerates into squabbling over style and template modification with something rigid.

Jean, I welcome more opinion:
stdint.h/stdbool.h get strong portable static typing - how do you feel about this ?

As also stated previously I accept/understand/appreciate that Fred is the final word. I'm not shooting for change - just spurring some conversation, since there is most likely some background I'm missing.
User avatar
jbelanger
LQFP144 - On Top Of The Game
Posts: 387
Joined: Sat Feb 23, 2008 8:58 pm
Contact:

Re: Genius ..

Post by jbelanger »

I'd be interested in hearing more about how Python changed your view of your embedded code so please elaborate.

As for stdint.h/stdbool.h, I've never used them and the compiler used on FreeEMS is not C99 compliant. But of course that doesn't prevent their use and I can see how that could make things clearer and potentially more portable. But I don't have any strong opinion one way or the other. This could change if I were to start using it but for something that may not be very portable such as what I suspect will be the case for a lot of the FreeEMS code, that might not be a big gain.

I must say that I've been doing c for quite a while so I've gotten used to doing things a certain way and stdint hasn't been part of it yet.

And I'm sure that Fred is the last person who would be against bringing up questions and suggestions. And if the suggestions are rejected you'll know why and it will make sense. And if you don't think it does make sense, he will listen to what you have to say and if you bring good arguments then he can change his view.

Jean
User avatar
EssEss
LQFP112 - Up with the play
Posts: 244
Joined: Thu Sep 10, 2009 9:23 am
Location: Dayton, OH

Re: Genius ..

Post by EssEss »

jbelanger wrote:I'd be interested in hearing more about how Python changed your view of your embedded code so please elaborate.
About 8 or so years ago I was getting sick of making the same mistakes over-n-over in C; It was my breaking point where I resolved to start taking control of the quality of my code. I knew it didn't have to be that way. I also happened to be surrounded by others who really didn't care much (about quality), and my search for a mentor resulted in nothing. I went in search of advice elsewhere and found the 'pragmatic programmer' book - it opened my eyes to a completely different way of doing things. All bits of advice 'spoke to me' - everything had a common thread - you're the one to make this happen if you want to take it seriously. No one out there will do it for you.

I started poking around the inet and stumbled across vast amounts of advice, one of them was to pick up some scripting to help automate tasks. I picked Python because it ran everywhere - it even interested me that you could embed it. It was active and surrounded by passionate people. lambda's and lack of typing competely baffled me - I wondered how could anything work like this ? was it even possible ? it must be, since it appeared to be very popular. So I just cranked out stupid app's and played around with it whenever I could - The eye opener was when I decided to see what this unit testing thing was all about. I stumbled on TDD about the same time too. Those two things were the breakthrough I was looking for - it was one of those ah-ha moments. Thats when I knew I found a solution.

I went back to working on some C and instead of being bland - it was technicolor. I was instantly reinvigorated by being able to see all kinds of faults in my logic and code, I could instantly see architecture flaws and even felt 'unsafe' without the safety net of tests to know that my code was doing what was intended. The simple act of picking up a new language, not just a progression of the same thing (c++), got me thinking in all kinds of different ways. I saw the ways where static typing could help AND hinder - I saw the ways where dynamic typing could help AND hinder. I discovered all those introductory texts on code sucked - 5 liner examples are a step backwards, the real power is in the idioms picked up with using the language.

In an effort to recreate what I discovered w/Python - I started trying to figure out ways to get unit testing going (and automating it all) in C. I did it. It was great. I was trying to find code everywhere and anywhere to try to apply all my newfound skills on, everything was snowballing and I felt on track again. I started to understand things in a deep manner, code reviews turned into code reviews .. not just shaking my head like everyone else. Things have become sharper and clearer than ever. Inside, I feel more dynamic than ever - I can adapt to anything and just roll with the punches. Solutions are just that, not a hack to fix some other day. That little voice in the back of my head is telling me that I'm on the right path, instead of constantly asking IF I'm on the right path. I recently discovered this book and thumbed through page after page saying to myself 'oh - I do that' - the confirmation is great. Counter to all the embedded advice out there on the inet, you could do these things in C - it didn't matter if you were on a PC or behind JTAG. My code is more robust and it's intention is clear. At least thats what I've been told.

I find myself throwing away a lot of code - I just churn through tons of it converging on a solution. It's liberating and I don't feel bad in the least about it because the final solution is elegant and wrapped in tests. Usually multiple solutions work, I just chose the simplest. My decision making skills are sharp and concise - I drill down to solutions quicker than ever (in all aspects of my life).


Maybe all of this just happened to coincide with the fact I was simply gaining experience :indiff: Maybe everyone goes through this. :indiff: I don't know, I have no mentors who can confirm this. I recognize that this may be a dangerous point on the experience curve :lol:

I know that this is just the start - I'm looking forward to what I can discover everyday.
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: Genius ..

Post by Fred »

I think Jean covered a lot of this, but I'd like to put some of it into my own words too.
EssEss wrote:nothing stands out immediately except for:
# when declaring a pointer make it (type* name) not (type *name)
# Never use int, always char, short or long
I disagree w/#1 because:

Code: Select all

int* pThing1, Thing2;
vs:

Code: Select all

int *pThing1, Thing2, *pThing3;
granted, I can't even remember that last time I did that, but I've seen others nailed by it multiple times.

I disagree w/#2 because the standard says that int is described as the most efficient native type for that platform. by restricting that you lose portability by making people aware of their platform.
1) If you are right, which I have no doubt about, then it is an ugly "feature" of the language. A typed variable declaration reads "type OF name" and to take the type and spread it into more than one place is ugly. I still advocate the way I said because I strongly prefer to never use a list of vars in a declaration, that is, I think it should be one statement per line, in this case, one variable declaration per line. Putting different types on one line is just ugly in my eyes.

short counter1;
short coutner2;

is better than

short counter1, counter2;

in my eyes.

2) If you use "int" then the code is actually NOT portable, whereas if you use char, short, long then it IS portable because the same behaviour AND accuracy and overflow etc will be present on both platforms. In the case of this chip alone, without porting it, a compiler flag change could totally break the code if int is used instead of an explicit type.
I think that you're working towards some kind of HAL, and the 5554 guys are actually depending on that. Thats the only reason I'm pushing on portability.
Some kind, maybe, fully portable I don't think is possible at this level. We are basically writing some math, glue code, ext interface and a hardware driver.
After that, the next problem you should run into is 'bounding' issues where your algorithims may inadvertantly depend on the 'width' of that type -- thats where something like units tests can help .. I enjoy CUnit
That is the thing, it isn't inadvertent, it is totally and necessarily explicit and intentional. You MUST be aware of the width of each variable to properly use it for accuracy and correctness. This absolutely goes for all mathematics, but also goes for things as basic as a loop in which you need to know how big it is going to go to use something large enough, likewise, if it goes smaller, you should scale down to compress the code. This core works nicely with both 8 and 16 bits so this choice is up to the programmer to make every time he declares something.
C is suprisingly portable if architected nicely - I commonly proto things out in msvc before even pushing it into my platforms.
I agree with this approach and am advocating it for the PID stuff, transient stuff and even averaging stuff.
This may give some ideas on how I can help out with the code base ?
In many ways, no doubt :-) Right now, the averging code would be a nice addition. How are you with Git?
I really have no problem with adhereing to the rules at all. I am appreciative that Fred's guidelines and just that - I've had the most success with this style. Peer review usually degenerates into squabbling over style and template modification with something rigid.
There are no hard and fast rules really, other than try to be nice most of the time :-) I'd much prefer the code stayed pretty consistent and that each block was the same throughout, but I won't cry about stuff that works but is different to my ideals. I may at my option "fix" stuff as I go though :-) I'm a bit like that... sorry.
As also stated previously I accept/understand/appreciate that Fred is the final word. I'm not shooting for change - just spurring some conversation, since there is most likely some background I'm missing.
I have to be the final word, by definition, BUT, I don't want it to be by iron fist, I want it to be the best solution, not just something that tickles my fancy. Some background to the (incomplete and draft) code style document :

http://issues.freeems.org/view.php?id=10

There is a broken link at the bottom of the page itself :

http://freeems.sourceforge.net/doxygen/ ... Style.html

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: Genius ..

Post by Fred »

jbelanger wrote:And I'm sure that Fred is the last person who would be against bringing up questions and suggestions. And if the suggestions are rejected you'll know why and it will make sense. And if you don't think it does make sense, he will listen to what you have to say and if you bring good arguments then he can change his view.
Thanks Jean! I (strangely) consider that one of the biggest compliments someone can pay me. I hope that that is an accurate reflection upon reality.

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
Post Reply