Gumstix and OpenEmbedded Workflow #1

The OpenEmbedded project is a combination of toolset and packages to be able to cross-compile Linux distributions for platforms other than the normal PC architectures. I’m using a Gumstix Overo Earth COM which is built with the Angstrom uCLinux distribution. Once you have the COM properly powered and running, you deal with the Angstrom distribution just like any other distribution. You log in to the console and start in your home user account. You have the standard Linux file directories and a package manager so to start customizing your install you go through the same motions as any other Linux distro. I didn’t get the Gumstix attachment to allow display connections so I’m running with just the console-only build of Angstrom, but you can build the Angstrom distro to run a GUI so it looks just like any other Linux distro on the PC.

Ok, so enough of the overview of the final product. I’m more interested in putting notes down on the workflow needed to add my own applications to the distro build. I’ll be using this hello-world example  from the Gumstix wiki as my example program. As my starting point I have already built an up-to-date Angstrom console-only image (omap3-console-image) and have loaded that onto my Earth COM. (I followed these instructions.) For OpenEmbedded I followed the Gumstix notes on downloading and setting up the OpenEmbedded toolchain. I’ll point out here that the Gumstix notes seem a little out-of-date as I have found the Overo recipes directly inside the OpenEmbedded recipes folder for the TI OMAP arch recipes. The notes say the Gumstix-specific recipes are in their own directories outside the OpenEmbedded directory. Looks like they changed their minds sometime after those instructions were posted.

So the first step toward building my hello-world example is to cd into my top-level directory for my Overo build (I called it overo-oe) and get the sources:

git clone git:// user.collection

I now have a new directory called user.collection in my top-level directory.  Inside the new user.collection directory I have these subdirectories:

  1. extras – Extra stuff… (?)
  2. recipes – BitBake recipes for each hello-world example (there are six of them).

Since I now have a user directory I need to make sure that the BitBake tool can find it. From the Gumstix/OpenEmbedded setup steps earlier, I know that the environment variable USERBRANCH denotes where the user files are. Just like how the variable OEBRANCH denotes where the OpenEmbedded core files are. I think USERBRANCH already came pre-set but I’ll just make sure by checking my environment variables:

spade78@ubuntu:~/Desktop/overo-oe/user.collection$ env | grep "\<USERBRANCH"

And I get the result:


Next I need to find the name of the recipe I want to build. According to the OpenEmbedded user manual, BitBake recipe files follow the convention:

Inside the recipes folder of the hello-world example we cloned, there’s a myhelloworld folder and inside that is this file:

So on the console, I will invoke BitBake to build the myhelloworld recipe:

spade78@ubuntu:~/Desktop/overo-oe/user.collection$ bitbake myhelloworld

And after some wait the recipe output appears in OVEROTOP/tmp/deploy/glibc/ipk directory:

spade78@ubuntu:~/Desktop/overo-oe/tmp/deploy/glibc/ipk$ find | grep myhelloworld

But wait, wasn’t my platform target an Overo (uses an ARM Cortex A8 by the way) which is also a sub directory in this folder? Yeah, not sure about that quite yet. There’s probably a config step I must’ve missed. Had the armv7a been my target, I then would’ve installed the package by copying the package files to my COM and invoking the package manager on the COM to install it. But I haven’t tried that part yet as I want to create a more sophisticated program to build and run on my COM.

That’s enough for now. I now have a clear path between creating source files, where to put them (user.collections/<MyProjectName>), making sure BitBake can find them (via the USERBRANCH environment variable), and where the output is put (the deploy directory) when the build is complete.

Yes, I’m still alive…

A lot has happened for me since my last post close to a year ago. I’m now living in San Diego, California and have changed jobs. With the new year will come new changes, including this blog. Though what form it’ll take I’m not sure quite yet but I do know that what I’m doing now just isn’t working out. Turns out that writing a blog is more work than I anticipated… duh!

First Cocoa milestone achieved!

So today, I hit a milestone in my efforts to learn Cocoa: I added my first Cocoa widget to a program! And an NSTableView at that. Oh yeah, baby!

OK, not exactly an earth-shattering moment in the history of the world but for me this does signify a sort of wall being broken down that I always go through when learning a new language these days. I’ve figured out that when I’m looking at a new programming language for the first time, my first instinct is to compare it to a C or C++ program which is what I’m most familiar with. Sometimes this works well, like Java. Other times it works poorly, like Haskell. Objective C and the Cocoa framework land in the latter category. For one thing Objective-C looks nothing like what I normally encounter with the C language, especially message passing. And the first thing I had to figure out was where the heck was main()?! Another thing that really got me was the workflow of the XCode/Interface Builder environments and its focus on separation of concerns between the implementation logic (XCode) and presentation (Interface Builder) of an application. So far, I’ve boiled down the work flow into these steps:

  1. Identify the Cocoa UI classes you want to work with and go through the Apple documentation to learn the core concepts behind each class.
  2. Identify how each object you want to create will interact with each other in the app.
  3. Lay out the objects in XCode, just focusing on declaring objects, outlets, and actions.
  4. Create the UI layout in Interface Builder. Make your connections.
  5. Go back to XCode and implement the app logic.

I feel these steps for working in XCode and Interface Builder are the most important thing I’ve learned thus far in my exploration of Cocoa. It takes the enormity of the Cocoa framework and chops them up into smaller chunks that a newbie like me can tackle one at a time without getting overwhelmed by the details. The lesson about the separation of concerns is also something that I will be paying much more attention to in the future in all the programming that I do from now on.

Simplicity Through Complexity

Recently I got my Dad a Magic Trackpad for his 2005-vintage iMac to go along with an upgrade to Snow Leopard. When I think about it, the trackpad is quite an amazing piece of technology. It looks simple on the outside but underneath I can imagine the effort expended by the engineers to figure out and tune the hardware and software algorithms to detect the various types of taps, touches, and swipes that a user can perform to make a computer do something. Compare this with your standard keyboard and mouse combo which is just a bunch of switches and a set of rollers. Explaining the usage of the trackpad to my Dad was a predictable affair as his tolerance for complexity was pretty low to begin with and I hit it easily as I was trying to explain how it worked compared with the standard mouse. But his interest quickly came back when we got to the Chinese input feature which was the reason why he asked for it in the first place.

For those not familiar, up till now the standard way to input Chinese characters on a computer was via keyboard. This can be a tedious affair as it is basically an adaptation of an input device optimized for Western European character sets to fit in the Chinese character system. There are a couple of variations of the system out there and I’m no expert, but the common trait they share is to start with the user inputting a basic subset of symbols which gives the system an idea of what character you have in mind. You keep inputting these basic symbols and the system will eventually give you a range of suggestions about the word it thinks you want to type and you choose the final word that you want. Essentially it is a divide and conquer method and I suspect it can be very useful with practice as it’s been around for a long time and I’ve never heard of any comparable alternatives. Alas, for my Dad, when it comes to trying to compose an email to his brothers back in Taiwan via email, this keyboard system is still one big pain in the butt for him. I think this is one of the chief reasons why my Dad never did get into computers and the internet in a big way because it’s hard to maintain an interest in a communication medium when its so hard to use it for communication. Hopefully this will change with the trackpad. I haven’t asked him about it recently but initial signs were good. Once my Dad understood the trackpad’s semantics of tracing out the character and then tapping on the appropriate character to output to the page, he was belting out characters on par with the best he could do with the keyboard input. I suspect with further practice he’ll only get faster and with much less frustration than with the keyboard input which means he’ll keep working at it and won’t abandon it.

This anecdote got me thinking about a device that is inherently complex (the trackpad) making some complicated task (computer input of Chinese characters) much simpler because it’s method of operation (touch) maps much better to the original method that the user would be familiar with. If I were to substitute a stylus, pencil, pen, or brush in place of the trackpad then my Dad wouldn’t have to shift his operational knowledge about writing chinese characters one bit. No matter what input method, he still uses the same knowledge of strokes and ordering to construct the symbols that he’s known all his life to communicate naturally with friends and family. Contrast this with an inherently simple device (the keyboard) that makes the task of writing Chinese characters much more complicated because its mode of operation fails to map to the original method. The take-away for me as a systems designer is the observation that the simplest device in the world can be horribly complicated to use if its made for an environment that it is fundamentally unsuited for. Though the keyboard was adapted to fit in the Chinese character environment, the cost of going through the hassle associated with the keyboard systems was too great for someone like my Dad and so failed as a useful device for him.