Code Mania

Ho-boy. Lots to get through today. Time to put on my wizard hat and cape, and try to be entertaining once again.

 

First things first. Calling all Melbourne AVR Freaks! That is, anyone who like electronics (in particular, but not at all limited to, AVRs) and that is free this Thursday (23rd of June). Atmel’s got a Roadshow on during the day which I sadly won’t be attending, but the plan is to go out afterwards and have a drink at the Grand Mecure Hotel bar in the city. There’s an AVRFreaks thread about it, but don’t let that fool you, all are welcome to join in and have a beer.

Now, on to why I’ve been silent these past few weeks; I’ve been busy with my mid-year exams. Being silent is not my normal state of mind nor is it my preferred state, but another week or two of this crud and I’ll be home free; while I’ve still got one semester to go before I head off to Atmel Norway next year, I’ll only be enrolled in my end-of-year project and a single other subject. Quite frankly that sounds like pure heaven itself over this last hellish semester.

Last week my girlfriend, her sister, her sister’s boyfriend and I went out and did something I haven’t done for a while, and only done once before (yes, yes, insert your favourite joke here) – and went go-carting. Given that I was less nervous this time and the track was much bigger, I think I actually went rather well, and managed to navigate a good twenty laps without crashing once. That’s a much, much bigger improvement over my last Norwegian attempt, which saw me burned, whiplashed and facing the wrong way more than once along the track. Actually, the one real difficultly I had was that the track direction was the opposite to Trondheim’s, so while my brain said TURN LEFT, I had to correct and steer right to avoid a messy crash and a fine (for breaking the barriers). This event also unlocked the inner grannies in my girlfriend and her sister, who managed to not only go around at a snails’ pace, but to somehow unintentionally block me from passing on a two-and-a-half-car wide track for several laps. Watch out Atmel, next time I’m going to burn rubber and kick ass.

 

One of the compliments I get about my code a lot is that it is very readable and clean. I do like hearing this, but its been making me wonder what the heck kind of code is out there in the wild to make everyone think mine looks prettier. Thinking about this some more, I think I’ve unlocked the secret. In K&R’s holy C book, the language authors manage to lay down not only the formal parser grammar and syntax that makes up the C language, but also a set down an unofficial style convention, which favours brevity. Take this code:

unsigned int bitcount ( unsigned int i ) {
	unsigned int r = 0;
	while ( i ) { r+=i&1; i>>=1; }
	return r; 
}

Which I pulled randomly off a StackOverflow comment. Look at it. He’s the same code reformatted to the way I’d write it:

uint8_t bitcount (uint16_t Value)
{
	uint8_t BitsInValue = 0;
 
	while (Value)
	{
		BitsInValue  += (Value & 0x01);
		Value       >>= 1;
	}
 
	return BitsInValue;
}

Compare and contrast. Now I know that many people will disagree on my particular coding style (Whitesmiths all the way baby!) but what I want to illustrate here is a basic concept; that of making your code fun to read. We have big monitors now, so vertical space isn’t so much of an issue — especially so since most functions should be kept small, or at least internally divided into separate chunks. Most code is read far, far more than it is written, so for the sake of those around you please consider a consistent style, meaningful variable names, comments (where appropriate) and visually spacing out sections of code. I don’t know why people try to use C’s ability to ignore whitespace between some tokens to the maximum, since the space bar is the biggest key on your keyboard and thus the easiest to hit. Visual whitespace helps the brain take in a section of code and parse it internally to work out what’s going on, and hopefully make any errors more obvious.

The other thing I see a lot in the sample code I am sent often is a lack of modularisation – I get one gigantic C file, with an optional header file containing everything about a project in a single lump. It’s far better to organize your code into separate modular files, for both readability and searchability. While GNU Indent can fix the formatting of your code, no tool can convert a “big ball of mud” codebase into nice files automatically. I wrote a tutorial on this some years ago, and it really makes my day (and makes me more eager to help) when I see people following it.

One last thing that I’ve found interesting is that some people find it odd that I’ve never sat down and learned the order of operator precedence in C – I’ve no idea what priority the parser gives to one token over another in many cases. This is because I personally tend to adopt the philosophy of “most parenthesis”; when in doubt, add parenthesis around statements to make it painfully obvious what the order will be. I hate it when I see code like this:

uint8_t x = a && b || q == 2 * 3 & w;

Since I haven’t a clue what the code is trying to do. Actually, I’d wager that a good number of other people won’t know either, outside of the language experts. I call upon everyone to start using parenthesis like candy:

uint8_t x = (a && b) || (q == ((2 * 3) & w));

So that regardless of skill level, people can still plainly see what’s intended. Again, you read code more than you write it, so it pays to go for maximum clarity.

 

Since I’ve harped on about coding long enough, I suppose I’d better talk about what code I’ve actually written over the last few weeks. Again, my time has been limited, but I’ve managed to add in a Host Mode Audio Class driver to LUFA along with some Host mode Audio demos, a HID device Report viewer project, and a “Media Controller” HID device project for the control of media programs using a USB AVR. I held off making a host mode Audio Class driver for a long time due to the limited processing power available, but since LUFA will be running on much larger chips before too long I thought it best to future-proof the code somewhat. With the final release of AVR Studio 5 out, I need to start looking at ways of making LUFA a little more IDE friendly, so I’ve added an option to use a LUFA configuration header in user projects to set the compile time tokens, rather than having to specify them on the command line to the compiler. I’ve also been working with fellow AVRFreaks to get the SVN ready for integration into C++ projects, given that Atmel announced a new C++ extension for AVRStudio 5 this week.

One thing missing from AVRStudio 5 — well one of several things, I’m looking at your lack of Doxygen documentation support, VisualAssist! — is the inability to get live feedback on your coding before you compile. Users of the Visual Studio shell will probably be accustomed to seeing the fancy red-squiggle underlines in their managed code when they’ve made a boo-boo, which saves on development time since you don’t have to recompile and wait for the inevitable errors to crop up before fixing them and trying again. The good news is that there’s a new “Naggy” extension to add this ability into AVRStudio 5, which seems to work reasonably well in my tests. It’s under active development at the moment, so expect a few bugs no doubt.

 

I’ve got a few new boards in to play with when I get some time (this week or next) and review, so stay tuned for those. I love new hardware, but I really wish someone would send me a package of free time instead occasionally…

 

Comments: 6

Leave a reply »

 
 
 

Coding style is always a funny thing.
I so often had people who said, this K&R style is nice to read and a few years later, they couldn’t read their own code.

Looking to your code, I sometimes think you first learned Modula-II or Pascal, because this style is often seen there. 🙂

So my personal way with foreign C-Code is usually an indent run with my settings (in difference to you, I’m a 2-tabber)

Steffen

 

I learned LOGO first, then VB6, then C, Java and a little C++. No Pascal for me (yet!).

Cheers!
– Dean

 

Hi Dean,

Have you got some news about RFCOM implementation in LUFA?

Did you reaced a stable release?

I’m look forward to use it in my new project.

Regards

Mirko Ugolini

 

Mirko,

Bluetooth was on hold while I did my Atmel internship, the the AVR32 and (now) the USB XMEGA ports of LUFA. In two weeks I start coding for my final year project however, which will be a complete re-write of my Bluetooth stack to properly implement all the layers needed for Bluetooth operation, and should hopefully work across different physical transports, as well as (hopefully) different microprocessors.

I did manage to get basic RFCOMM communications up and running (PC initiated only) in the existing code before I switched directions, so in the meantime you can play with that.

– Dean

 

I’ve been looking at the LUFA stuff recently.. I was googling around trying to find the reason why do you put all of the includes for a module in the header and found this post. Why does a header that only has function prototypes in it include stdio.h? It seems all of the demo projects do this. It also makes no sense to me for functions that aren’t used outside of the object to be in a header in the first place either. I’m sure you have some reason for it and I’m not saying it’s bad practice or anything. I just couldn’t see why you would want or need to do that.

Personally, I don’t really mind about the layout of braces etc, that all be fixed with a formatter.

 

Mostly a bad habit; I like placing all the includes in the header since it makes the C code (actual implementation) a little shorter — the alternative is a mix of includes in both the C file (when needed by the C code) and the header file (when needed by the header code). On an embedded platform the additional preprocessing time is negligible, and header files don’t result in any extra code being generated in the final binary. On a large PC system where one include can result in many megabytes of headers being drawn in this might have a detriment on compile time (and namespace pollution) but I don’t feel it’s a deal breaker on an embedded platform.

C++ code is the obvious exception here; often including one heavily templated header can result in significantly longer compile times.

Cheers!
– Dean

 

Leave a Reply

 
(will not be published)
 
 
Comment
 
 

 

Vital Stats

  • 35 Years Old
  • Australian
  • Lover of embedded systems
  • Firmware engineer
  • Self-Proclaimed Geek

Latest Blog Posts

RSS