Migrating to GPUTILS from MPLAB
For the projects I work on these days, switching to a Mac OS X-based development environment has been mostly painless. Eagle works, Java and Ruby are essentially cross-platform, and there’s always Unix just under the covers.
It’s the hardware tools that have been difficult to migrate, mostly related to PIC assembly and programming. On the PC, I’ve been using MPLAB for PIC code development and simulation, but that program isn’t available on the Macintosh. Luckily, GPUTILS is a stellar alternative that runs on Mac OS X. I ran into only a couple of issues in switching over.
Unsupported directives access_ovr and idata_acs
My Modbus implementation supports both ASCII and RTU modes, but only one or the other at a time. This constraint permits me to overlay the mode-specific variables so they share the same physical memory (since I know both modes won’t operate simultaneously), and I used access_ovr
to locate that memory in the PIC18F242’s access bank:
From ascii.asm:
;; ---------------------------------------------------------------------------
.modeovr access_ovr
;; ---------------------------------------------------------------------------
ASCII.Delimiter res 1 ; frame delimiter character
ASCII.Timeouts res 1 ; supports extra long (>1s) delays
From rtu.asm:
;; ---------------------------------------------------------------------------
.modeovr access_ovr
;; ---------------------------------------------------------------------------
CharTimeout res 2 ; the inter-character timeout, in μs
FrameTimeout res 2 ; the inter-frame timeout, in μs
TimeoutDelta res 2 ; difference between timeout values
The latest version of gpasm
(from GPUTILS v0.13.7) doesn’t support access_ovr
, but it was trivial to add myself. The resultant map file looks good, although I admit I haven’t tried the binary on a real device yet (see below).
Likewise, gpasm
omits support for the idata_acs
directive, which I was using—I thought—to initialize some variables in the access bank:
From random.asm:
;; ---------------------------------------------------------------------------
idata_acs
;; ---------------------------------------------------------------------------
Random.Value dw 0
As it turns out, idata_acs
is intended to be used with C programs only, since it relies on the C start-up code to do the actual initialization. The directive is pretty much useless if that code isn’t linked in—which it isn’t—so my IDATA was never initialized. I never noticed because the values weren’t critical (the code above defines the random seed) or were otherwise explicitly initialized during execution.
The solution was to replace idata_acs
with udata_acs
and use res 2
instead of dw 0
.
gpasm dies with “Bus error”
This issue seemed a little more serious. Luckily, it only happened on one source file, so I was able to quickly narrow it down to a problem with my config
directives. I had placed them ahead of the chip-specific header #include
; once I moved that #include
up, the bus error went away.
Even though the solution was straightforward, I usually prefer informative application messages over scary two-word system errors. Yikes!
As an aside, MPLAB never complained about my config placement, although I did have trouble programming the resulting hex file using MicroPro (from DIYpack 25). It always complained about an invalid format, so I ended up commenting out the config
directives and setting the fuses manually, quite a pain to do every time. After running into this issue with gpasm
, however, I tried MPLAB on the corrected file; still no luck with MicroPro. (This may be fixed by the latest version—renamed MicroBrn—but I’m not interested in all the IP baggage associated with the upgrade.)
gpasm is more stringent with opcode target
Not really an issue, this behavioral difference between the two assemblers may be due to a simple configuration setting I don’t know about. gpasm
warned me whenever I forgot to specify an F or W target when required. This wasn’t a warning I ever received from MPLAB, and though the default (F) was appropriate in every case, I still appreciated knowing where I had neglected to be explicit.
Still haven’t programmed GPUTILS output to a real device
The first step was just getting gpasm
, gplib
, and gplink
to process my sources error-free and generate a valid hex file. That appears to be the case, so the next step is to get that file onto a device. That’s a saga for a different post.