I'm starting a new PIC project that will reimplement some logic and
functions from a previous project, this time pulling more of the
functions into the PIC itself. This last project was the first one
with a non-trivial amount of functionality, and I found myself
struggling to keep my assembler code legible and understandable. Now
part of my design considerations for this new project is whether to
use a HLL (C, JAL) since I have significantly more memory than last
time (4KB now vs. 512B last time), but so far assembly still seems
like a good choice.
So to get to the question - those of you that program significant
amounts of code and complicated bits like TCP/IP stacks etc., what do
you do to keep your code structured in a useful way?
--
http://www.piclist.com PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
My answer is partly described and available for free with many examples from
http://www.embedinc.com/pic.
The same basic rules apply whether it's PIC firmware or some other software:
1 - Break function block into modules.
2 - Break individual functions within modules into separate
routines.
3 - Carefully document all interfaces. Don't just tell what a
subroutine does, but exactly what it expects, what it returns,
pre-conditions, etc.
4 - Document the purpose of all variables.
5 - Document the purpose of small chunks of code with paragraph
comments immediately above them. Chunks are typically a few
lines to 1/2 a page or so. Too small and it will be hard to
see the forest for the trees. Too large, and there isn't
enough documentation.
6 - Document the purpose of individual lines.
On PICs, we find MPASM doesn't provide sufficient features to allow clean
code to be written. That's why we have our preprocessor, PREPIC. Among
other things, it allows for named global flag bits, named I/O pins so that
the specific port and pin is not hard coded where the pin is used, floating
point assembly time calculations, the ability to hook existing MPASM
opcodes, and lots more. For details, see the PREPIC documentation file.
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
I do not think the issues around this are *that* different
depending on what tool one uses. I come to think about
things like :
- Meaningfull/clear variable names and lables.
- A good overall structure in the code.
- Probably slitting the application into multiple source files
to keep each file both more readable and also to make bugs
more "isolated" and easier to track down.
- Modular code also makes it easer to write test-cases that
runs lower level code without re-writing to much.
None of this is particular specific for assembler.
And of course make use of whatever tools MPASM/MPLINK provides.
(include files, macros, assembly time calculations, external/
global, REServing GPR's in the module that uses them and so on).
Relocatable code is a given, of course.
4KW (not bytes, right ?) is not that much. I guess some
of it will be occupied by tables and other "data" also.
Jan-Erik.
Of course you're right, and in C etc. I don't have this issue. What
causes me grief is that assembler is so damn verbose. It takes a few
lines to do every miniscule thing, so it's very easy to lose sight of
what you're actually doing.
Something that would take one or two lines in C (I'm using C as an
example since that's what I'm most familiar with on bigger processors)
ends up taking you 10-15 lines in assembly.
I guess the two approaches are writing novel-sized documentation and
using macros wherever possible... The macro approach, depending on
implementation, is almost the first step to a higher-level language
though.
>
> 4KW (not bytes, right ?) is not that much. I guess some
> of it will be occupied by tables and other "data" also.
>
KB - RAM, not flash memory.
Can you give a little more info on the type of chip you're using?
I described an OOP approach that we started using about 2 years ago ("[EE]
Implementing OOP features in C"). It's not a silver bullet, but it has
tremendously improved the quality and maintainability of our code. Following
the prescriptions to the "t" requires some overhead, so the maximum benefit
is realized on relatively large projects (5000+ of lines of code). However,
some of the rules have zero overhead (e.g., naming conventions) and most
have negligible overhead.
Vitaliy
You can still use inline or blocks of Assembler. If you really feel you
must. Unless you are doing very high volume or very constrained on
space, consider 18F family.
Even JAL is more easily translated/ported to arbitrary other language on
some non-microchip cpu than the best written assembler.
Going from an 18F2321 with an external UART-interfaced webserver
(SitePlayer) to an 18F67J60.
The original "memory" comment was probably a bit vague - my point was
that the 18F2321, with its 512 bytes of RAM (384 bytes of which were
basically static information that the code would process every second
or so, plus some UART string parsing) was exhausted fairly quickly.
But now , with a part with 4KB RAM, where the tasks will include a
TCP/IP stack, webserver, all kinds of wacky communications, etc., I'm
doubting my abilities as an assembly programmer when it comes to
organizing that volume of code.
On 2010-06-14 21:16, Marcel Birthelmer wrote:
>> Can you give a little more info on the type of chip you're using?
>
>
> Going from an 18F2321 with an external UART-interfaced webserver
> (SitePlayer) to an 18F67J60.
>
> The original "memory" comment was probably a bit vague
To say the least... :-)
> - my point was
> that the 18F2321, with its 512 bytes of RAM (384 bytes of which were
> basically static information that the code would process every second
> or so, plus some UART string parsing) was exhausted fairly quickly.
> But now , with a part with 4KB RAM, where the tasks will include a
> TCP/IP stack, webserver, all kinds of wacky communications, etc., I'm
> doubting my abilities as an assembly programmer when it comes to
> organizing that volume of code.
Well, that's a way other class of processor then I was
thinking of...
> Use JAL (or C) for 10F/12F/16F/18F and write reusable libraries with
> comments as if you are trying to understand someone else's code.
Speaking of JAL, is there a current list of supported devices? Enhanced
14 bit instructions?
Looking at the JALv2 site, I couldn't find it, nor is it in any of the
three PDF files I found there.
Thanks,
Bob
--
http://www.fastmail.fm - Accessible with your email software
or over the web
see
http://code.google.com/p/jallib/source/browse/trunk/?r=1655#trunk/include/device
319 devices
I'm doing an 18F67J50 thing in Jalv2
Or you can forego the comments and write self-documenting code. :)
Vitaliy
You can definitely benefit from the "OOP in C" approach.
One thing I dislike about the 18Fs is that you have to define extra types to
differentiate the type of memory you're accessing. Have you considered
moving on to a 16-bit PIC?
Vitaliy
> Michael Watterson wrote:
> > Use JAL (or C) for 10F/12F/16F/18F and write reusable libraries with
> > comments as if you are trying to understand someone else's code.
>
> Or you can forego the comments and write self-documenting code. :)
>
There is no such as self-documented code -- only lazy programmers :-)
Comments are telling you what the code meant to do -- as opposed to code,
which tells what did you (or somebody) do. So if you compare the two, you
would see if you (or others) did it correctly.
Tamas
>
> Vitaliy
> --
> http://www.piclist.com PIC/SX FAQ & list archive
> View/change your membership options at
> http://mailman.mit.edu/mailman/listinfo/piclist
>
--
int main() { char *a,*s,*q; printf(s="int main() { char *a,*s,*q;
printf(s=%s%s%s, q=%s%s%s%s,s,q,q,a=%s%s%s%s,q,q,q,a,a,q); }",
q="\"",s,q,q,a="\\",q,q,q,a,a,q); }
Your comment seems to imply that there are other kinds of programmers.
> Comments are telling you what the code meant to do -- as opposed to code,
> which tells what did you (or somebody) do. So if you compare the two, you
> would see if you (or others) did it correctly.
Deja vu -- I'm sure we've done this debate already. :)
In a nutshell, if you apply the "loose coupling/tight cohesion" principle,
and use appropriate names for variables and functions, you can eliminate the
need for most comments.
Whenever I see heavy use of comments, it is usually a good indication of
poorly written code.
[FLAME SHIELD ON]
--------------------------------------------------
From: "Michael Watterson" <mi...@radioway.org>
Sent: Monday, June 14, 2010 7:55 PM
To: "Microcontroller discussion list - Public." <pic...@mit.edu>
Subject: Re: [PIC] Structuring Assembly Code
> Marcel Birthelmer wrote:
>> ... Now
>> part of my design considerations for this new project is whether to
>> use a HLL (C, JAL) since I have significantly more memory than last
>> time (4KB now vs. 512B last time), but so far assembly still seems
>> like a good choice.
>>
>> So to get to the question - those of you that program significant
>> amounts of code and complicated bits like TCP/IP stacks etc., what do
>> you do to keep your code structured in a useful way?
>>
> Use JAL (or C) for 10F/12F/16F/18F and write reusable libraries with
> comments as if you are trying to understand someone else's code.
>
> You can still use inline or blocks of Assembler. If you really feel you
> must. Unless you are doing very high volume or very constrained on
> space, consider 18F family.
>
> Even JAL is more easily translated/ported to arbitrary other language on
> some non-microchip cpu than the best written assembler.
I take the simple approach of using whatever can meet the goals of the
project quickest. If it can be done in C, then I use C (possibly with some
assembly stuff called in for optimisation purposes - I hardly ever use
inline) which is usually the way I go for most stuff. If memory and speed
may be a real issue, then I use assembler. With either approach I try to
document stuff properly and keep things well organised and readable, the
extra time/care taken always pays for itself in the end. As mentioned, I use
18F most of the time as you get more for hardly any increase in cost. In
fact I have also really got into the PIC32 recently for a lot of things that
require a modest amount of memory or speed - a bit different and more
complex architecture, but well worth it for any medium to large projects.
Same argument as the 18F over 16F applies, and if volume is not too high
then it can make life a lot easier too. I'd be interested to hear about JAL
and any benefits it may have over C - can it be used for PIC32 also? (I
assume not as you don't mention it, but just checking)
--------------------------------------------------
From: "Vitaliy" <pic...@maksimov.org>
Sent: Tuesday, June 15, 2010 2:16 AM
To: "Microcontroller discussion list - Public." <pic...@mit.edu>
Subject: Re: [PIC] Structuring Assembly Code
> Tamas Rudnai wrote:
>>> > Use JAL (or C) for 10F/12F/16F/18F and write reusable libraries with
>>> > comments as if you are trying to understand someone else's code.
>>>
>>> Or you can forego the comments and write self-documenting code. :)
>>>
>>
>> There is no such as self-documented code -- only lazy programmers :-)
>
> Your comment seems to imply that there are other kinds of programmers.
>
>
>> Comments are telling you what the code meant to do -- as opposed to code,
>> which tells what did you (or somebody) do. So if you compare the two, you
>> would see if you (or others) did it correctly.
>
> Deja vu -- I'm sure we've done this debate already. :)
>
> In a nutshell, if you apply the "loose coupling/tight cohesion" principle,
> and use appropriate names for variables and functions, you can eliminate
> the
> need for most comments.
>
> Whenever I see heavy use of comments, it is usually a good indication of
> poorly written code.
>
> [FLAME SHIELD ON]
Hmmm, not sure if I agree with that one - rather a "brave" statement :-)
Obviously well named variables and functions make life easier and I can see
where you are coming from, but are no direct substitute for comments in a
lot of situations. When reading someone else's code, it can make
understanding things so much quicker, and can save having to skip from file
to file following stuff or guessing at intentions - even with your own code
it can make a big difference. I certainly cannot see how it follows that
heavy use of comments indicates poorly written code - though I note the
"usually". I think it may be more likely the unnecessary stuff might just
indicate over cautiousness and stating the obvious in an attempt to be as
clear as possible. For example "int AddTwoNumbers(int a, int b)" probably
doesn't need a comment stating the obvious, but I can see why people do it
just to be consistent and complete. Comments can be unnecessary or poorly
written *as well* as the code being so (maybe more likely if code is written
badly) but I tend to think that part of writing code well (of any reasonable
size/complexity) *includes* well written and appropriate commenting.
To me it indicates that there's someone who, like many,
(a) won't be able to remember in 6 months time what a snippet of code
does and why it was done in that particular way
(b) is being kind to others who read it
(c) has been though the code and justified/explained it to themselves
(perhaps not necessarily carefully but at least has attempted to) ....
(d) .... and therefore, hopefully, understands or is on the way to
understanding, the code
Poorly-written code and poorly-written comments don't have to go
hand-in-hand. Both are sets of facts and either could be completely
wrong without making other also wrong
For example, below might or might not be 'heavy' use of comments, as
almost every line has one, but it explains to me the functions and paths
of this section. At some time in the future I'm sure this will save me a
lot of time if I need to modify it or understand it again
Even if I added a paragraph of explanation before this code I would
still comment. The comments, labels, and mnemonics as a package
tell me exactly what I want to know
not_ok bcf mpow ;motor power relay off
nop
nop
bcf mdir ;motor direction relay off
chk_btns btfsc but_up ;check for Down or Up button
goto up ;Up pressed
btfss but_dn ;Down pressed
goto chk_btns ;neither
down call _251a ;read opto number into temp0
movlw .20 ;compare with Down limit
xorwf temp0,w
bnz ok_dn ;not limit, motor on, Down
call tx ;send as current opto number
goto not_ok ;at limit, don't move down
goto done ;finished
done display "Joe" ;indicate end of post
end
run
Joe
> > Whenever I see heavy use of comments, it is usually a good indication of
> > poorly written code.
> > [FLAME SHIELD ON]
> Hmmm, not sure if I agree with that one - rather a "brave" statement :-)
Nah. That's not brave. Just trolling :-).
Consider:
- "Heavy" & "usually" can be defended subsequently as a matter of
interpretation.
- He's loaded for Ol.. er, Bear. "Some people" advocate commenting in
a style that could be adumbrated to be criticised heavily by such a
remark, and they might be expected to come running. Might. (I probably
comment code at about the level tat Olin advocates, but, that's
another story.)
- How many people have you EVER had to ask to document their code LESS.
- How many of the many many many papers etc written on good
programming that you have met have recommended reducing documentation?
- How many listings have you read where you wished there were LESS
comments. (And how many where you wished there were more?).
- If you read your OWN code after 1/6/60 months do you tend to wish
for more or less comments.
- Short of a major problem, how many people are going to write comment
material in detail BECAUSE their code is poor. The implication is that
the documentation is perceived to be needed to make the code work
better (hasn't worked from Ada on), or to make people THINK your code
is good (some may look at documentation as primary evidence - most
just run the code first and see what it does.
- Would you buy a good low mileage only driven by a little old
man/woman on Sunday's horse/car/other from someone who advocated less
or lower levels of or minimal commenting?
- How well correlated, in your experience, are copious commenting and
the attributes and poor attitude that lead to poorly written code.
- It's 4pm Friday - I'm really looking forward to a weekend of
commenting my code".
- Nah, sorry mate, I can't get to the party, I have to ...
- I was running up against the deadline so I had to double the commenting.
- It would be completely obvious to any fish waving moron what this
port bit does, so I added a paragraph of comments.
...
____________________
There are, arguably, 5 levels of comments or related documentation levels.
Project description. Sets the stage
Per module or block or ...
ALL modules blocks will have SOME comments.
Usually will describe functionality.
Usually will list variables/parameters and may and describe them
unless well established at higher level.
Per paragraph of code - 1 to some lines. Commonly (1<= Some <= 10),
maybe 10-20, seldom > 20 depending on level of language and type of
routine. eg N lines of identical inline shifting, fall through NOP
stacks for isochronous timing adjustment etc will merit less comment.
All 'paragraphs' will have some form of comment
End of line or equivalent. Many or most lines will have such.
Variable/label/function/subroutine/ ... / names - self documenting.
No?
:-)
Russell
No doubt the miscreant was removed from the "campus" with
prejudice when the CSA heard of it...
Jack
Recently I had to do some small modifications on a project that was done
"OOP in asm". All variables resided in objects, and pointers to those
objects were passed around. The silly thing was that there was only one
instance of each object... Maybe worse was that there were almost no
comments (and little other documentation), and half of it was subtly out
of phase with the code.
So maybe there is a place for "OOP in XXX" (where XXX is a non-OOP
language) but it raises the possibilities for horrible code to a next level.
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
In my experience the correlation (if any exists) is the other way round.
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
--
One of the main things you should do if you are writing larger
assembly language programs is to formalize a more robust and general
purpose parameter passing mechanism for subroutines... ditto for
"local variables"
Macros that implement complex data structures are also very useful, as
well as those that let you implement some program control without
having to sprinkle obnoxious labels all over.
Basically, you want as many of the features that high-level-language
people have found to be useful as you can get without having to
actually use a language that doesn't fit the actual processor
architecture. (arguably, C succeeded because it was pretty close to
being a snazzy assembler
for a rather large suite of processors...)
As Olin said, MPASM isn't quite up to the task :-(
BillW
> Tamas Rudnai wrote:
> >> > Use JAL (or C) for 10F/12F/16F/18F and write reusable libraries with
> >> > comments as if you are trying to understand someone else's code.
> >>
> >> Or you can forego the comments and write self-documenting code. :)
> >>
> >
> > There is no such as self-documented code -- only lazy programmers :-)
>
> Your comment seems to imply that there are other kinds of programmers.
>
Recent years I rarely can see other kinds of programmers :-)
> Deja vu -- I'm sure we've done this debate already. :)
>
Do not worry, that was only adjusting the Matrix :-) But yes, we have been
discussing this already.
In a nutshell, if you apply the "loose coupling/tight cohesion" principle,
> and use appropriate names for variables and functions, you can eliminate
> the
> need for most comments.
>
> Whenever I see heavy use of comments, it is usually a good indication of
> poorly written code.
>
Interesting to see your experience. My observation was the opposite:
Whenever a programmer is lazy to comment, also lazy to write good and
self-documenting code.
Tamas
>
> [FLAME SHIELD ON]
>
> Vitaliy
>
> --
> http://www.piclist.com PIC/SX FAQ & list archive
> View/change your membership options at
> http://mailman.mit.edu/mailman/listinfo/piclist
>
--
int main() { char *a,*s,*q; printf(s="int main() { char *a,*s,*q;
printf(s=%s%s%s, q=%s%s%s%s,s,q,q,a=%s%s%s%s,q,q,q,a,a,q); }",
q="\"",s,q,q,a="\\",q,q,q,a,a,q); }
> - How many people have you EVER had to ask to document their code LESS.
>
I remember only one occasion: That was the time of 8 bit microcomputers. My
Father had this Apple II, and some programmers were developing a budget
calculator for him. Applesoft Basic were storing the comments in memory as
it was an interpreted language, therefore they run out of the 64KB RAM
because of the nice but huge comments they were doing :-)
Tamas
--
int main() { char *a,*s,*q; printf(s="int main() { char *a,*s,*q;
printf(s=%s%s%s, q=%s%s%s%s,s,q,q,a=%s%s%s%s,q,q,q,a,a,q); }",
q="\"",s,q,q,a="\\",q,q,q,a,a,q); }
Assembly program beginners (and sometimes C beginners too) tend to
comment what the instructions do, like
movlw 0x20 ; load value 0x20 into W
n++; /* make n equal to n + 1 */
I tell them to leave such comments out.
OK, I also ask them to comment *why* 0x20 must be loaded in W, or why n
must be incremented.
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
--
No Russell, I'm not trolling. Honest.
> - He's loaded for Ol.. er, Bear. "Some people" advocate commenting in
> a style that could be adumbrated to be criticised heavily by such a
> remark, and they might be expected to come running. Might. (I probably
> comment code at about the level tat Olin advocates, but, that's
> another story.)
Consider the possibility that we are both right. Olin's tool of choice is
assembler. The scope of my comment was limited to C.
> - How many people have you EVER had to ask to document their code LESS.
Someone actually told me more than once that I documented my code too much,
and that comments impeded his understanding of the code. This was before the
truth was revealed to me.
> - How many of the many many many papers etc written on good
> programming that you have met have recommended reducing documentation?
How many books teach waterfall as a valid project development methodology?
Why do both feel so unnatural?
The trend is changing. Our desktop brethren already embraced agile
methodologies, which advocate exactly what sounds so ridiculous to you: LESS
documentation.
> - How many listings have you read where you wished there were LESS
> comments. (And how many where you wished there were more?).
I don't recall wishing for either, anytime recently. I do recall thinking
many times, "this code can use some serious refactoring".
> - If you read your OWN code after 1/6/60 months do you tend to wish
> for more or less comments.
It hasn't been 60 months since we adopted the methodology. But I can easily
find my way around in code I wrote 1.5 years ago, and in my partner's code.
> - Short of a major problem, how many people are going to write comment
> material in detail BECAUSE their code is poor. The implication is that
> the documentation is perceived to be needed to make the code work
> better (hasn't worked from Ada on), or to make people THINK your code
> is good (some may look at documentation as primary evidence - most
> just run the code first and see what it does.
You don't have to go far. Look at Microchip's 18F library. It's a
wonderfully documented mess of a code.
> - Would you buy a good low mileage only driven by a little old
> man/woman on Sunday's horse/car/other from someone who advocated less
> or lower levels of or minimal commenting?
Sorry, I don't understand your metaphors.
> There are, arguably, 5 levels of comments or related documentation levels.
>
> Project description. Sets the stage
>
> Per module or block or ...
> ALL modules blocks will have SOME comments.
> Usually will describe functionality.
> Usually will list variables/parameters and may and describe them
> unless well established at higher level.
>
> Per paragraph of code - 1 to some lines. Commonly (1<= Some <= 10),
> maybe 10-20, seldom > 20 depending on level of language and type of
> routine. eg N lines of identical inline shifting, fall through NOP
> stacks for isochronous timing adjustment etc will merit less comment.
> All 'paragraphs' will have some form of comment
>
> End of line or equivalent. Many or most lines will have such.
Texbook style, followed it faithfully for years. Description for the module,
function block describing function purpose and parameters.
Nowadays have maybe one comment per 100 lines of code, only where necessary.
Why? The magic of "loose coupling, tight cohesion". The module name
describes its purpose. The header file contains all the access functions (a
small number, because public functions are the enemy of loose coupling).
Each function does exactly what its name says. Same goes for parameters.
> Variable/label/function/subroutine/ ... / names - self documenting.
>
> No?
Yes, but I suspect we would disagree on the definition of "self
documenting". Most people's code isn't self documenting enough, hence the
need for copious amounts of commenting.
Vitaliy
I tell new programmers, "ALWAYS use meaningful variable names and NEVER use
magic numbers".
numberOfNewStudents = UiHandler_GetNumberOfNewStudents();
studentCount = studentCount + numberOfNewStudents;
Vitaliy
That does help, but it is not the end. Some magic numbers are more clear
when used magically than when #defined somewhere. This 2 should *not* be
#defined somewhere else:
n = n << 2; // multiply by 4 to get the word offset
In assembly, registers don't have meaningful names :( But this is a few
parts of a graphics LCD driver:
#define R_IOSET R5
#define R_IOCLR R6
#define R_SET_ALL R7
#define R_XCLR R8
#define R_MASK R9
#define R_TEMP R10
LDR R_IOCLR, =MKT_IO0CLR
LDR R_IOSET, =MKT_IO0SET
LDR R_SET_ALL, =SET_ALL
LDR R_XCLR, =SET_XSCL
LDR R_MASK, =SET_DATA
// set XSCL and D0..D3
STR R_SET_ALL, [ R_IOSET ]
// shift 4 data bits to the correct position
// and mask all other bits off
AND R_TEMP, R_MASK, \REG, lsl #GLCD_D0
// write D0..D3
STR R_TEMP, [ R_IOCLR ]
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
--
It will be "he said, she said" until we look at some actual code examples.
It also depends on your definition of "poorly written code". Based on your
response to "n++" in your students' code ("use a comment to explain why
you're incrementing n"), I think it's safe to say that our definitions are
quite different.
The statement I made is controversial because it contradicts a long-standing
programming dogma. However, if you think about it, it makes perfect sense:
poorly written code requires a lot of explaining. Well written code requires
little or none.
Four years ago, I bought a Chinese MP3 player, that requires you to make a
series of non-intuitive button presses to perform simple tasks. To turn up
the volume up two clicks, you have to press [MODE][MODE][NEXT][NEXT][MODE].
You must read the manual to figure out how to fast forward or switch between
the player function and the picture viewer.
The iPhone has a volume control on the side, so the same operation is
completely effortless. Even complicated tasks are easy, because the
interface is so well thought out. The iPhone doesn't come with a manual.
Vitaliy
I did consider a PIC32 with ethernet MAC (as well as other ARM etc.
type processors), but even though this is mostly a one-off right now,
I can't help but feel that the price point is overwhelmingly in favor
of the PIC18 (especially since it includes the PHY).
I wish I could show you some of our code, so you would understand that
comments aren't necessary to achieve all of the nice things you listed
above. Alas, it's proprietary, but I am willing to answer legitimate
questions from those who decide to consider the subject with a sincere heart
and an open mind. :)
> Poorly-written code and poorly-written comments don't have to go
> hand-in-hand. Both are sets of facts and either could be completely
> wrong without making other also wrong
My premise is, perfect code doesn't need comments. Of course, no one writes
perfect code, but if you approach code writing with this mindset and strive
to write self-documenting code, you will find your need for comments greatly
reduced and in many cases, eliminated.
> For example, below might or might not be 'heavy' use of comments, as
> almost every line has one, but it explains to me the functions and paths
> of this section. At some time in the future I'm sure this will save me a
> lot of time if I need to modify it or understand it again
My comments are meant to be taken in the context of the C language. I have
close to zero experience with assembler. I'm sure some of the concepts are
transferrable, you can simulate procedures and "objects", but as we all know
TANSTAAFL: OOP comes at a price (bigger overhead) and if you start using it
in assembler you would probably be better off writing your program in a
higher level language in the first place.
Vitaliy
I've been through the phases. Like everyone else, I wrote spaghetti code and
named my variables "asdf;lkj". Then under the influence of my professors and
some of the books/articles I read, I started commenting my code religiously.
It never felt "right", though.
Writing self-documenting code is not easy, but practice makes perfect, and
with time it becomes second nature. And refactoring never feels like a waste
of time, like commenting often does.
You may remember when I first started looking into OOP for C, Xiaofan
suggested a couple of articles where the authors were emulating C++ in C.
IMO their implementations are a huge overkill, and I would have probably
failed miserably if I followed in their footsteps, because I'm not 1/10 as
good a programmer as they are.
Luckily, an author of a book on patterns suggested, "favor aggregation over
inheritance". If you don't use inheritance in your code, the task of
emulating OOP in a procedural language is greatly simplified, and you still
get 90% of the benefits.
Vitaliy
But as others mentioned, code with comments is more likely to be written
by someone who has put at least some effort into the work, which has
some correlation with writing good code.
Note that the correlation breaks down the moment you start measuring it
and acting on the measurements. This is something that is often
overlooked by the quality guys.
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
--
> Four years ago, I bought a Chinese MP3 player, that requires you to make a
> series of non-intuitive button presses to perform simple tasks. To turn up
> the volume up two clicks, you have to press [MODE][MODE][NEXT][NEXT][MODE].
> You must read the manual to figure out how to fast forward or switch between
> the player function and the picture viewer.
Aha!
[RCL] , [CHS] + [7] + [8]
That shows my age.
GoFlo will explain it :-).
I never owned one, alas.
I had 21 65 25 ... ?
I'd like a 35 - the one that properly started it all [tm].
Russell
Ah, perhaps I misunderstood your meaning of "poorly written". Are
you talking about *how* the code is written - the label and variable
names for example - rather than the efficiency of (possibly poorly-
constructed) code ?
Of course not, that's why you state the unobvious. In this case natural
questions would be why is this function here at all? Why is the built in
"+" operator insufficient?
> Comments can be unnecessary or poorly
> written *as well* as the code being so
Yes, writing good comments takes skill, just like writing good code. The
two go together. One can not replace the other since they serve different
purposes.
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
I have done that. First I define a set of "general registers" REG0...REGn
in unbanked memory. Usually, parameters are passed to subroutines in these
registers, and return values also in these registers. Also, the general
assumption is that subroutines preserve all the general registers they don't
specifically return values in.
Of course specific routines can break these guidelines when there is a good
reason to do so, but then must go out of their way to warn about the unusual
interface. I usually write a comment in the subroutine header like:
; WARNING: Trashes REG0, REG1, REG4.
> ditto for "local variables"
That makes no sense. Being local, they are invisible to callers outside the
module so there can't be any rules about them in that context. Inside a
single module you are a bit more free to do something unusual since its
scope is contained. You still of course need to document it carefully.
Still, I can't think of what formal rules should apply to local variables.
> As Olin said, MPASM isn't quite up to the task :-(
Have you tried PREPIC? It adds a lot of cool features to PIC assembler.
Doc file at http://www.embedinc.com/pic/prepic.txt.htm
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
So this isn't a request to comment less, but comment better, and is part of
the important process of teaching your students to comment well.
Unfortunately, teaching good commenting is something all too rare.
Personally, I think source code submitted to a programming class should be
graded about equally on functional content and documentation.
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
The thing you seem to be missing is that there is a tradeoff between what
you can explain with symbol names and what you can explain with comment. If
you make your symbol names too verbose, it takes away end of line comment
space that could possibly be used to explain some wrinkle no amount of
variable naming could explain. It also makes it more difficult to visually
see the structure of the code. For example, it takes a little longer to
visually parse your second line above to see that it has the basic structure
A <-- A + B
Conversely, some information can be succinctly explained with symbol names.
Comments and symbol names are different, and when used effectively
complement each other to provide good documentation in a way either alone
couldn't.
You have essentially chosen to phanatically push one to the extreme at the
expense of the other. Not good.
In your example above, we can see that new students are being added to the
count of students, but are these students of a particular class, the whole
school, something else? Or is this maybe in a general purpose subroutine
that deals with a pile of students and it's up to the caller to understand
the scope of this pile. All of these are legitimate, but those kinds of
questions are better answered by good comments in various places.
This is where you're wrong. Well written code may require a little less
explaining, but no amount of verbose and carefully chosen symbol names can
provide the kind of information that good comments can. The two work
together. It's not a question of which one is best.
More or less. occasionally there are comments that can be left out
without replacing by something else.
Note that it is not entirely the students faults: a comment is there to
state the non-obvious. But to a first-week asm progger it is really
non-obvious that MOVLW loads a constant value into W... So commenting
skill must grow with programming skill.
> Unfortunately, teaching good commenting is something all too rare.
Unfortunately only a few of my fellow teachers have done any serious
programming in their career. They are 100% teachers.
> Personally, I think source code submitted to a programming class should be
> graded about equally on functional content and documentation.
I wish I was allowed to do that. As it is, I must conform to a certain
percentage of students completing a course successfully. (Yes, really!
if, let's say, only 50% succeeds *I* have a problem!). There is enough
challenge in getting them to write anything that resembles working code.
I do reward good comments, but punishing the absence would be too much.
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
--
--------------------------------------------------
From: "Olin Lathrop" <olin_p...@embedinc.com>
Sent: Tuesday, June 15, 2010 1:00 PM
To: "Microcontroller discussion list - Public." <pic...@mit.edu>
Subject: Re: [PIC] Structuring Assembly Code
> Oli Glaser wrote:
>> For example "int AddTwoNumbers(int a, int b)" probably
>> doesn't need a comment stating the obvious,
>
> Of course not, that's why you state the unobvious. In this case natural
> questions would be why is this function here at all? Why is the built in
> "+" operator insufficient?
In this case, the function is "here" merely as an illustration of a point -
I would be asking serious questions of myself if this ever actually got used
in any of my code :-)
>> Comments can be unnecessary or poorly
>> written *as well* as the code being so
>
> Yes, writing good comments takes skill, just like writing good code. The
> two go together. One can not replace the other since they serve different
> purposes.
Yep, that is the general essence of what I was trying to point out.
Surely you can disclose a module or two of maybe a few 100 lines total that
is not implementing a central function of your business?
The rules Olin has offered are a good general case...
Just my opinion , of course.
John Ferrell, W8CCW
On 6/14/2010 1:57 PM, Marcel Birthelmer wrote:
> I'm hoping [PIC] is the appropriate tag here - if not, I'm sure some
> kind soul will take it upon himself to correct me.
>
> I'm starting a new PIC project that will reimplement some logic and
> functions from a previous project, this time pulling more of the
> functions into the PIC itself. This last project was the first one
> with a non-trivial amount of functionality, and I found myself
> struggling to keep my assembler code legible and understandable. Now
> part of my design considerations for this new project is whether to
> use a HLL (C, JAL) since I have significantly more memory than last
> time (4KB now vs. 512B last time), but so far assembly still seems
> like a good choice.
>
> So to get to the question - those of you that program significant
> amounts of code and complicated bits like TCP/IP stacks etc., what do
> you do to keep your code structured in a useful way?
John,
I'm not sure how the question is too vague - my problem, as stated, is
that on projects i've worked on with assembly code, I end up with
something that's hard to read and follow, and I'm not sure how to go
about structuring it any better. Hence my request for other people's
methods.
I'm not sure that there is much difference between hobby code and
commercial code, either... if I'm working on something intermittently
over a few months' time, there are bound to be parts of the code that
will be revisited only after several weeks/months, and those will sure
look foreign to me at first glance. And I definitely don't want to
have to reacquaint myself with the ugly mess of code each time.
I did get some valuable insights, and I'm going to see how I can adapt
those to my situation.
- Marcel
Being a person who is inherently unstructured in any sort of work, I
like to write out the proposed code in "high level pseudo code" without
any actual code that will assemble/compile. Then when I have
changed/restructured/whatever other changes deemed appropriate I then
use this pseudo code as the comments, and write the actual code in
between lines of the comment pseudo code. This may end up having a block
of the pseudo code as a large multi-line comment, or single lines of
pseudo code as a comment to a block of code.
Otherwise I tend to start coding, and find that I haven't taken into
account something, and end up having to rewrite considerable amounts of
code, instead of a few lines of pseudo code.
The pseudo code can start of as very broad brush stroke code, which can
get refined in several passes as I determine what variables are
required, and what blocks can be changed to make suitable subroutines
which can be used in multiple places by having suitable call parameters.
--
Scanned by iCritical.
Cheers,
-Neil.
On Mon, 14 Jun 2010, Vitaliy wrote:
> Michael Watterson wrote:
> > Use JAL (or C) for 10F/12F/16F/18F and write reusable libraries with
> > comments as if you are trying to understand someone else's code.
>
> Or you can forego the comments and write self-documenting code. :)
>
I cringe when I hear people talking about "self-documenting code". Not
because I'm an advocate of "heavily commented code" but because I feel
"self-documenting code" AND "heavily commented code" both miss the
point!
Code should be written so as to be easy to follow and maintain. Adding the
odd comment here and there is necessary when the code is doing something
obscure. But the comment itself does nothing to improve the code. It
doesn't tell the compiler / assembler / macro processor etc what the code
is trying to do, what exceptions to look out for, what side effect are
taking place, or aything else. Comments can be misleading to the human
trying to understand what the code is trying to do. In my experience,
reducing the volume of comments actually causes the programmer /
maintainer to read the source much more carefully and work out what the
code is actually doing rather than just skimming it and relying on the
comments to understand what is going on.
I've had to dig through a great many peoples code during the course of my
carear and the number of times I've found a mismatch between the code and
the comments is incredibly high. People fix code but are less prone to
fixing comments. Sometimes someone will fix a piece of code in one place
and not realise that the fix has implications on comments in some other
place. The compiler / assembler etc doesn't warn you. It can't it doesn't
understand the corrolation between the comments and the code. Sometimes
people just rip a piece of code from one place and embed it somewhere else
(comments and all) without understanding the comments at all. Then they
hack it to fit in with the new code and before you know it the old
comments are just a misleading waste of time.
Heavy commenting == BAD
Light commenting == not so BAD but why is it necessary? Why is the code
obscure such it needs commenting?
Regards
Sergio Masci
If you haven't learned that yet, no amount of PIClist posts will teach it to
you.
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
There are certain cases that I can't imagine how to make fully
self-commenting code:
1) Routines that implement communication protocols, are much easier to
understand with comments that correlate the code statements with what
they do in the protocol, or even embed parts of the protocol
specification into the code.
2) Certain code optimizations make the code very hard to understand and
need a lot of comments to explain how the code works.
Isaac
__________________________________________________
Fale com seus amigos de graça com o novo Yahoo! Messenger
http://br.messenger.yahoo.com/
Correct. I say "poorly written" for lack of a better term.
Vitaliy
Code can be very clear about what it is doing - good code might need
little or no comments for that.
But for a reader it is often more interesting to know *why* the code is
doing what it is so clearly doing.
Somewhere in the code of my shop's administration I will either multiply
an amount by FACTOR_VAT, or leave it as-is. It is clear what is being
done: in some cases I need to charge VAT, in others I don't. The
EC/Dutch rules for this are a bit complicated, so a comment could point
to a document clarifying these rules. One might argue that such a
pointer belongs in the specifications, not in a comment. Maybe. In an
ideal world. Sometimes.
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
--
> But for a reader it is often more interesting to know *why* the code is
> doing what it is so clearly doing.
>
Could not say better than that!
Tamas
>
> Somewhere in the code of my shop's administration I will either multiply
> an amount by FACTOR_VAT, or leave it as-is. It is clear what is being
> done: in some cases I need to charge VAT, in others I don't. The
> EC/Dutch rules for this are a bit complicated, so a comment could point
> to a document clarifying these rules. One might argue that such a
> pointer belongs in the specifications, not in a comment. Maybe. In an
> ideal world. Sometimes.
>
> --
>
> Wouter van Ooijen
>
> -- -------------------------------------------
> Van Ooijen Technische Informatica: www.voti.nl
> consultancy, development, PICmicro products
> docent Hogeschool van Utrecht: www.voti.nl/hvu
>
> --
> http://www.piclist.com PIC/SX FAQ & list archive
> View/change your membership options at
> http://mailman.mit.edu/mailman/listinfo/piclist
>
--
int main() { char *a,*s,*q; printf(s="int main() { char *a,*s,*q;
printf(s=%s%s%s, q=%s%s%s%s,s,q,q,a=%s%s%s%s,q,q,q,a,a,q); }",
q="\"",s,q,q,a="\\",q,q,q,a,a,q); }
Enough. There are at least four different types of comments:
1) You can comment how the code itself works, especially when tricky
things are happening:
swapf STATUS,w ;put unchanged STATUS in w with nibbles
reversed.
or
} /* time for new brightness */
} /* while forever */
2) You can document the algorithm that the (piece of) code is
implementing:
/*
* We have a random number in each PWMx between 1 and 128
* and we're going to have 128 cycles of delay. So each
* decremented value can only cross zero once, at which
* time we toggle the output state.
*/
or
;; standard code from http://piclist.com/math for 32bit multiply
by 10.
3) You can document what the code does at a higher level:
/*
* This implements the IP checksum as defined in RFC791, a long
with
* special functions to update and recompute when we do a TTL
decrement.
* See RFC1122 (requirements for internet hosts and RFCxxxx
(properties of
* the ip checksum algorithm) for additional details. This code
does NOT
* handle IP options that change value at each hop.
*/
or
;; OBD protocol low-level bit banging. Matches NSTI-1998
version of spec
;; tested against GYA-17 homologation suite.
4) You can document the history of the code:
;PS:<6-1-MONITOR>TCPTCP.MAC.43, 25-Mar-86 00:42:41, Edit by BILLW
; advertize optimistic windows based on number of interupt level
; buffer that are available at NUWNDO.
or
/* Be careful when checksum hits magic values; see bugID 1234 */
and
/* This is version 1.0 of the shipping XYZ code ! */
(oh yeah; no one has mentioned this yet: use some form of version
control
software, and document/checkin changes are a relative fine
granularity!)
All of these are "important" to some degree, especially for "large
projects",
and no one style of documentation is likely to adequately cover them
all...
"self documenting code" is clearly unsuitable for at least three of
them.
Now, many "projects" never achieve a complexity of code, algorithm,
conformance,
and history that is likely to require major attention to ALL of these
for the same
line of code. But you should think about them all at least a little
bit!
BillW
My favourite negative examples of commenting are nearly all GNU projects.
Usually there is a huge comment section at the top of the source, but that
only tells boring stuff like GNU licence and the like. They rarely actually
tell what the actual source is about, which module is that, sometimes not
even the name of the project it belongs to. I do not like spending hours
figuring out which module does what just because someone did not want to
spare 5 minutes to write 2 sentences -- if you know what I mean.
Tamas
On Tue, Jun 15, 2010 at 11:56 PM, William "Chops" Westfield
<wes...@mac.com>wrote:
>
--
int main() { char *a,*s,*q; printf(s="int main() { char *a,*s,*q;
printf(s=%s%s%s, q=%s%s%s%s,s,q,q,a=%s%s%s%s,q,q,q,a,a,q); }",
q="\"",s,q,q,a="\\",q,q,q,a,a,q); }
On 15/06/2010 16:37, alan.b...@stfc.ac.uk wrote:
>> I'm not sure how the question is too vague - my problem, as stated, is
>> that on projects i've worked on with assembly code, I end up with
>> something that's hard to read and follow, and I'm not sure how to go
>> about structuring it any better. Hence my request for other people's
>> methods.
>
> Being a person who is inherently unstructured in any sort of work, I
> like to write out the proposed code in "high level pseudo code" without
> any actual code that will assemble/compile. Then when I have
> changed/restructured/whatever other changes deemed appropriate I then
> use this pseudo code as the comments, and write the actual code in
> between lines of the comment pseudo code. This may end up having a block
> of the pseudo code as a large multi-line comment, or single lines of
> pseudo code as a comment to a block of code.
I second that notion. I find that thinking the system through using
flowcharts, psuedo-code and perhaps the odd bit of Python helps
enormously. Without producing a proper structure, even in rough, for what
I plan to implement costs me several times as much in time than it would
had I planned it properly.
- --
Brendan Gillatt | GPG Key: 0xBF6A0D94
brendan {a} brendangillatt (dot) co (dot) uk
http://www.brendangillatt.co.uk
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (MingW32)
iEYEARECAAYFAkwYGaAACgkQHEhZ5Ws5poHVgwCbB4PcK4Ef4aETviH8O2S5uqxy
I+cAoIqAr6JlXuMxTuCHVqnI7TGFuSnW
=2Ua+
-----END PGP SIGNATURE-----
Care to elaborate? I have no Python experience.
thanks, Jack
"There is only one thing in the world worse than having no
Python experience ....."
(Give us a bit of the wit, Oz)
By all means :)
Jack
p.s. - I'm still curious about the conjunction of pseudo-code
and Python...
I would not object to this kind of comment.
Vitaliy
On Tue, 15 Jun 2010, Olin Lathrop wrote:
> sergio masci wrote:
> > Light commenting == not so BAD but why is it necessary? Why is the
> > code obscure such it needs commenting?
>
> If you haven't learned that yet, no amount of PIClist posts will teach it to
> you.
>
Eh? Teach me what?
Regards
Sergio Masci
I like to comment assembly code embedding the corresponding C code as
end-of-line comments, aligned vertically sometimes after the 80th column.
Sometimes I start with C code, compile to assembly and then start
optimizing it. The original C code inserted as comments by the compiler
become my comments, and the comments I put into the C code end there
also, then I have a fairly well commented assembly code.
Of course sometimes it is impossible to express some assembly sequences
as (organized) C code, then I use pseudo-code the more like C as possible.
As a rule, I like to have my assembly modules available in C also, as a
reference and a starting point for porting to other platforms.
Isaac
__________________________________________________
Fale com seus amigos de graça com o novo Yahoo! Messenger
http://br.messenger.yahoo.com/
--
That good comments are necessary whether or not the code is obscure. Here's
a simple example from a outdoor light controller I wrote nearly 10 years
ago:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Note that for these two routines that W contains the month offset.
; In this way it can get the sunrise/sunset value for the current month or
; the next month, which is required to compute the difference over the span
; of the month. Note that January is repeated at the end of the list so that
; The december values can be computed without modification to the routines.
sunrise addwf month,W
addlw 255 ; Subtract 1 to offset for month from 1-12
addwf PCL,F
dt 163,154,126,85,49,28,31,50,72,92,117,144,163
sunset addwf month,W
addlw 255 ; Subtract 1 to offset for month from 1-12
addwf PCL,F
dt 40,69,94,118,141,163,172,158,123,82,45,29,40
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Taking another look at the comment, I forgot to note that the values are
the number of minutes offset from 5AM for sunrise and 5PM for sunset
respectively. Also that this system does not try to account for Daylight
Savings time and runs all year in Standard Time.
Even the small comment in the routine describes why the addlw 255 is
there.
That's the point. 10 years later I can look at the comments for this
routine and have a pretty good idea of how it works. A bit more complicated
example from the program is the usage of these tables to set the specific
sunrise/sunset value for a particular day. I didn't want to have a table
with 365/366 values for each day. So I used linear interpolation between
the offsets of two consecutive months above to approximate the
sunrise/sunset time. Here's that code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Set the sunrise/sunset time. We do this by interpolating the sunrise/sunset
; times at the beginning of the month. Linear interpolation over a 32 day
; month is done because it makes the fixed binary arithmatic easier. The basic
; algorithm
; 1) Get the current month's first day time
; 2) Get the difference from next month's time. Divide by 32.
; 3) Add 1/32 for each day into the month. Truncate to an integer minute.
; 4) Add/subtract the extra minutes from the 1st day offset
; 5) Adjust the offset to the correct minute/hour time for that day.
; We only need to do this once a day at midnight.
setset movlw 1
call sunset ; Get the sunset offset for the next month
movwf sunnext
movlw 0 ; Get the sunset offset for this month
call sunset
movwf sunoff
movlw 17 ; Start of the offset time 5:00 PM
movwf sunhour
call interp
movf sunhour,W
movwf sshour
movf sunmin,W
movwf ssmin
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Finally the interpolation routine is complicated. So like the others,
there's an explanation at the top. This time virtually every line of code
has a comment describing its purpose:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
interp ; Interpolate the sunrise/sunset time
; input in sunoff/sunnext/sunhour
; Result in sunhour/sunmin
movf sunoff,W ; Get the offset for the current month
subwf sunnext,W ; Find the difference between the two
offsets
movwf sunsign ; Keep the sign
btfsc sunsign,7 ; Check the sign bit
sublw 0 ; Negate by subtracting W from 0.
movwf sunnext ; Negate if negative. Sign still in sunsign
; We treat sunnext as a III.FFFFF fixed number. We need to multiply this
; offset by the number of days since the beginning of the month. However
; If the sum exceeds 1 we need to take the integer part and add/subtract it
; from the original offset and then remove it from our running sum
clrf sunfract ; Start at zero
movf day,W ; Get the current day
addlw 255 ; Subtract one. This is our count
btfsc STATUS,Z ; Done if first day of the month.
goto sscont2
movwf c1 ; Put in counter
ssloop movf sunnext,W ; Get the fraction
addwf sunfract,W ; Add to the current fraction
movwf sunfract
movwf tempw ; Save so we can shift and swap
rrf tempw,F ; Shift
swapf tempw,W ; Swap. III now in low three bits of W.
andlw 7 ; Ditch the rest.
btfsc sunsign,7 ; See if we need to subtract
sublw 0 ; Negate W if we need to subtract.
addwf sunoff,F ; Add to the offset
movlw 0x1f ; Only keep the fractional part
andwf sunfract,F ; So mask off the integer part in sunfract
decfsz c1,F ; Loop
goto ssloop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
It's not self commenting. And the comments are not unnecessary. In fact
looking at it 10 years later, it's a pretty good use of a fixed point
algorithm. But I wouldn't even want to try to figure out how it worked
without the comments.
And that's the point Olin is trying to make.
BAJ
--
Byron A. Jeff
Program Coordinator: IT/CS/CNET
College of Information and Mathematical Sciences
Clayton State University
http://cims.clayton.edu/bjeff
On 16/06/2010 01:55, John Gardner wrote:
>> ...and perhaps the odd bit of Python ...
>
> Care to elaborate? I have no Python experience.
>
> thanks, Jack
Python is really very nice to jot down outlines of algorithms with: it's
structure for loops is very clean and there are no parenthesis to deal
with. In fact it's syntax is similar to common pseudo-code, with the
added benefit that I can run the code without much trouble if needs be.
(See the example code in
http://en.wikipedia.org/wiki/Bresenham's_line_algorithm for example).
Say I wanted to set all the pins of a port with 1 second intervals
between them I could plan this with a section of Python:
for pin in range ( 8 ):
set_pin ( pin )
wait ( )
The alternative in a flowchart would be something like:
( START )
|
( pin = 0 )
|
|-------------+
| |
( Set pin ) |
| |
( pin ++ ) |
| |
< pin > 7? >--N--+
|
Y
|
( DONE )
which is obviously a bit more cumbersome.
I believe Pascal is the traditional language to quickly describe working
code with, though I have no experience with it.
- --
Brendan Gillatt | GPG Key: 0xBF6A0D94
brendan {a} brendangillatt (dot) co (dot) uk
http://www.brendangillatt.co.uk
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (MingW32)
iEYEARECAAYFAkwY0CgACgkQHEhZ5Ws5poFIsACfcmKEO4tFLyfUzvxoq9AxMIE7
SrUAnRJ2IWGJGwtdTwpShG/qaEUduDbS
=YmJ2
-----END PGP SIGNATURE-----
> Surely you can disclose a module or two of maybe a few 100 lines total that
> is not implementing a central function of your business?
Attached is an example of extreme commenting.
If people wish, it can be used as an example of how these comments
could be replaced by code without comments.
The reason that such an extreme amount of commenting is unnecessary
could also be explained.
The text below has been truncated at 60 characters per line to show
what the code to comment ratios are, but to avoid email system line
folding . The same code but untrimmed is provided in the attached
file.
This is for an interesting processor - it has only AND but not OR -
(or the other way around) it is now so long since this was writtten
that I do not remember which it is. I have not met another processor
where Demorgan's theorum was an essential part of programming, rather
than an option.
____________________
valid3key
;validrkey
; <KKH2> Here add a little bit of daring (with some d
; Now that a valid key has been pressed The record lin
; be set low (active).
; This has the affect of precharging the microphone ca
; and is aimed at reducing the initial "click" when re
; If recording is NOT wanted the line must be de-asser
; CS being taken low to avoid recording.
; ********** With MICON separate from RECORD this should
; The microphone can be enabled without riskin
; The above has been diminished in danger by reading B
; only lowering record if a record is requested. This
; not be early enough to prevent clicks and taking thi
; to before the last serial in will re-introduce the d
; NOTE that the code should not be taken back into the
; loop or the microphone would be on during normal key
; thereby drawing current when unneeded.
; IF the time added by this routine excessively increa
; delay (unlikely) the call to sout16 could be arrange
; when a change in the write request line status has o
; The write request line is not explicitly debounced b
; with other delays and should be effectively debounce
; Note that the Brecording flag is NOT changed (code w
; do this is commented out) as this is an "operational
jrr Bsinrecreq, sindata, preset_brec ; jr if record re
; i
set sout2pr, sout2nd ; set record line high
set sout2micon, sout2nd ; Microphone off
jp preres_brec
; ##########################################################
preset_brec res sout2pr, sout2nd ; set record
res sout2micon, sout2nd ; Microphone on
; Bugfix!?: 30.10.97 - don't allow extend to be decremented
; This was happening on sequential recordings when the
; held on between records.
ld a, K6lextend ; get extend count
cpi a, 0 ; if at zero leave i
jrz nodec
dec K6lextend ; Take 1 from extend
; always contain at
; and extend is only
nodec
jp putrecstatus ; K6L 20.8.97
preres_brec ; K6L 20.8.97
; K6L 20.8.97
; If we are here any level-extends achieved by record-
; should be cancelled as we are not recording.
ldi K6lextend, 0 ; Not recording so a
putrecstatus ; K6L 20.8.97
call sout16
ldi wdr, watchtim ; keep watchdog at bay
; <KKI4>
Last_Chance
; It appears we are all ready to go.
; Now we optionally ofer a "user debounce period based
; settings sin2data bits 0 to 2. If these are non zero
; about 80 milliseconds per count (0 to 7 counts) ther
; key activation delays of up to 7 x 80ms = 560 millis
; The LED is lit at the start of this period so that u
; see that their keypress is actually achieving someth
ld a, sin2data ; get DipSwitch settings
andi a, 07h ; keep only 3 lsb's
jrnz user_delay ; jr if user delay is wanted
jp no_delay ; jp if no delay
; ##########################################################
user_delay
; <KKI5 greatly remodelled to use irq timerud >
; Delay for user selected period
ld ud_temp, a ; save delay value
sla a ; double it
add a, ud_temp ; add to initial value --> 3 x mul
ld ud_temp, a ; save tripled value
set sout2led, sout2nd ; show that something is happeni
call sout16
ld a, ud_temp ; get tripled value
ld timerud, a ; set irq timer to N x 3 x 37.5ms
ld timerud, a ; = N x 0.1125 seconds
; We will now loop while the same key is held down unt
; the user releases the key or the "tremor" delay time
; There are 2 paths through this loop to account for b
; and remote keyboards.
ud_loop
jrs local, keymode, ud2_loop ; b if main keyboard
; Here if remote keyboard
call SIN4 ;) Remote Kbd testing
call SINKEY ;) Remote Kbd testing
jp ud3_loop ;) Remote Kbd testing
; ***********
; Main keyboard
z908
ud2_loop call KEYIN ; Get present key va
; Both keyboards
ud3_loop cp a, rawkeycode ; and see if user has pe
jrnz back_off ; jr if not same key, user has give
ld a, timerud ; check timer for expiry
jrz GoManGo ; jr / go for SRB ignition on time
jp ud_loop ; jp / still same key pressed so f
; ##########################################################
; same key not pressed, main engine shutdown
back_off
res sout2led, sout2nd ; show that something stopped ha
call sout16
jp no_key
; ##########################################################
GoManGo ; (note that LED is on)
no_delay ; liftoff
; <KKI4 end>
; <KKI5 start>
; Briefly flash LED to show record start.
res sout2led, sout2nd ; LED off
call sout16
ldi a, 014h ; for 50 ms
call sdelay
set sout2led, sout2nd ; and on again
call sout16
; <KKI5 end>
; **********************************************************
;
; A stable valid keypress has been detected.
; This is the stage at which we are committed to actio
; having been pressed. This code will be processed to
; an ISD address based on keymapping dipswitch setting
; will be taken based on whether we are in record, pla
; mode.
ld a, rawkeycode ; get validated keycode
andi a, 1FH ; use only 5 lower bits
; Change code to match binary key numbers
ldi drwr, keymangle.w ; point to lookup table
ldi x, keymangle.d ;.
add a, x
ld x, a
ld a, (x)
ld Vkeycode, a ; save modified keyc
; A now contains a 5 bit key number
; Translate keycode into speech address
; Original A is destroyed
; Results are in talkadhi & talkadlo (raw codes) & t
call keymap ; Translate code in A to address
; <KKJ3G> - use talkdurn to control sleep timing
;
; As a key has been pressed reset sleep timer to stop
; sleep.
;
; As the talk duration value is a direct multiple of t
; timer_pd interupt delay of 3.75s when its value is 0
; may be used to set timer_pd when key delays are long
; done timer-pd may time out and put the system to sle
; talking is finished.
ld a, talkdurn
; FALLTHROUGH 970813 cpi a, 0ch
; K6: ALWAYS JUMP jrc var_pd ; jr if big key
; K6L: Always jump also
; FALL THROUGH 970813 jp var_pd ;
var_pd
; Use variable power down delay
; K6L: This is rubbish for a K6L - will need to work on fina
inc a ; Make the delay a little larger to avoid
inc a ; clipping the end of speech.
; MODIFICATION NEEDED
; K6L temporary
jrs Bk6l, keymode, k6ltimerpd ; j if a
jp k6timerpd
k6ltimerpd
; get keylev delay flag
ld a, talkdurn
andi a, 00000001b ; 16.8.97
; convert to either 32 key mode = 1 or all others = 2
addi a, 01 ; becomes 1 for 32 key mode
ld v, a ; push delay
; add 1 extra leylev delay per extend count
cpi a, 1 ; If cnt is one we a
jrz addonce ; j if in 32 key mod
; per extend_count
add a, K6lextend ; else add an extra
addonce
add a, K6lextend ; add again (or once
ld K6lrectime, a ; save K6L recording
inc a ; extend time for sh
inc a
k6timerpd
; Bugfix (actually bug bypass) 28.8.97 1030 ish
; The speaking time for extended keys is less than the
; This can be confirmed by recording on level 1 with o
; a message fills most of level 1 and level 4. When th
; back, some is missing. However, if level 4 is played
; message is heard. Conclude: That timer_pd is shuttin
; IF this is what is wrong, rather than finding out wh
; by doubling the time provided.
; NOTE: Investigation shows that the time spoken for v
; always less than the correct time). This MAY be due
; decrementing of timer_pd relative to other timers as
; an interupt driven prescaler.
; GOTCHA (I think). Clearing timer2z prescaler seems t
SLA A ; double max allowab
ld timer_pd, a ; save delay to shut
ld timer_pd, a
clr timer2z ; Clear prescaler -
; .=.=.=.=.=.=.=.=
atlast
; At last, my address is whole again !
; ISD slot address is in talkadhi/talkadlo
; Now we need to decide what to do with it.
;
; Choices are -
;
; CONTROL
; Added at K6L
;
; Key may never get as far as speaking
;
; RECORD
; Recording continues while the same key remai
; the time allotted to the key is not exceeded
; keyup is required before the next key can be
;
; Calculate & output address, lower IS
; Lower ISD/CS
; Start key duration timer
; ? LED on ?
; While key down -
; leave ISD/CS down
; if timer expires
; Raise ISD/CS
; idle loop until keyu
; Keyup - Raise ISD/CS
; - pulse ISD/PD hi/lo
;
; PLAY - No Repeat
;
; A single low pulse of CS is provided. A key
; will idle loop until released. To initiate a
; the next key must be pressed after the curre
; finishes.
;
; Calculate & output address
; Pulse ISD/PD hi/lo (resets any prior
; Pulse ISD/CS lo/hi
; While key down - idle loop
;
; Play - Repeat Calculate & output address
;
; Monitoring of EOM/OVF is needed. When a key
; held down when a sequence terminates a new C
; initiated. Permanent output of CS would not
; the following message(s) would be sequential
;
; Lower ISD/CS
; ? LED on ?
; Pulse ISD/CS lo/hidown
; While key down -
; if EOM low going edge
; Wait till EOM goes h
; Pulse ISD/CS lo/hi
; Keyup Pulse ISD/PD hi/lo
;
; ==============================
;
; First some initialisation of flags which will be use
; proper action.
; 1.
; Find out if the user is attempting to record.
; set "Brecording" if user wishes to record.
; Note flags is 1 on record but request line is low on
jrr Bsinrecreq, sindata, set_brec ; jr if record reque
; is l
res Brecording, flags ; reqres high - not recording
jp res_brec
; ##########################################################
; zzzz1
set_brec set Brecording, flags ; reqres low - in
res_brec
;
onthefly
; "ON THE FLY" key processing
;
; 2.X - Added at K6L - see if this is an "on the fly" contro
;
; The "otf" controls are:
; 9.8.97: Changing of levels in 32 key mode.
; 3.9.97: Single key rotating level change.
; 3.9.97: and in 16 key mode
; These will be fairly hard coded here.
; Later on more generality will be required.
; 32 key mode level setting from keyboard
jrr Bk6l, keymode, nototf32 ; j/bypass i
jrs Brecording, flags, nototf32 ; j/bypass i
jrs B32key, keymode, testotf1 ; j to otf i
jrs B16key, keymode, testotf1 ; j to otf i
jp nototf32
testotf1
; If here, we are in 32 or 16w keymode and not recordi
; See if the key pressed is a level shift key.
; LS keys are currently in the LH column of 4 keys.
; Codes (after keymap) are 00h, 04h, 08h, 0Ch.
; To test the level keys against the current level the
; to be translated into the levels 0,1,2,3.
; While "clever" coding could be used the easiest meth
; explicit test and set for each value.
;
; "As it happens" the key codes output by Keymangle are iden
; those used here so the translation is un-needed SO FAR but
; leave it in so we can make change easily.
ld a, Vkeycode ; get saniti
andi a, 00011111b ; ensure onl
; If a "real" translation was happening the keycodes to be t
; appear in the following line eg cpi a,"keycode"
; The keycodes from keymangle start at "00" in the bottom lh
; increment by row and then by column.
cpi a, 00h ; Key = 00?
jrnz not0a ; j if not k
ldi a, 00h ; else trans
jp lshift01 ; and go to
not0a
cpi a, 01h ; Same as ab
jrnz not0b
ldi a, 01
jp lshift01
not0b
cpi a, 02h ; Same as ab
jrnz not0c
ldi a, 02h
jp lshift01
not0c
cpi a, 03h ; Same as ab
jrnz not0d
ldi a, 03h
jp lshift02
not0d
jp nototf32
; ****************
Thanks. Think I'll look into Python a bit further.
Jack
I don't have a problem with the amount of comments, but it's a remarkable
example of how to write large volumes of largely useless babble. The all
important what the module does is missing from the header comments. It
dives right into details without any context. I'm sure some of the context
would come from understanding what the overall system was supposed to do,
but still, there is nothing explaining what this module as a whole is
supposed to do and how it fits into the system.
You know bad code will follow when the module comments start with "Here add
a little bit of daring...". Not only is this immature, but the word usage
is so messed up to make it difficult to follow. Why is the programmer
telling us what we should be doing? He probably meant to indicate that he
thinks this code is "daring", whatever that's supposed to mean to us. The
missing periods, random capitalizations, and overall lack of neatness in
formatting make this module difficult to follow even if you had some idea
what it was supposed to do.
Some of the end of line comments are meaningful, but then there is stuff
like "K6L 20.8.97". There's lots more, but I've got real code to write.
FYI: Python is my first choice for all PC programming. Nice syntax,
libraries for almost everything you can imagine, good portability to
Linux, etc.
Small minuses:
- slower that a language that compiles to machine code
- a user must either install python, or you'll have to wrap your program
using something like py2exe, the result will be big
- there is no compilation-time type checking
- there is no module abstraction other than using separate files
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
--
On Tue, 15 Jun 2010, Wouter van Ooijen wrote:
> > Light commenting == not so BAD but why is it necessary? Why is the code
> > obscure such it needs commenting?
>
> Code can be very clear about what it is doing - good code might need
> little or no comments for that.
>
> But for a reader it is often more interesting to know *why* the code is
> doing what it is so clearly doing.
>
> Somewhere in the code of my shop's administration I will either multiply
> an amount by FACTOR_VAT, or leave it as-is. It is clear what is being
> done: in some cases I need to charge VAT, in others I don't. The
> EC/Dutch rules for this are a bit complicated, so a comment could point
> to a document clarifying these rules. One might argue that such a
> pointer belongs in the specifications, not in a comment. Maybe. In an
> ideal world. Sometimes.
Yes I agree with you that sometimes "*why* something is done" is obscure.
And as you alude to yourself, this can be because someone else reading the
code you have written may not understand the complexities of the rules
involved. I understand this and agree, however, adding comments to the
code to clarify this is in my opinion probably not the best way to help
the reader. Where do you add the comments, everywhere the variable or
constant is used? Ok, maybe just where it is declared. So the programmer
ends up gathering together all variable and constant declarations and
commenting these. Fair enough. So now we have reduced the commenting of
our use of the variables and constants of our program. We have made it
easier for the reader to follow the code because he/she knows where to
find the information about these things. Consequently we don't need to
pepper our code with this redundent information. However now we have
another problem, we WANT to keep variables and constants belonging to
seperate modules with those modules and not be forced to move them to a
central place.
Your argument that "such a pointer belongs in the specifications" is a
good one. Perhaps what is needed is a seperate level of documentation that
sits between the specification and the source code, one that gives an
overview of variables, constants and algorithms - maybe arranged in a
hierachy. Then a reader could read that before diving into the code.
I think one of the biggest problems we have is that "people" expect to be
able to dive into some source code (at any point) and expect to be able to
quickly fix or change its behaviour without needing to understand the
entire system. And for this to happen they expect comments in the source
to help.
I argue that if you need to comment something like:
// add the VAT to the subtotal giving the total.
// VAT is a percentage
t = s * (1 + v / 100);
Then the programmer is doing something seriously wrong.
Code commenting should be for obsure things that can't be calrified by
cleaning up the code. e.g.
// note: reading the USART clears the receiver ready flag,
// so save a copy of the receiver ready flag first
flag = USART_status;
ch = USART_buff;
I also argue that you should use the computer and (development) software
to help you wherever possible. In short write your code so that it is
easier for the compiler to spot mistakes, easier for you to unit test
modules, easier for you to understand a module and simply replace it if
needed rather than waste time trying to track down obscure bugs in it.
Commenting does NOTHING to help the development software track down a
problem or identify a misunderstanding. Comments are open to user
interpretation. They can be broken by an update to the code. A relevent
comment might be in a place you haven't visited yet. Just because a
comment says something should never happen at this point in the code
doesn't make it so. If you need to put checks in place then put them in
place in which case the comment is redundent. If you don't need to put the
checks in then a comment wont help you anyway and it centainly wont help
the compiler of debugger.
Many people seem to think that it's ok for code to be obscure because it's
intended for a machine. Code doesn't have to be obscure, the intension of
the code doesn't have to be obscure. You can wrap it up so that it is easy
to follow and those bits which can't be should then be documented
(includeing comments if needed). But seriously, adding an ocean of
comments to your code doesn't help you write better code, it just lets you
get away with writing BAD code which on its own is hard to follow.
Regards
Sergio Masci
Yes it does. Forcing yourself to explain what you're doing to that mythical
person looking over your shoulder catches mistakes that never become bugs.
One of the objections I have heard to comments is that they take time. If
you use comments effectively, they actually save time just with the initial
writing and debugging of the code, let alone the savings in maintainence
later.
An ocean might be a bit over the top, but writing some comments
certainly helps (compared to writing none). At the very least it forces
you to sit back and look at your code from a distance, and to ask
yourself "now what would a fresh reader of this code need to know to
understand it?".
Note that "help" is not the same as "force" or "guarantee" or the like.
There is still no silver bullet. (But Brooks has written a new book,
"The design of design".)
--
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: www.voti.nl/hvu
--
Except for the second, those are huge minuses, in my opinion.
On Wed, 16 Jun 2010, Wouter van Ooijen wrote:
> >> But seriously,
> >> adding an ocean of comments to your code doesn't help you write
> >> better code,
>
> An ocean might be a bit over the top, but writing some comments
> certainly helps (compared to writing none).
I agree "some" will probably be necessary. What I really detest is when
people look at the code to comment ratio and dismiss the code (without
even bothering to try and understand it) because in their opinion there
are not enough comments. Forget that the code might actually be easy to
understand or that there may be explanitory documentation elsewhere that
clarifies everything.
> At the very least it forces
> you to sit back and look at your code from a distance, and to ask
> yourself "now what would a fresh reader of this code need to know to
> understand it?".
Yes I understand exactly what you are saying here. Sometimes I look at my
own code and think "this is too complex, I need to break it down more".
Sometimes I look at it and think "I need to do too much explaining, it's
crap, I need to re-write it". Sometimes, like you, I think "this needs
some reference to external stuff that explains why I'm doing this".
Like you, I don't try to explain *everything* in the comments embedded in
the code. That would just add noise and make it difficult to see what the
code is trying to do.
>
> Note that "help" is not the same as "force" or "guarantee" or the like.
> There is still no silver bullet.
Again I agree, but I think you've got to define the level of person you
are willing to help. I mean, are you going to write documentation that is
going to help a complete novice understand your code or an expert.
Probably someone on the same level as you if this is a comercial
application and probably someone at a lot lower level if it's for teaching
purposes.
Regards
Sergio Masci
As this is personal in many aspects, you can safely ignore many of the
extreme comments from "comments are a must" to "comments are useless".
Comments and documentation in general may or may not be useful, depending on
many factors. Using previous sample Safety critical system implementation
will mandate you to strongly document every minor piece of your
design/code/test and map it to higher level requirements, being reviewed by
2 or more independent people, etc, and being maintained by many years. So
documentation of what you are expected to do is just mandatory, no question.
On the other hand, a web page may live for a day and be obsolete in just
hours, documentation may be overkill, useless and obvioulsy unnecesary cost
increase. Some developers don't have a vast experience on working in too
different systems so will offer a valid opinion but probably for the
applications they are familiar with.
For the specific context you ask the question for, sweet spot is probably in
the medium range of above two extreme examples. I would suggest the approach
of successive refinement and refactoring: start by a code that just works
for the main functionality you want, with minimal or no documentation at
all. Review your code to honestly criticize ugly parts (i.e. hard to
understand. inefficient, too large) and split in meaningful smaller
procedures and probably complement with comments. Depending on how much time
you want to dedicate to the task, refactoring over refactoring will put you
in a much cleaner code with limited documentation effort required.
Note above is about "refactoring for clarity and maintenability" which is
not necesarily the same than "refactoring for best performance".
HTH
2010/6/14 Marcel Birthelmer <marcel...@gmail.com>
>
>
> So to get to the question - those of you that program significant
> amounts of code and complicated bits like TCP/IP stacks etc., what do
> you do to keep your code structured in a useful way?
>
>
--
Ariel Rocholl
On Wed, 16 Jun 2010, Olin Lathrop wrote:
> sergio masci wrote:
> > But seriously,
> > adding an ocean of comments to your code doesn't help you write
> > better code,
>
> Yes it does. Forcing yourself to explain what you're doing to that mythical
> person looking over your shoulder catches mistakes that never become bugs.
The same could be said for designing the software properly before writing
the code. You could use flow charts, psuedo code, OO diagrams etc.
>
> One of the objections I have heard to comments is that they take time. If
> you use comments effectively, they actually save time just with the initial
> writing and debugging of the code, let alone the savings in maintainence
> later.
Ok, granted you've found this to be true in your experience, however I
have found that:
(1) all to often too many comments obscure the real *warnings* that need
to be seen.
(2) tons of explantory comments are actually there because the code is
badly written and is difficult to follow. Here the answer is to re-write
the code, make it simpler so that you don't need to rely on the comments.
(3) the comments can be misleading and although they tell you that the
code is doing one thing, the code is actually doing something else because
the person that wrote it doesn't understand or someone has changed the
code and / or comments incorrectly.
In short I *always* find it more productive to work through the code and
treat the comments as suspect.
Regards
Sergio Masci
Yes, and the two are independent. I agree you don't want to just write code
without understanding the structure of the system it will fit into and how
it will fit within that structure. None of that, however, should keep you
from writing good comments once you do start writing the actual code.
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
Then you'll never work here. This is one of the simple first pass filters I
use to look at a candidate's code. I'm not expecting a comment on every
line for the quick visual style inspection, but a whole page of executable
code without a comment is a serious red flag. After the first impression I
look more carefully, particularly at subroutine header comments, and then a
few random pieces of code in the middle of something.
The lack of comments in any one piece of code is not the issue, but the
sloppy nature that invariably accompanies sparse commenting is. Those who
think there is such a thing as "self documenting" code need not apply.
Depends on the person, I believe. Of course, "production" code is
expected to be that way (and it is expected to cost a lot, but what if
the budget is limited?).
But when developing and debugging the code some developers are quite
comfortable with keeping the uncommented code in their short-term (up
to week) mind "cache". The code is getting changed many times,
writing/rewriting comments at this stage would be just a waste of
time.
Of course, on cleaning the mind "cache" you need to give birth to
comments and write them down. In my better years (best years were
System 360 - related) I was able not only to handle the uncommented
code for weeks, I was able to write chunks of hundreds of PIC words
even without a compiler, just memorizing all the PIC's commands in
Hexadecimal. My programmer would then take the code from the text file
and burn it into a PIC.
But again, I agree 100% with Olin on comments for "production" code
(provided the budget were enough).
On Wed, 16 Jun 2010, Olin Lathrop wrote:
> sergio masci wrote:
> > What I really detest is
> > when people look at the code to comment ratio and dismiss the code
> > (without even bothering to try and understand it) because in their
> > opinion there are not enough comments.
>
> Then you'll never work here.
Don't sweat it Olin, you couldn't afford me anyway :-)
> This is one of the simple first pass filters I
> use to look at a candidate's code. I'm not expecting a comment on every
> line for the quick visual style inspection, but a whole page of executable
> code without a comment is a serious red flag. After the first impression I
> look more carefully, particularly at subroutine header comments, and then a
> few random pieces of code in the middle of something.
So do you actually work through the code and check it against the
comments, or do you just skim the code and belive the comments? It's far
more important to me that I be able to work through someone's code without
having to perform contortions - that I don't have to rely on comments that
cannot be automatically verified.
>
> The lack of comments in any one piece of code is not the issue, but the
> sloppy nature that invariably accompanies sparse commenting is.
Why "invariably"? You seem to have had exposure to a lot of crap source
code that you found hard to follow or you've worked with a lot of very
poor programmers who couldn't cut it.
> Those who
> think there is such a thing as "self documenting" code need not apply.
As I said before, I'm not an advocate of "self documenting code", but I do
belive you can write code so that it is simple to follow and requires a
low level of commenting.
which part of the above following line is true?
rrf fred ; increment fred
Regards
Sergio Masci
If the budget is limited and you want to achieve minimum cost, then
you should, of course, take care to comment very well indeed.
Russell
Does generating comments really take time? I can type about as fast as I
can think, so it really takes no time to comment as I go along. I'm
thinking how the code works anyway, so it's real quick to write it down.
Harold
--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!
Or not to comment at all in the case :-)
During a interview I'm only trying to get a impression of the person and how
good a engineer the candidate is. Good engineering requires attention to
detail. This appears to be a overall character trait. When someone is
sloppy about one thing, they are invariably sloppy in other areas too. I
have never seen a sloppy person make a good engineer.
Stepping back and thinking about each line of code you write at one level
higher, then writing down that explanation, and for sections of code, and
following some basic style rules shows attention to detail. The opposite is
the "eh, who cares" or "eh, I'll get to it later" attitude that is a sure
sign of a poor engineer. So comments and consistant style are things to
measure a software engineer by directly, but more importantly for a
interview, they are a good indicator of the mentality required for
engineering.
Also keep in mind that any code that a candidate shows you during a
interview was carefully picked. If that code is even marginally sloppy,
imagine what the rest looks like.
>> The lack of comments in any one piece of code is not the issue, but
>> the sloppy nature that invariably accompanies sparse commenting is.
>
> Why "invariably"?
It's just how people are. We may think we can change our style, but we
really can't much and for long.
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
On Wed, 16 Jun 2010, Olin Lathrop wrote:
> sergio masci wrote:
> > What I really detest is
> > when people look at the code to comment ratio and dismiss the code
> > (without even bothering to try and understand it) because in their
> > opinion there are not enough comments.
>
> Then you'll never work here.
Don't sweat it Olin, you couldn't afford me anyway :-)
> This is one of the simple first pass filters I
> use to look at a candidate's code. I'm not expecting a comment on every
> line for the quick visual style inspection, but a whole page of executable
> code without a comment is a serious red flag. After the first impression I
> look more carefully, particularly at subroutine header comments, and then a
> few random pieces of code in the middle of something.
So do you actually work through the code and check it against the
comments, or do you just skim the code and belive the comments? It's far
more important to me that I be able to work through someone's code
without
having to perform contortions - that I don't have to rely on comments
that
cannot be automatically verified.
>
> The lack of comments in any one piece of code is not the issue, but the
> sloppy nature that invariably accompanies sparse commenting is.
Why "invariably"? You seem to have had exposure to a lot of crap source
code that you found hard to follow or you've worked with a lot of very
poor programmers who couldn't cut it.
> Those who
> think there is such a thing as "self documenting" code need not apply.
As I said before, I'm not an advocate of "self documenting code", but I
do
belive you can write code so that it is simple to follow and requires a
low level of commenting.
which part of the above following line is true?
rrf fred ; increment fred
Regards
Sergio Masci
No, you'll roughly divide by 2, although the high bit of the result is
uncertain in this snippet because we can't see how the C bit was previously
set. For example, this would do a integer divide by 2 of a unsigned number:
bcf status, c ;set 0 bit to shift in
rrf fred ;divide by 2
Whereas this does a integer divide by 2 of a signed number:
rlf fred, w ;replicate sign bit to shift in
rrf fred ;divide by 2
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
Not always true.
Engineers work with compromises. A good engineer will choose the best
compromises. Unfortunately (or fortunately depending on your
perspective) that decision does not always lie with the engineer.
I've seen many cases where the engineer simply was not given the TIME to
do proper documentation (this includes commenting, but extends to many
other areas). I think everybody here knows that sometimes you are in a
time crunch, and the "details" start to go by the wayside.
Yes, in the long run everything takes more time without proper
documentation, but to label the engineer as "bad" is incorrect.
Yes, sample code brought to an interview cannot invoke this excuse.
TTYL
Yes, exactly what I tried to say. I talked about budget limitation.
That's the same as time limitation, in the context.
Some documentation does take time, but commenting code as you write it takes
so little extra and *saves* time even the first time thru. Not commenting
code because of a deadline is simply a fallacy.
Think about it. How many milliseconds does it take per line to add a
comment? And then is your line writing really limited by typing anyway?
Actually chunks of lines often are, but the additional wait time to think
about a chunk before writing it dwarfs the extra little time the comments
will take to write in that chunk. Weigh that against the minutes or even
hours to find and fix a single bug that could have been avoided by forcing
yourself to explain your code to the mythical person looking over your
shoulder. It just doesn't add up. Code comments *save* time, and not just
in the long run. If nothing else, think of them as a low cost first pass
debugging step.
> I think everybody here knows that sometimes you are in a
> time crunch, and the "details" start to go by the wayside.
Only for bad engineers. Some additional investigation and the like may go
by the wayside, but the implementation details can't.
> Yes, sample code brought to an interview cannot invoke this excuse.
Exactly. Although you'd probably be surprised at some of the excuses I've
heard about code brought to a interview. I haven't heard one I consider
valid yet. This is like interviewing for loan officer of a bank and showing
up in a T shirt and jeans. The excuse "my good clothes are in the laundry"
is just going to make you look more stupid than you already do.
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
True.
> Not commenting
> code because of a deadline is simply a fallacy.
Not true. Why? Because I don't think anybody on the planet can write a
program that is "correct" the first time through.
Software has bugs. Fixing those bugs often requires many iterations of
changing of the code, sometimes little things (i.e. where a loop
terminates), sometimes big things (changing a routine to run
recursively).
As a result, comments get "out of date". If you're changing a routine
multiple times in order to narrow down a problem it is NOT reasonable to
expect the comment to be updated in every iteration if you are under a
time crunch.
When the issue is resolved undoubtedly another issue appears, and more
comments get out of sync.
A "good" engineer with enough time in the budget will then go over the
changes and ensure comments are corrected/amended/removed as necessary.
This is non trivial time wise, and sometimes not worth the effort
(update the comments or miss the deadline and get fired? Hmmm...).
> > I think everybody here knows that sometimes you are in a
> > time crunch, and the "details" start to go by the wayside.
>
> Only for bad engineers. Some additional investigation and the like may go
> by the wayside, but the implementation details can't.
Sorry Olin, I live in the real world, I know that is not universally
true. When a deadline looms details DO go by the wayside, a good
engineer doesn't just focus on details, he/she focuses on what's
necessary to solve the problem, sometimes a kludge is acceptable if it
means the product meets the deadline.
> > Yes, sample code brought to an interview cannot invoke this excuse.
>
> Exactly. Although you'd probably be surprised at some of the excuses I've
> heard about code brought to a interview.
To be frank, I consider sample code in an interview useless, since it
doesn't tell me much more then the resume. Sample code is easy to
perfect (since the candidate has a near infinite amount of time to get
it that way), might not even BE from the candidate (a friend wrote it
and told them what it did) and shows nothing as to the candidates ACTUAL
attention to detail and skill while working under a crunch.
When we interview we actually ask technical questions and have the
candidate write code in front of us on the white board. That is where
you start to get an idea of their proficiency. It becomes clear very
quickly whether the person is a good fit.
TTYL
But this is exactly where comments help.
> As a result, comments get "out of date". If you're changing a routine
> multiple times in order to narrow down a problem it is NOT reasonable
> to expect the comment to be updated in every iteration if you are
> under a time crunch.
Of course it is, since doing so **saves time**. As you write new code, you
write the comments to go with it. The same logic for writing comments in
the original code applies to any changes.
You also make it sound like debugging changes a lot of code. Usually very
little code actually changes as a result of debugging. You mostly find
stupid stuff where you forgot to add or subtract 1, added where you meant to
multiply, etc. It's actually quite rare that major structural changes are
required as a result of debugging. The vast majority of code does "just
work".
Today is as good a example as any. I was adding offset and gain calibration
capability to firmware I'm in the middle of developing for a 30F4013. The
actual offset and gain computation is rather trivial. The larger amount of
code had to do with commands and responses to get the values from the host,
write them to EEPROM, send various values to the host so it can compute
calibration values, the host test program code to provide a user interface
to the new commands and response, compute calibration values from raw
numbers in a file, update the docs for the new commands, etc.
In this process I made two mistakes. In one place I was accumulating 16 bit
A/D readings into a 32 bit value, and forgot to sign extend. It's not that
I didn't know I needed to, but when it came to writing the code I just
forgot. The second mistake was not clipping the result of the calibration
computation to the full scale range. Previously this variable held the raw
A/D reading which couldn't exceed 32767. After offset and gain was applied
it could, and I forgot that this variable was treated as a signed number in
some cases, so the out of range values wrapped to negative.
In both cases, the problem was evident from the symptoms, and the fixes were
trivial, just a couple lines of code in either case. I didn't even use the
debugger, just dumped new versions to the board and looked at the symptoms.
Of course I've made bigger mistakes that took a lot longer to figure out,
but what happened today is more typical. Think about it. How long do you
really spend debugging and how much does the fix end up changing the code?
> A "good" engineer with enough time in the budget will then go over the
> changes and ensure comments are corrected/amended/removed as
> necessary.
In my experience, that never gets done. Once it's a mess, everybody always
has something better to do than to clean up the mess.
> This is non trivial time wise, and sometimes not worth the effort
> (update the comments or miss the deadline and get fired? Hmmm...).
Non-trivial only if you let it get that way in the first place. Letting
that happen is bad software development and counter-productive, especially
when a deadline is looming.
> To be frank, I consider sample code in an interview useless, since it
> doesn't tell me much more then the resume. Sample code is easy to
> perfect (since the candidate has a near infinite amount of time to get
> it that way), might not even BE from the candidate (a friend wrote it
> and told them what it did) and shows nothing as to the candidates
> ACTUAL attention to detail and skill while working under a crunch.
>
> When we interview we actually ask technical questions and have the
> candidate write code in front of us on the white board. That is where
> you start to get an idea of their proficiency. It becomes clear very
> quickly whether the person is a good fit.
I actually agree with this. Sample code is only to show the "guaranteed not
to exceed" level. It's amazing how low that level often is though, which is
why it's still useful to look at. Perfect sample code is no proof of
anything, but bad sample code is.
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
Time before the due date can be short, but I always make some
effort to tidy up afterwards, if only for my own records and personal
satisfaction. This helpful when and if a review is necessary
Agile/refactoring/self-documenting code help a lot with this. You don't have
a "cleanup phase", it is seamlessly integrated into the process.
Vitaliy
A few exemplary paragraphs would be good.
R
Defending "a kludge" practice is not a good idea as for me. And I did
not mean it when I said that sometimes for some developers it's OK to
go with almost no comments. Clean, well-structured, self-explanatory
code by the only developer on a project could be OK within some
reasonable time span when working on a separate program module, in my
opinion.
> Defending "a kludge" practice is not a good idea as for me
Well, there are kludges and then there are kludges. Some may put
the product out of spec, and even a little O/S might disappoint some
customers. No comments won't affect a product's performance, but
could have other consequences that may affect that one and/or future
products or the business
>No comments won't affect a product's performance, but could have
>other consequences that may affect that one and/or future
>products or the business
I've been following this thread with great interest.
I don't consider myself to be a 'great' programmer - I'm competent
with PIC assembler but definitely NOT a superstar.
For example, Vitaliy talks of 'self-documenting' code. Because I am
not used to reading such code, I think that it would take me days to
learn from the code what the system is supposed to be doing.
For me, what works is comments. Lots and lots of comments.
Comment blocks at the top of each major code block that tells me what
the intent of that block is. The comments tell me any 'gotchas' that
might bite me if I make changes a couple of years down the road.
Comments at the end of many line of code that say useful things like
"active LO" or "active HI" or "cntr decs to 1, then
stops". Sometimes the line comments say obvious things - but not often.
For example, look at the following code chunk.
;mulitply MS digit by 10, add LS digit, done!
movwf TMP0 ;W contains MS TW value
addwf TMP0,F ;*2, clr C
rlf TMP0,F ;*4
addwf TMP0,F ;*5, clr C
rlf TMP0,W ;*10
addwf TW_LSB,W ;add ones digit
movwf TW_TIME ;thumbwheel time delay in 100ms ticks
goto DoneTW
The comments at the end of each line tell me years later ** WHY ** I
used 'addwf' instead of 'rlf' when I wanted to double the value
contained in TMP0 in line 2. Yeah - what the code is doing is
obvious, especially when you read the comments. But would you notice
that its important that C be cleared if modifying that code several
years down the road? Would you notice that you would have to
pre-clear C if you did decide to change that 'addwf' to 'rlf'?
I guess the best way I can put it is this: comments are for MY
benefit. Not the customer's. They help ME do a better job.
Olin says that writing comments adds hardly any time to writing the
code. I'm not Olin, I'm not even in the same league. I find that
writing useful comments - especially the comments at the front of
major code blocks - takes time.
But the time spent writing those comments IS useful.
Its useful while writing the comments - they help clarify in my mind
what the code should be doing. Its useful when writing the code - I
can look at the comment block to make sure that I'm doing what I'm
supposed to be doing.
On the other hand - writing comments at the end of lines of code
takes almost no extra time. The key here is to be careful NOT to
write useless or trivial comments - its shockingly easy to write
useless stuff because your head is wrapped up in what the code is
doing. You have to exercise discipline to NOT write obvious comments.
dwayne
--
Dwayne Reid <dwa...@planet.eon.net>
Trinity Electronics Systems Ltd Edmonton, AB, CANADA
(780) 489-3199 voice (780) 487-6397 fax
www.trinity-electronics.com
Custom Electronics Design and Manufacturing
I've described the agile methodology, refactoring, and the concept of
self-documenting code on many occasions. Which part do you want me to
explain? :)
Vitaliy
I think you would be surprised at how much easier it is to read
self-documenting code, than to follow the comments.
Here is a snippet of code from an actual project (an ECU simulator):
int main(void)
{
Initializer_InitializeAll();
StnEcuSim_Run();
return 0;
}
Few will disagree that comments would be completely redundant here. Or, for
example, if you see this function call:
StnUart_SetBaudRate(UART_1, 9600);
Do you need a comment to tell you that it sets the baud rate of UART1 to
9600?
Comments have a number of huge drawbacks. First, they double the amount of
work upfront: you say what you want to say in code, then you explain what
the code says. It gets worse: code changes, so now you have to update the
corresponding comments. And you have to update them in multiple places, and
you are never sure that you got them all. You can't completely trust the
comments, so you have to read the code too, to verify.
In practice, comments are either omitted because they create too much extra
work (and you're in a hurry) or they act as a straightjacket: you want to
restructure a block of code, but you know that you will have to change all
the line comments too, so you say "forget it."
Self-documenting code does not have these problems. You just follow a few
simple rules, for example a function name should describe exactly what a
function does. If there is a discrepancy, it usually means that the name is
wrong, or the function is doing too much and needs to be split up. When you
change the name of the function, the compiler won't let you forget to change
it everywhere.
Vitaliy