Tuesday, April 22, 2014

Free embedded programming course on edX

I've enrolled into the UT.6.01x Embedded Systems - Shape the World somewhere back in January/February but never got around to finishing all the exams, yet. It's a microcontroller development class focused on ARM architecture, using TI Stellaris LaunchPad as the platform.


It's been a mixed experience so far, let me explain why.

The good:
- using a widely available board, cheap, out-of-the-box. The class can theoretically be completed even without any hardware
- awesome teachers
- well-structured curricula with a relaxed and modern teaching style
- free! (unless you want the certificate)
- it touches on a lot of real-world topics, every theoretical experience is backed by practical examples
- goes through all the major peripherals without too much detail
- automatic grading system that's awesome in theory

The bad:
- the presentation is discontinuous, videos are interspersed with text, sometimes in a new chapter, sometimes in the same chapter. Makes it hard to follow and have for example an evening of watching videos and an evening of reading text.
- you are forced to use Keil as an IDE. I'm used to either Eclipse or the notepad-like Arduino IDE. It gets in the way with non-standard shortcuts, bugs and trial popups
- the grading plugin is limited, forcing you to use one implementation of the many possible ones. When you don't get it "right" it will fail with little explanation ("PCTL_R not properly set")
- even in the later labs there is still no provided library that can set up the ports for you, you have to do everything manually, all 15-20 registers
- the online quizzes have a result entry box that while accepts formulas it's really slow in parsing them (5~10 seconds on my i7)

It's at the same time fun, useful stuff, but very frustrating to use. I can't imagine designing a complete state machine (there's one exam where you design a traffic light) in Keil, I'll probably have to invest some time to redefine the shortcuts but more likely I'll have to do a proof-of-concept design in C that just uses stdio and compiles in a shell and then translate that into uC code.

The grading plugin takes some time getting used to:
- you have to make sure the project options (target, library, compiler) are properly set each time otherwise you will not understand what's going on
- the site generates a "public key" number that you paste into the grading window, after the evaluation the plugin generates a "private key" that you paste back into the web site
- if you paste a wrong key in the website the public code gets reset to a random value
- if you reset the simulator/board/cpu, the key entered into the plugin gets reset
- the grading plugin is not aware of state, you have to reset the board before grading to make sure it is running correctly
- combine the above three and you will probably spend at least 5-10 minutes to get your grade into the system because you copied the wrong code or you restarted the program
- you have to manually press the buttons or whatever you have on your board, which kind of makes sense, but it's annoying

I read the curricula in ~3 hours, on and off, the videos have captions so kudos to them.
A quiz takes me about 2-12 minutes to finish, since I already know most of the stuff, even without reading the courseware. There are 14 quizzes in total.
A lab takes me about 10-20 minutes to fully implement, including the hardware, then maybe another hour to debug why I'm not getting 100%. I've finished 8 labs out of the total 11, but the remaining three will take more time than the previous ones.

All-in-all the course could take around 10 hours to complete if you were free to choose the IDE and libraries of your choice. Probably 30 hours because of the quirks.
Just to mention, I haven't used the forums nor other channels of communication with the class (piazza), so all these issues had to be solved with no help. That's good practice, I guess.

My suggestion for a similar class would be:
- design a bootloader for the system that outputs data via some port (serial, usb over serial, gpio, etc)
- design a program that interfaces with said port and collects the data necessary for grading. It also resets the CPU prior to making a test run
- the program can be a browser plugin or it can have its own HTTP client to connect to the main grading system
- if the above is not possible (proxy issues for example), do not reset the "public key" each time a check is unsuccessful. Instead, keep it there for 5 tries and WARN the user when the key changes

With the changes above the student is free to use Energia/Arduino, Eclipse or whatever IDE/compiler combination he desires. If he knows how to properly set the PLL, pull-ups and ADC then he's anyway golden.

Useful non-spoiler notes:
- You cannot set interrupts on PORTA, PORTB, PORTE because the TexOS library uses those.
- for the interrupt lab I had to reset the board when it said to toggle the switch back, I could not get it to recognize the (positive-logic) switch change otherwise
- for the UART lab you do not require to add the " or ' characters to the string. I wish this information was visible somewhere
- I might write a library or a cheat-sheet that will be useful reference for future students, that should make it easy to set up the GPIO. It will be an Energia/Arduino pins.h port.

It's been a worthwhile experience so far, even though it reinforced my debugging skills rather than my embedded programming skills. Probably that's a more useful skill anyway.

Would be worth to mention that perhaps it would have been a good idea to introduce students to unit testing. Basically having mock services/peripherals that can simulate real ones, in order to verify that the algorithms work. So the students would write a file that compiles to an executable that's easily run on any OS.
This should be a staple in embedded development and I'm saddened it's not taught more but rather by trial&error. Unit testing and test-driven-development are good things that should be inherited from higher level languages.

Also, I might have judged Keil too harshly: it is the best embedded simulator environment hands-down. You can run code and see variables in near-realtime, probe analog and digital channels, inject your own data and add plugins (like the grading one).

Edit May 2017:
What I may consider constructive criticism might be consider red flags by others. So far, the edX course has been the only one to tackle affordable hardware and solid embedded practices. The other best bet is to join the hardware hacking programs, but those will teach you more about the result rather than the inner workings. The other alternative is to follow the full class from ECE4760, Bruce Land, but you will get no immediate gratification. 
In a perfect world, there would be alternatives, but only edX provides the bridge between the computer user and the rookie embedded programmer. I wish they they continue to provide that - in the future - without restrictions.