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.