Newbie Mistake

I’m heartbroken. I’ve just finished watching the last episodes of Stargate SG1 (plus the two recently released movies) and I’m at a loss. Screw an “edgier, younger” Stargate spinoff, I just want the show I’ve been watching for 10 years to continue.

I’m actually a little bit peeved on another count, after receiving my “USB 2.0” hub off eBay. Admittedly it was cheap, but I refuse to pay $30 in stores for what amounts to a single chip and a few sockets. The hub was supposed to replace an old similarly cheap USB hub I’ve been using, which was 1.1 compatible only (despite a prominent “USB 2.0!” sticker) – no good for high speed devices. You can see where this is going – the new hub is also labelled as “USB 2.0” but has an ancient 1.1 controller chip. The only interesting part of the exercise is speculating what the controller chip is, as USBVIEW reports that is has an Atmel VID. Damn shifty scamming Chinese.

I thought it would be useful here to give a visual comparison between the two big players in the USB162 market, AVROpendous and the Teensy. Here are the three boards next to one another:

From left: the Original AVROpendous board, the new AVROpendous Mini, and the Teensy. All nice boards – I use the AVROpendous quite a lot, and last week I spent the day teaching my friend C and AVRs using the easy-to-use Teensy board. He’s now a happy camper (and hopefully converted from the TI MSP430 we used at University) and I’m happy that the Teensy has given him an easy way to experiment.

Actually, the last week has been quite productive. This is possibly the first time in my life where the demand for me to work exceeds the time I am physically able to work in, excluding schooling. I’ve found myself working on several projects from several companies, and I’ve got a few future contract proposals built up in my inbox. It’s a nice warm fuzzy feeling to work and get paid — I’m sure glad that I didn’t manage to get a job in retail over the summer break.

One such project I worked on was late last week, as a rush-job to correct some bugs in the LUFA firmware. Easily the most profitable thing I’ve ever done (big companies pay big money to get things done now) it was actually embarrassing to find the source of one of the bugs, which has sat in the Mass Storage demo since I wrote it a good year or more ago. A completely rookie mistake, here’s the offending line in all its glory:

CommandBlock.DataTransferLength -= (TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);

During debugging, I discovered that Linux gave I/O errors when the number of sectors (blocks) exceeded 32. That baffled me, as the data actually written to the disk was fine, confirmed good with MD5 hash compares. Looking at the code, the answer hit me like a brick: integer promotion error. In the above code, CommandBlock.DataTransferLength is a 32-bit unsigned integer, TotalBlocks is an unsigned 16-bit integer and VIRTUAL_MEMORY_BLOCK_SIZE is an untyped macro constant of 512, the number of bytes in a block.

Any idiot can see where this is going, and I’m ashamed to have overlooked it myself for so long – it’s interesting to note that Windows doesn’t give any feedback about such a grievous error when the returned number of unprocessed bytes is non-zero (indicating an error). In C, macros are assumed to be of type int unless qualified with a cast. That means that the compiler was performing 16-bit multiply on the operands before promoting the result to an unsigned 32-bit integer for the final subtraction. Having the TotalBlocks value exceed 32 causes the multiply to overflow the 16-bits, and results in a corrupted result. Talk about a dumb, rookie mistake.

As an aside, it’s interesting for one to know how the Mass Storage class works in USB devices, since a lot of people mail me and write questions on the support list regarding it. The Mass Storage USB class is actually just a thin transport wrapper, which wraps up standard SCSI commands to and from the device. This allows for a very lightweight specification, as all the heavy lifting is performed by the tried-and-tested SCSI standard. That’s why when a USB flash disk is inserted into a Linux machine, one can observe the SCSI drivers being invoked in the kernel log, as the existing SCSI layers can be used without modification on the USB disk, with the Mass Storage Class drivers perfoming the USB transport only.

To that end, the AVR itself is entirely unaware of the data being written to or read from the disk, in the Mass Storage demo. The SCSI layer includes block read and writes of the storage medium, which is duly performed, but at no point is the AVR involved in interpreting the actual bytes stored on the disk. That’s why you can happily format the Mass Storage demo to any file system you like, and so long as the host supports it the demo will work just fine. It’s also why the Mass Storage Host demo can only read and write raw blocks rather than files, as there is no filesystem driver in the demos.

By adding a filesystem driver to either demo, one can read and write files stored in the filesystem on the disk instead of disk data blocks. That will lock you into using one specific disk filesystem however, as both the host and the AVR will need to understand what is stored on the disk.

 

Comments: 1

Leave a reply »

 
 
 

I doesn’t matter how many years of experience you’ve got.. sometimes you do stupid mistakes.. Like this other day I had to test a FPGA date version ( a long hex number ) in a bootloader and in a FPGA driver in Linux. Did the exactly right thing in the bootloader.. But managed to type the comparison value in dec rather than in hex in the Linux driver.. damn 0x.. my brain didn’t really pick up on that although it’s so obvious it’s ridiculous… Sometimes your brain just cheats you. That’s why one needs to accept that we are just human and that embracing rigorous testing and a large user community is the way to go. 🙂
The code passed initial testing because I did not try combinations of versions…

 

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