Archives

Now that I’ve been using a PIC32MX microcontroller for a while, and its associated software tools from Microchip, it’s time for a mini-review. My previous microcontroller experience was primarily with 8-bit Atmel AVRs, so my comments will reflect that. Many of the differences between a PIC32MX and AVR will also apply to any other modern 32-bit microcontroller, like the many ARM variants.

On the whole, I’ve been fairly pleased with the PIC32MX. Below you’ll see that I’ve written much more about dislikes than likes, but that’s because the likes are largely self-explanatory, while the dislikes deserve a more detailed explanation.

Note: Last year Microchip purchased Atmel, the makers of the AVR. So now both of the microcontrollers in my comparison are provided by the same company.

HARDWARE LIKES

Faster core speeds – Up to 50 MHz on my PIC32MX230F256, 80 MHz on other devices in this family.

Configurable pin remapping – Relocate functions like the UART’s TXD and RXD to one of several different possible physical pin locations. Makes PCB routing much easier.

Set / clear / invert registers – Modify a single GPIO pin with a single instruction, without needing to do a read-modify-write of an entire port.

DMA – I haven’t used it yet, but this will enable possibilities like writing a long piece of text to the serial port while the program continues on to do other things.

SOFTWARE LIKES

IDE – The Microchip MPLAB X IDE seems pretty good, after you install the separate PLIB libraries that are required for compiling all the example code.

Debugger – With the el-cheapo PICKit 3 programming tool, you get a halfway decent debugger in MPLAB X. I can’t believe I survived for years on the AVR with no debugger at all.

HARDWARE DISLIKES

Bloaty code – A similar amount of code seems to consume substantially more program flash memory on the PIC32MX than the AVR, so the larger amount of flash on the device isn’t as much of an advantage as it first seems. Part of this is due to the hardware difference between 8-bit and 32-bit instructions, and part due to compiler optimizations to software (see below).

Awkward bootloader setup – The PIC32MX230F256 has 3KB of protected boot flash, which isn’t enough to do anything useful, considering how bloaty the code is, and that more than 1KB will be consumed by interrupt vector tables and the C startup code. My USB mass storage device bootloader is 39KB of code! This forces the bootloader to be located in main program flash, which requires using a customized linker script for the main program to map everything to new memory locations, which requires that the bootloaded and non-bootloaded versions of the main program are subtly different.

No EEPROM – AVR has separate non-volatile EEPROM memory for storing user preference data, that can be updated one byte at a time, and is rated for 100K erase cycles. PIC32MX has no equivalent. You can reuse some of the program flash memory for the same purpose, but it can only be updated one page at a time (1K or 4K depending on the device) and is rated for 10K erase cycles.

Fewer instructions per clock cycle – AVR executes one instruction per clock cycle, so 16 MHz means 16 MIPS. The number of instructions per clock cycle for PIC32MX varies, but will on average be less than one, due to flash memory wait states, addressing modes, pipeline stalls, and other factors. So while the core speed of PIC32MX might be 3x faster than AVR, it won’t necessarily run code 3x faster.

SOFTWARE DISLIKES

Debugger limitations – When using the PICKit 3, the debugger can’t view arbitrary memory or array elements, can’t set new breakpoints while the program is already running, can’t step through a disassembled view of arbitrary code (without a map file), and is incredibly slow for single-stepping through code. I’m not sure if these are software issues, or limitations of the PICKit 3. Microchip offers other more expensive debugging tools that may address these issues.

Limited compiler optimizations – The XC32 compiler that’s included with MPLAB X will compile your code with -O0 (no optimization) or -O1 (some optimization for speed and size). But it won’t do -O2 (more optimization for speed) or -Os (optimize for size). It also won’t do a bunch of related linker optimizations to help reduce code size. Those require the pro version of the compiler, which is a $30/month subscription.

Mixed quality libraries and code examples – Almost all the PIC example code you’ll find on the web, from Microchip or 3rd parties, uses the PLIB peripheral library along with MLA (Microchip libraries for applications). A few years ago these were officially discontinued in favor of a newer solution called Harmony, but the developer community has largely ignored Harmony and continued using PLIB and MLA. The strong impression I had was that attempting to use Harmony would make life unnecessarily difficult. Yet some of Microchip’s newer code examples are only available in Harmony versions, while older examples are only PLIB/MLA versions, resulting in a confusing mess.

Many of the PIC32MX code examples I found were designed for the top of the line, the PIC32MX795. These examples are mostly applicable to the PIC32MX2xx family too, but sometimes there are subtle differences that are difficult to catch. For example, Microchip’s PIC32 USB mass storage bootloader example assumed the device had a flash erase page size of 4K, with a comment in the code that said “do not change this value”. Only after much frustration did I discover why it wasn’t working reliably – the PIC32MX2xx has a 1K flash erase page, so the Microchip code was only erasing 1/4 of the the flash memory during bootloading.

2 Comments so far

GotNoTime May 10th, 2017
1:16 pm

The PIC32MX compiler is actually GCC and the Pro edition lock regarding optimisation is an extra check that Microchip added. You can actually compile their version of GCC from scratch and re-enable all of the optimisations for free. Another option is to replace the license checker to always indicate you’ve got the Pro version and then patch GCC because they’d gotten wise to this and now hash the license checker binary.

I personally don’t see any issues with this considering it is GPLed code in the first place anyway and the same libraries are used whether you’re in -O0 or -O2 mode. Just giving you an option anyway as I fully understand not everybody will be so willing to mess with it.