8051 Microcontroller Programming

8-bit MCUs continue to be a popular microcontroller for embedded systems because they are fairly simple to understand and write code for. I have been pursuing embedded programming as a hobby for several years now and have found the obstacles to understanding to be pretty difficult to overcome. In the course of the past year or so, though, I haver begun taking steps to figure things out. My first step was to actually purchase a microcontroller development board along with some books. I ended up purchasing a dev board from Silicon Laboratories. The actual development kit I bought is the C8051F020DK. It provides everything you need to get started with Microcontroller development. What it doesn’t include though is a quick way for programmers to learn electronics. This continues to be my biggest challenge. Here, however, is what I’ve learned so far for those of you who are Windows programmers but would like to venture into the embedded world.

Interrupts Are Like Events
As programmers we are used to responding to events constantly. An event handler on a button or a list control that has just been changed gets triggered when a user does some function such as clicking the button or changing the selection in a list.

Things are similar in embedded programming. While embedded systems don’t have the layer upon layer of abstraction we’re used to, they do provide the tools you need to be able to do what is necessary in the embedded world. Interrupts are a special abstraction that get triggered based on a timeout or a button (a physical button on the dev board for example). Timers are a special peripheral of these chips that will count up and then trigger an interrupt when the number overflows. When that happens, we are able to figure out how much time actually elapsed and create more meaningful delays in order to achieve what we want.

While flashing an LED (Light Emitting Diode) is not terribly exciting, it is something that can be handled very easily in an embedded system using interrupts. You simply set the timer running and attach an interrupt function (similar to a callback, really) and when the timer overflows, our function gets called. It is at that point when the LED gets toggled on or off to make it flash.

Ports Turn Stuff On and Off
On the development board, I have 64 port pins that I can manage in code that turn things on and off. The C code to do so is very simple. First, we have to define the memory location of the pin we’re interested in. Bascially on my system there are 8 ports with 8 pins each. Only the lower numbered ports 0-3 are bit addressable which means that they can be turned on and off independently of the rest of the pins on the given port. Byte addressable only ports require that you maintain state and use bit shifting and/or masking to make the changes that you need.

Hooking It Up
I’ve hooked up my board to an “Electronics Learning Lab” from Radio Shack. You really don’t need to get one of those, but I had one and decided to use it. My first project was connecting it to a 7-segment display on the learning lab. For each of the LEDs in the 7 segment display, I connected a port pin from port 1. Below are the pinouts for the peripheral connections. I used Port 1, which is connected to pins C4, B4, A4, C3, B3, A3, C2, and B2. See the frame below for the complete pinout.

You can see the way the seven segment display is connected in the following illustration.

From Vast Resources to Few
Being a Windows programmer makes learning embedded systems a bit of a challenge. By specification, the 8051 only allows you a maximum of 64KB of program code. If your program is bigger than that, you are either out of luck or you have to use some embedded guru’s black magic that I am, clearly, not yet familiar with. This is a far cry from the amount of programming (and data for that matter) memory space we have at our disposal as Windows programmers.

As strange as it may seem, I really like the challenges that come with learning embedded systems. I think it makes you more likely to consider optimization in other types of programming which can be a good thing. As soon as I think of a killer project to create, I will prototype it, market it and sell the idea to highest bidder. Until then, I will just continue to fiddle around with LEDs and, well, LEDs. Does anybody have some ideas for a killer widget that is primarily LED related?

A Pluggable Framework

I’ve been wanting to blog about this for a while, but haven’t as it seems it might be time consuming to explain my thoughts. I’m going to dip into it a bit here and then follow up as I have time.

The company I work for provides data analysis for retail stores (read grocery) found throughout the country. The companies we work for are fairly small which is to say chains like Albertsons, King Soopers, Safeway, etc. are much larger than what we handle. We would like to see that change and I think it will in the future, however, the largest chain we work with currently has fewer than 30 stores total.

Part of being able to use the same data analysis tools for all of these different companies has meant being able to take transaction data (data from scans at the cash register stored in log files) and convert it to a format that can be easily loaded into the database schema we use when running our analysis tools.

I was tasked with writing the extraction processes for each of the different Point of Sale (POS) systems that we support and converting that data from raw log files to the format (XML) that can be loaded into our database schema.

As you might have guessed from the title of this post, I use a pluggable framework that allows me to select which ‘extractor’ to use at run time based upon the type of POS system the store is using. Keep in mind that we need to support numerous POS systems since these smaller companies all use a broader range of systems than what you might find at the large corporate site I mentioned earlier. Also, though it doesn’t happen too much, there may even be cases where within a single company or single site (store), there might be a mix of POS systems in use. That’s why it’s important to be able to accommodate multiple types of POS systems.

I am using reflection for my pluggable framework. I’ll get to the details of that in a minute, but first let me talk about how to organize pluggable components.

Namespace Organization
In order to adhere to good programming practices, I created an abstract base class that contains some common functionality that all transaction log extraction modules will benefit from. I placed that class in it’s own assembly, though, which allows me to create new extractor any time I need to without having to have a reference to the other modules. Organized into namespaces, it looks like this:


CompanyName.ApplicationName.Extractors
CompanyName.ApplicationName.Extractors.SuperPOS
CompanyName.ApplicationName.Extractors.HyperPOS
CompanyName.ApplicationName.Extractors.WonderPOS

Each of these are in their own projects and therefore each of them create their own assembly. Each of the specific extractors has a reference to the CompanyName.ApplicationName.Extractor namespace and inherit from a class in there called “ExtractorBase”. Keep in mind that all of my namespaces here are bogus. In the real application they have their actual names, but I didn’t really want to give away anything here about the real POS systems we support.

The reason I’ve done things this way is because I want to be able to create new projects in the future that adhere to the interface (abstract class) without requiring me to recompile anything but the new assembly. So, say in the future I decided to add a new extractor with the namespace:

CompanyName.ApplicationName.Extractors.CoolPOS

I can simply create a new project that has a reference to CompanyName.ApplicationName.Extractors, inherit from CompanyName.ApplicationName.Extractors.ExtractorBase and implement the interface specified. Then, when I’ve compiled the assembly, I can simply move CompanyName.ApplicationName.Extractors.CoolPOS.dll into my extractors directory and then the existing system will be able to simply load the new assembly using reflection based on some parameters I will add to a configuration XML file.

Reflections Of the Way Life Used to Be
Do you remember life before we had reflection? RTTI (RunTime Type Identification) was the closest I recall in C++. These days I can’t imagine how I could have done anything like this so easily without it. In the code that actually calls each extractor, I use reflection to find and invoke the method. As part of my interface (abstract class), I’ve provided a single entry point that has multiple implementations (e.g. polymorphism). The method name is called Execute and it provides multiple signatures in case some parameters are not needed or desired. The method invocation code is able to determine based on the number of parameters passed in which Execute method should be called.

The method invoker uses strings that specify the full namespace of the object that is currently needed and able to load the proper assembly. It then calls the execute method on the extractor module found in that assembly. The code looks something like this:
[csharp]
string extractorAssemblyName =
configManager.GetValue( “ApplicationPath” ) +
“CompanyName.ApplicationName.Extractors.” +
this.extractorName + “.dll”;

string extractorObjectName =
“CompanyName.ApplicationName.Extractors.” +
this.extractorName + “.” +
this.extractorClassName;

DynamicMethodInvoker invoker = new DynamicMethodInvoker(
extractorAssemblyName,
extractorObjectName,
“Execute” );
[/csharp]
The strings extractorName and extractorClassName were populated from an XML configuration file. In the case of my new POS system I referred to above as CompanyName.ApplicationName.Extractors.CoolPOS, the string extractorAssemblyName would now contain “C:\path_to_application\CompanyName.ApplicationName.Extractors.CoolPOS.dll” and extractorObjectName would now contain “CompanyName.ApplicationName.Extractors.CoolPOS.CoolPOSExtractor” (which is the actual name of the class we are going to use for this POS).

All I need to do at this point is pass in the parameters that the Execute() method is expecting and call Invoke() like this:
[csharp]
invoker.AddParameter( param1 );
invoker.AddParameter( param2 );
invoker.AddParameter( param3 );
invoker.Invoke();
[/csharp]
And my Execute method for the new extractor, CompanyName.ApplicationName.Extractors.CoolPOS is now running without having to recompile my entire calling application.

At this point, I can’t remember where I got the DynamicMethodInvoker class from, but if you are interested in taking a look at it and using it, just let me know and I’ll forward it on to you (I believe I got it off of MSDN, but heck if I can find a reference to it now). DynamicMethodInvoker provides a simple interface for calling methods and examining reflected types and methods. It makes things a little bit simpler to implement.

Conclusion
I haven’t yet done any profiling to see if things would be much faster if I didn’t use reflection (e.g. just create a hard coded class hierarchy), however, the system does seem to work well and fast enough to accomplish what we need. I had thought about using a provider model, but I realized later that the provider model is really intended for creating an abstraction in case you need to change the underlying system at a later date. A data provider for instance provides access to different databases based upon a specific implementation of a provider interface. If you ever needed to switch from a SQL Server database to a MySQL database, for example, you would simply need to implement the provider interface for the MySQL database and the specify in a config file that you want to use that provider instead.

The approach I’ve outlined here works similarly, however, in contrast to the provider model this pluggable framework is intended to swap out the current extractor in use during a single session where the data provider model is simply a design choice you make in order to support a different underlying data store should you need to in the future.

Well, that’s it for now. I will revisit this again as more comes to me. Meanwhile, good luck and have fun making pluggable frameworks with reflection.