I no longer recommend Remotesoft
I can no longer recommend using Remotesoft's products. In September, I sent them a detailed description of a problem I had with their product, and I have yet to hear anything at all from them about it.
They have a good product, but it is effectively completely unsupported.
Update: End the tyranny of buggy obfuscation products and poor technical support. Use Obfuscar instead.
Atmel AVR on OSX and the Build Button
I've been playing with microcontrollers lately.
I first picked up the Microchip PIC microcontrollers several years back, but I didn't get further than designing a few circuits and writing some code. They had just started with their line of flash-based chips, but most resources out there were about their eprom / eeprom chips, and I was turned off by the prices of their development tools and programmers.
The next time I looked to microcontrollers, I discovered the Atmel AVR chips. All of Atmel's diverse line of chips seem to be flash based, the programmers are dirt cheap (Atmel appears to prefer in-circuit programming, and you can build your own programmer with parts you already have sitting around), and they support a fully open source gcc-based toolchain. That's pretty hard to beat. It means there is a lot of code out there, example circuits, and an active online development community.
At the time, I ordered a basic Olimex development board, their AVR-28C, I think from Spark Fun. It came with an ATmega8 chip, an 8Mhz crystal, and assorted bits necessary for it to communicate via RS-232. I also ordered from them a very basic serial programmer (it was only a couple dollars). I had intended to build a little clock with it, but never got around to finishing it.
The Build Button
Last year, I changed the development processes in my department, and we now have an automated unit testing and a continuous integration process (rebuilds and runs tests when commits are made). A few months back, I grew tired of QA asking for fresh builds of the latest code for testing, so I automated the creation of QA builds too. My first version was a push button wired to a serial port. For the next iteration, I rewired one of those Easy Buttons from Staples...It now has an RS-232 port on the side, and green and yellow LEDs. On the host system, there's a basic service that lights the green LED (indicating that it's running and waiting to be pushed), and waits for pin change events from the serial port. When the button is pressed, the service runs the build scripts to clean, compile, unit test, obfuscate, package and deploy the installer for the system to a repository for QA. During the build process, the green LED is turned off, and the yellow one blinks. When the process is complete (sucessful or otherise), the LED goes back to green. Now QA can make their own builds for testing.
But I'm not done...There are two things I want to change:
- There's no feedback regarding the status of the source tree. If the build is broken, and one initiates a QA build, the build silently fails and the light goes back to green. Currently, QA has to notice that the build has failed, request that it be fixed, and then can initiate another build. I'd like the Build Button to indicate the status of the source tree as determined by asking the continuous integration server.
- It's tethered to a development system in my office via a RS-232 cable. This means that anyone who wants a build has to come into my office to start one. It's not a real problem, but an interesting one to solve.
My new goal is to have a number (well, only one is planned for now) of lamps, positioned around the office, that will reflect the current build state (e.g., green if the build is good, red if someone has broken the build, yellow when a QA build is in progress), and any of the lamps can be used to initiate a new QA build. Imagine those [tap lights] you see advertised on late night television, but where the color of the light is meaningful (and tapping the light does something). Something like the Ambient Orb, but functional.
To this end, I have purchased a blindingly bright RGB LED from Hong Kong (it's a monolithic LED containing three chips, each color drawing ~350mA). I've connected it to my ATmega8 microcontroller, and wrote a simple program so I can make any 24bit RGB color using the 3 PWM pins on the microcontroller. So far, it just fades from color to color, but it's extremely bright, and I'm nowhere near done.
Atmel AVR Development on OSX
I no longer have a serial port. My Macbook prefers USB instead, and I don't think the bit fiddling necessary to operate my old serial programmer would work with a USB-to-Serial converter (which seems distasteful to me anyway, somehow). I heard that Atmel's AVRISP mkII USB programmer was supported on OSX (via avrdude), an it is supported...mostly. I got mine from Digi-Key, for ~$30.
Installing the GNU Tool Chain for the AVR was pretty easy. I installed libusb via fink (so I wouldn't have to deal with its details), then followed the avr-libc installation instructions to build building the rest of it (the GNU Binutils for the AVR, GCC for the AVR target, AVR-libc itself, and avrdude) from source. I chose not to install the rest of the toolchain via fink, so I could use the lastest versions of everything (this turned out useful). On my system, to keep it nice and isolated, I've made sure that all of it (except libusb) lives under $HOME/local/avr (the details of using a prefix like this are in the avr-libc installation instructions).
After I got it all built, I connected the programmer to my laptop. Growl notified me that it connected, and the little light on the programmer itself went red (indicating it was idle). I plugged the programmer into my circuit, and the light went green (indicating that it was connected and happy).
I compiled my code to a .hex file, and tried to upload it to my microcontroller via avrdude:
avrdude -p m8 -P usb -c avrisp2 -D -U flash:w:code.hex:i
This tells it that I'm using an ATmega8 chip, via the USB port, with the AVRISP mkII controller, and that it should upload the code.hex file. It initialized, the green communication light on the programmer blinked a little, and then it sat there. I couldn't figure out what I did wrong. I had read a bit about the programmer being really slow with avrdude on OSX, and most of the chatter online describe the problem being related to the serial clock for the programmer being set to an absurdly high value, and that the solution was to connect to the programmer via terminal mode, and instruct it to change the serial clock to a lower value. I connected via terminal mode, and issued the command sck 5...turns out it was previously something ~953us.
When I tried to upload again, same problem...to be more specific, it initialized, opened the microcontroller, and halted. The last message displayed before avrdude halted (when avrdude was run with the option for extra verbose output) was as follows:
avrdude: usbdev_open(): Found AVRISP mkII, serno: XXXXX
Where XXXXX is the serial number printed on the bottom of my programmer...this means it was communicating with the programmer, but nothing else was happening. Both lights on the programmer remained lit green, and the communication LED would blink out every few secs (which to me meant it was doing something). I could kill the process by disconnecting the programmer from the USB port.
After a great deal of trial and error (installing and removing prebuilt versions from others, poking and prodding at libusb, etc...useless stuff), I got up for a bit, and when I returned, I saw a series of messages that indicated that it correctly programmed the chip! It turns out that it wasn't halted, just extremely slow (read: ~10 mins to program the chip). Looking over the messages, I saw the next thing printed following the usbdev_open message above, was a message as follows:
avrdude: stk500v2_getsync(): error communicating with programmer: (0)
After further research in the avrdude-dev mailing list, it turns out that there's a function, stk500v2_getsync, that fails in an unusual manner when run via OSX, over USB, against the AVRISP mkII. Essentially, it tries to send a command to the programmer, and fails to receive valid data. The method that retrieves the response from the command is apparently expected to return either a number of bytes greater than 0, or to return an error code less than zero. In this case, the receive returns zero, causing it to retry 33 times! Why 33? Sounds pretty arbitrary to me...but in any case, each retry takes 10-20 secs to fail. After the 33rd failure, it returns 0, and avrdude moves on.
Considering that the programming was sucessful, even when the stk500v2_getsync function was doing nothing but wasting time, I added return 0; as the first line of stk500v2_getsync. Aside from a warning about unreachable code, it now runs beautifully, and I can program my chips with no trouble or delays.
Bits and Implementation
I've made a lot of orders to Digi-Key, Mouser, Spark Fun, and All-Spec (see below) in the last few weeks, as the project has grown.
The plan is to use an FTDI USB-to-serial chip ([FT232RL], to be specific), connected to one of those super cool XBee Zigbee modules from Maxstream (ordered from Mouser) to build a USB-Zigbee modem, which will be used to control the lamps. Each lamp will have one of the XBee modules, connected to the microcontroller, which will drive the LEDs and handle the input pushbutton.
I had originally planned to use the open source AVR USB stuff (it's a software-based USB implementation), but after staring at arduino's USB circuitry, and seeing an article describing a 'trick' that does pretty much the same thing, I think it's better to hand off the USB functionality to a dedicated chip. the USB-Zigbee modem won't need a microcontroller at all...it's pretty much a two-chip module. The lamp circuitry is similarly simple, basically just the XBee module, and a microcontroller brain.
At first, I used Inkscape to draw my schematics. They came out really pretty, but getting everything lined up was problematic, I had to draw each part at least onc, and so it didn't scale very well.
Next, I tried CadSoft's freeware Eagle software for schematic capture and layout. Its schematics aren't as as pretty as the ones from Inkscape (and they aren't SVG), but I found Eagle on Windows to be easy and pleasant to use. Unfortunately, its installer for OSX required root privileges to install. I don't very much trust .pkg installers on OSX, particularly when they talk about personalized licensing and registration (it always sounds to me like they want to hide things from me).
Rather than install Eagle on my OSX system, I have been working with gschem (also installed via fink, see the geda-bundle), for schematic capture. gschem isn't as pleasant as Eagle, but it's open source, and easy enough to use once you figure out how it works.
Once I get something working, I plan to publish the schematics for everything, as well as pics and source code.
Plug
From All-Spec, I ordered the Weller WES51 soldering station. Until now, I've always used junky little soldering irons, of the type sold at radio shack. I figured I'd be doing a lot of soldering in the near future, so an upgrade might be prudent. It's temperature controlled, ESD-safe, and I cannot recommend it enough. Also, All-Spec is located in Wilmington, so I received my order in one business day, even with the cheapest, slowest shipping...it was a nice suprise.
Disclaimer: I have no special relationship with any of these vendors, I just buy things from them...I don't get free stuff or anything.
Definitely an Edge Case
It seems that not even Remotesoft's .NET Obfuscator is immune from bugs caused by edge cases. Seems that they have some trouble with generic classes overloaded with covariant returns.
I managed to simplify the problem I'm running into...here's my example:
namespace TestTemplate
{
class ClassX { }
class ClassA<ObjectType>
where ObjectType : class
{
public virtual ObjectType PrintAndReturn( )
{
Console.WriteLine( "This should never be called" );
return null;
}
}
class ClassB : ClassA<ClassX>
{
public override ClassX PrintAndReturn( )
{
Console.WriteLine( "This _should_ be called" );
return null;
}
}
class Program
{
static void Main( string[] args )
{
ClassB b = new ClassB( );
b.PrintAndReturn( );
}
}
}
In the above case, it should (and does) print "This should be called". After obfuscating the resulting assembly, using the 2.0 version of the obfuscator, it prints "This should never be called". It seems that following obfuscation, ClassB.PrintAndReturn is given a different name than ClassA.PrintAndReturn, so the overloading doesn't work and the base class method is called instead. Here's the obfuscator's log:
.module TestTemplate
.namespace TestTemplate
{
.class private ClassX => A.A
{
.method public void .ctor()
}
.class private ClassA`1 => A.a
{
.method public virtual !0 PrintAndReturn() => A
.method public void .ctor()
}
.class private ClassB => B.A
{
.method public virtual class TestTemplate.ClassX PrintAndReturn() => a
.method public void .ctor()
}
.class private Program => a.A
{
.method private static void Main(string[] args) => A
.method public void .ctor()
}
}
I've sent them some email about the problem, and in the meantime, I've set it to not obfuscate methods that are overloaded this way (I have explicitly marked the methods by name).
Will post an update when I get a response.
Update: I no longer recommend using Remotesoft's products.
Update 2: End the tyranny of buggy obfuscation products and poor technical support. Use Obfuscar instead.
No More Typo
In case you had not noticed, I have abandoned Typo...It got a little too thick for my taste, and they had no plans to cut it down any time soon. Anyway, Rails is simple enough to whip up something similar pretty quickly.
So, it is not nearly as functional as Typo, but it is a lot leaner, and it works. It will also be something fun to play with.
There isn't a feed, comments support (mail me at drcforbin@gmail.com if you have any), search or any of that stuff right now.
eMusic Rocks
No pun intended...well, maybe a little. I joined eMusic last week, and I've already exhausted my trial downloads, upgraded to the premium subscription, and exhausted the downloads it provides for the month.
And I still have 30+ albums in my 'save for later' list.
eMusic isn't for everyone. On their forums, there are two kinds of people...junkies like me, who don't have enough downloads for everything they want, and people who hate it because they can't find anything to download. The people who hate eMusic really hate eMusic. They always seem to complain of being tricked, duped, swindled, etc.
I feel sorry for these people. eMusic has a lot of music, something for every taste, I think. That is, unless your taste is big-label mainstream music. eMusic even offers a free 14-day trial. They give you 25 free downloads during that period, so you can decide whether you like the service. If you really can't find anything you like, then cancel before the 14 days is over. I can only imagine that these people are simply unwilling to try something new.
My musical taste is pretty varied, and I've never really gotten into the big-name music. I found that many of the artists I listen to are on eMusic, and I'm finding a lot of new stuff. Since joining eMusic, I have listened to dozens of albums from artists I'd previously never heard of, and found many of them to be pretty good.
Another plus is that eMusic uses no DRM. I refuse to purchase music from iTunes, Microsoft, Napster, etc. I will not purchase music that I am not free to listen to on the device of my choosing, at the time of my choosing, or as often as I choose. Until I signed up for eMusic, I was buying CDs and ripping them myself. eMusic's tracks are high-quality MP3s. That's tough to beat.
I would rather buy music than download it illegally. Not because of the RIAA's threats and lawsuits (which make me want to download illegally, out of spite), but because I think the artists should get paid for their work. eMusic lets me buy my music, and listen to it however I like.
On a related note, I think that it is pointless to boycott music and music downloads in an attempt to send a message to the RIAA, or to send a message about DRM. There are already a lot of people who don't buy music at all, and the boycotters will just be counted among them. Much more effective is to simply buy non-DRM music from non-RIAA labels...show the labels and artists that money can be made without resorting to DRM. It's much more effective to vote with your money then by withholding it.
And yes, you can browse emusic without signing up, just use a deeper link.