MPLABX Command Line

It’s no secret: I hate IDEs. I also hate proprietary compilers, but sometimes I have to begrudgingly use them. Microchip uses GCC for their PIC32 series, but their 8- and 16-bit microcontrollers use their own XC8 and XC16 compilers which have a free option which don’t optimize. Regardless of which version (free, standard, pro) of the compiler you have, it’s nice to know that you can not only compile but also program and debug PIC based projects from the command line on all three operating systems supported by MPLABX.

Compiling

MPLABX uses standard (though kind of convoluted) @Makefile@s. The Makefiles are generated within the IDE when you set up the project. Once that is done, though, you don’t really need the IDE for anything else, and you can cobble together your own Makefile using their templates.

Compiling is as simple as running make. Linux has GNU make available, and OSX has make as part of XCode. For Windows, MPLABX includes a version of make in the installation.

Programming

The debugger is run from a shell script, mdb.sh which is part of the installed file set from MPLABX. It looks like it’s either a stripped-down version of gdb or it was made to emulate gdb in a number of aspects. I haven’t done much with it at this point yet. It does support the use of script files, and this is what is used to easily program from the command line.

In a nutshell, you will use the script file to tell MDB which device you’re targeting, which programmer you’re using and then specify which hexfile to program into the device:

device pic18f4520
hwtool pickit3 -p
program "myprogram.hex" 
quit

save this is pgm.txt or something and pass it along as a parameter to mdb.sh:

mdb.sh pgm.txt

You may need to include the full path to mdb.sh depending on your environment.

A Note on Java

OSX and Java don’t seem to get along very well, and while MPLAB-X seems to work fine with a newer JVM/JDK, the programmer absolutely requires version 1.6. I had installed 1.8 to screw around with Eclipse on another project and through installing 1.8, managed to break command line programming:

$ make program
/Applications/microchip/mplabx/mplab_ide.app/Contents/Resources/mplab_ide/bin/mdb.sh prog.cmd
To use MPLAB X jar files you must use version 1.6

I tried overriding the 1.6 version check but that just caused mdb.sh to explode:

$ make program
/Applications/microchip/mplabx/mplab_ide.app/Contents/Resources/mplab_ide/bin/mdb.sh prog.cmd
To use MPLAB X jar files you must use version 1.6
Device PIC24FV32KA304
content/mplab/mplab.deviceSupport
content/mplab/MPHeader.xml
content/mplab/PluginBoardSupport.xml

set system.disableerrormsg true

Hwtool PICkit3 -p
java.lang.IllegalStateException: java.lang.IllegalAccessException: Class org.openide.util.WeakListenerImpl$ProxyListener can not access a member of class org.openide.filesystems.$Proxy0 with modifiers "public" 
    at org.openide.util.WeakListenerImpl$ProxyListener.<init>(WeakListenerImpl.java:423)
    at org.openide.util.WeakListenerImpl.create(WeakListenerImpl.java:164)
    at org.openide.util.WeakListeners.create(WeakListeners.java:271)
    at org.openide.filesystems.MultiFileObject.<init>(MultiFileObject.java:125)
    at org.openide.filesystems.MultiFileObject.<init>(MultiFileObject.java:142)
    at org.openide.filesystems.MultiFileSystem.getMultiRoot(MultiFileSystem.java:267)
    at org.openide.filesystems.MultiFileSystem.setDelegates(MultiFileSystem.java:190)
    at org.openide.filesystems.Repository$MainFS.resultChanged(Repository.java:206)
    at org.openide.filesystems.Repository$MainFS.<init>(Repository.java:182)
    at org.openide.filesystems.Repository.assignRepository(Repository.java:141)
    at org.openide.filesystems.Repository.initialize(Repository.java:118)
    at org.openide.filesystems.Repository.getDefault(Repository.java:291)
    at org.openide.filesystems.FileUtil.getConfigFile(FileUtil.java:2168)
    at com.microchip.mplab.mdbcore.platformtool.PlatformToolMetaManager.init(PlatformToolMetaManager.java:123)
    at com.microchip.mplab.mdbcore.platformtool.PlatformToolMetaManager.<init>(PlatformToolMetaManager.java:115)
    at com.microchip.mplab.mdbcore.platformtool.PlatformToolMetaManager.getSingleton(PlatformToolMetaManager.java:108)
    at com.microchip.mplab.mdbcore.platformtool.PlatformToolMetaManager.getAllTools(PlatformToolMetaManager.java:75)
    at com.microchip.mplab.mdb.debugapi.ToolFinder.getPlatformToolMetaByHardwareName(ToolFinder.java:209)
    at com.microchip.mplab.mdb.debugapi.ToolFinder.getPlatformToolMetaByCmdToolName(ToolFinder.java:195)
    at com.microchip.mplab.mdb.debugapi.cmd.cli.Hwtool.run(Hwtool.java:89)
    at com.microchip.mplab.mdb.debugapi.CommandInterpreter.runCommand(CommandInterpreter.java:54)
    at com.microchip.mplab.mdb.debugapi.CommandInterpreter.process(CommandInterpreter.java:114)
    at com.microchip.mplab.mdb.debugapi.FileReader.Process(FileReader.java:68)
    at com.microchip.mplab.mdb.debugapi.CommandInterpreter.ProcessCommandFile(CommandInterpreter.java:27)
    at com.microchip.mplab.mdb.debugcommands.Main.run(Main.java:47)
    at com.microchip.mplab.mdb.debugcommands.Main.main(Main.java:31)
Caused by: java.lang.IllegalAccessException: Class org.openide.util.WeakListenerImpl$ProxyListener can not access a member of class org.openide.filesystems.$Proxy0 with modifiers "public" 
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
    at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
    at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:412)
    at org.openide.util.WeakListenerImpl$ProxyListener.<init>(WeakListenerImpl.java:413)
    ... 25 more
system did not find the tool [ PICkit3].

Fortunately, the fix turned out to be straightfoward. In mdb.sh there is a check for whether we’re running on OSX (Darwin) or not, and if so, it sets the $jvm variable to “java”. I looked at the file to see what it was and lo and behold, it’s just a symlink. Moreso, the old java 1.6 JDK was still there as well:

$ which java
/usr/bin/java

$ ls -l /System/Library/Frameworks/JavaVM.framework/Versions/
total 64
lrwxr-xr-x  1 root  wheel   10 23 Oct  2014 1.4 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 23 Oct  2014 1.4.2 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 23 Oct  2014 1.5 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 23 Oct  2014 1.5.0 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 23 Oct  2014 1.6 -> CurrentJDK
lrwxr-xr-x  1 root  wheel   10 23 Oct  2014 1.6.0 -> CurrentJDK
drwxr-xr-x  8 root  wheel  272  8 Dec  2014 A
lrwxr-xr-x  1 root  wheel    1 23 Oct  2014 Current -> A
lrwxr-xr-x  1 root  wheel   59 23 Oct  2014 CurrentJDK -> /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents

So, to use java 1.6 with mdb.sh I just edited the script:

if [ $os = Darwin ]; then
  # we do not ship java with MPLAB X IDE for the Mac (not allowed).
  # assume java is in the path. It must be java 1.66
  export jvm='/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Commands/java'
  # make sure it is 1.6
  $jvm -version 2>&1 | grep 'java *version *\"1\.6' >/dev/null
  if [ $? -ne "0" ]; then
   echo "To use MPLAB X jar files you must use version 1.6" 
   exit 1
  fi
else

My change was on the export jvm line. The original was export jvm=java. By pointing to the specific version I wanted, sanity (at least as much as can be had when working with Java) was restored.

Debugging

More to come once I use it a little more.

Add picture from clipboard (Maximum size: 1 GB)