Friday, December 21, 2012

C Is Your Friend

The C Bible

I read a post today about Why C++ Is Not Back. I've been thinking a lot lately about the various languages that exist and why people hate on C and C++ and insist they aren't relevant (I'm not saying the above post is guilty of that it just got me thinking about it). I want more software developers to get into firmware development. I'm not talking Raspberry Pi or even Arduino. I'm talking about buying a $2 PIC or AVR microcontroller and writing C code to make it do cool stuff. But when I talk to people it's always the same thing, "I have to write in C? Ouch."

What Are You Afraid Of?

Most software developers I know are smart people who are good at solving complex problems. Why are you so afraid of C? Is it the memory management? Is it the pointers? People, these are not hard things to understand. Certainly no harder than dependency injection or inversion of control. Are pointers harder to grasp than writing multi-threaded code? In my office my .NET books stack well over 2 feet high. 840 pages of LINQ. 1000 pages of WPF. 680 pages of C# Object Basics. Almost another thousand pages of ASP.NET MVC. On and on. And then there is my C book. The only book I reference for C questions. 274 pages of basically all you need to know about C.

Get Ready For A Change

So what's my point? C is really not that bad. I'm not suggesting you write everything in it. Not at all. I love C#, Ruby, etc. They're great. I do think, however, that there is going to be a growing push for software developers to contribute more to hardware development as the Internet of Things takes off and every major corporation tries to carve out it's share of the loot. Now I know what you may be thinking. "You're right man. That's why I bought me a Raspberry Pi and I hack on that." While the Raspberry Pi is an amazing little device that pushes the limit on cool factor it simply is not what companies will be using to connect their devices. Not even close. They are using low level microcontrollers that have C code on them.

C is Not Back....But Relevant

So I'm not trying to start the "C is back, join the revolution" movement. In fact as hardware gets faster and smaller I think we will move on to higher level languages being closer to metal (Node.js on a PIC anyone?) but we're still a ways off from that. C is still, and will be for years to come, the go to standard for embedded development. And may I even suggest that learning C will make you a better programmer in your other languages. It certainly did for me. After all, being good at memory management never hurt anybody.

Saturday, November 10, 2012

Your DelayMs() Is...Delayed

I'm working like crazy to get more modules and documentation added to the EasyPIC project and as part of that I was working on a tutorial that illustrates a delay. In the delay module of EasyPIC I use the Delay.c and Delay.h files from Microchip. There's only one problem, the functions don't work properly in the free version of the compiler. They're too slow. Like almost exactly twice as slow. That means a call to DelayMs(1000) produces a 2 second delay instead of a 1 second delay.

Solutions

There are a couple of ways to get around this besides paying for a version of the compiler that provides the necessary optimizations. The first, and simplest, is to write your own delay function using the built-in __delay_ms() function. I have found it to be accurate but it doesn't take large arguments so you will have to wrap it in a loop like:

i = 200;
while(i--) __delay_ms(10);

The other option is to use a timer and either trigger an interrupt on overflow or just poll the interrupt flag. This does mean you'd have one less timer available to your application but if that's alright this will provide a very accurate timer.

Monday, November 5, 2012

Auto-Incrementing Build Number in MPLABX

I must admit that I like a lot of the new features available in MPLABX. I used MPLAB for years and always felt it very lacking in the code editing department. MPLABX is much better in that regard although I still use Sublime Text 2 to do most of my source file editing. One of my favorite features of MPLABX is the build system being based on makefiles.

What Is It?

So the first question is what is an an auto-incrementing build number? Well, there are really two aspects to this as far as I'm concerned. The first is a definition that is available from within your source code so if you were to use a define like BUILD_NUMBER it would evaluate to the current build. This is handy for printing out the current build without having to change a hard-coded number somewhere. While that's nice I'm more interested in the other use of a build number which is in naming the output file. I wrote an SD bootloader that parses the name of the target hex file and determines if it's a newer version than that currently loaded. To accomplish this I use a specific naming convention of v[major]_[minor]_[build].hex. Instead of having to rename the output from MPLABX every time I like it to just assign a new name automatically each time I build.

Give Me The Code

My current implementation currently only increments the build number and is meant to run in a Windows environment. This is much easier to accomplish on a *nix machine. I do this because I want to control when the major and minor versions roll. The implementation is quite simple and you can modify it to suite your specific needs. The first thing you will need to do is find the .X folder created by MPLABX. It defaults to a name like [Project Name].X. In that folder there is a file named Makefile.

  1. Open Makefile in a text editor
  2. In the .build-post: section simply add a call to a batch script we will create called deploy.cmd (remember to indent it properly per the makefile syntax)
      call deploy.cmd
    
  3. Create a new file named deploy.cmd in the same folder as Makefile and add the following code
    setlocal enabledelayedexpansion
    
    set major=0
    set minor=0
    set buildnum=
    
    del /Q ..\bin\*.*
    
    for /f "delims=;" %%i in (build_number.txt) do set buildnum=%%i
    
    cp dist/default/production/piclibs.X.production.hex ../bin
    mv ../bin/piclibs.X.production.hex ../bin/v%major%_%minor%_%buildnum%.hex
    
    @echo.
    @echo.
    @echo.
    @echo ===============================================================
    @echo Created new firmware version: v%major%_%minor%_%buildnum%.hex 
    @echo ===============================================================
    
    set /a buildnum=%buildnum% + 1
    
    @echo %buildnum%;> build_number.txt
    
  4. Change the cp and mv lines to match the default name of your production output hex file
  5. Save and close deploy.cmd
  6. Create a file named build_number.txt in the same directory as Makefile and deploy.cmd
  7. Add the starting build number followed by a semicolon. Save and close.

That's it. When you build you'll get a file in your output directory (defined in deploy.cmd) that is appropriately named and it will increment the build number in build_number.txt.

Customize It

All of the magic happens in deploy.cmd which is simply a batch script that is run by the make process after a successful build. We hard code the major and minor version numbers in deploy.cmd with set statements so you can change those just by altering the assignments.

set major=0
set minor=0

I like to output my production files outside of the MPLABX folder because I don't like the nested location and I don't like the name it assigns. I like my outputs to be in a bin folder at the root of my project. You can alter this behavior by modifying the copy and move statements in deploy.cmd. You can also modify the name of your output file by modify the second half of the move line. If you have any suggestions or better approaches feel free to send me a message or post a comment.

Wednesday, February 22, 2012

PIC32 Awesomeness

I've been head-down in tinkering mode for a while now and recently made the decision to upgrade my PIC from the 18F series to the PIC32MX series and I have not been disappointed. I'm doing development on the PIC32MX795F512L with the USB 32-Bit Whacker board from Sparkfun. I currently have the Microchip TCP/IP stack running with WiFi (MRF24WB0MB), USB serial terminal emulator, real time clock and calendar with alarm functionality and this thing doesn't skip a beat. As part of my WiFi implementation I'm sending/receiving JSON using the cJSON library and I still have plenty of code and data memory left. One of the major upsides to the PIC32MX family coming from the 18F series is that I no longer have to do weird data/program memory switching when dealing with strings. On the 18F series, for example, if you wanted to do a strcpy you had to use different functions depending on whether you were copying a string from RAM to RAM, RAM to ROM, ROM to RAM, etc. With the PIC32 it's like you're writing a C program that runs on you're local machine; you just use strcpy. Some of the other things I love about development on this chip:
  • RAM code execution
  • PIC32 Peripheral Library (great abstraction of many chip features)
  • Built in exception-handling
  • 128K of RAM
  • Blazing fast at 80MHz