|
Part 1: Laying Out the Tools
by Fred Eady
Start ı Tooling
Up ı Hardware Development Tool ı Software
Development Tools ı Selecting a Terminal
Emulator ı The Boot Loader ı Add
Virtual Paper ı Sources and PDF
THE BOOT LOADER
Itıs easy enough to program the PIC16F877
in a controlled environment like the Florida room. Itıs also a simple
task to program the PIC16F877 by other means in other places if you
do your homework. The S-7600A/PIC16F877 Internet Engine is designed
to interface with the most common I/O transport on computing devices
today, the serial port. Unfortunately, the PIC16F877 doesnıt come
with any pre-loaded intelligence, and it would be impractical to design
a programming circuit that you would have to touch to operate. Thatıs
where the boot loader idea comes in.
A typical boot loader is a small program
that resides in the least conspicuous area of a microcontrollerıs
ROM area. The boot loaderıs job is to lie low until called upon to
help put code in the desired places of ROM for immediate or later
execution. In the case of the PIC16F877, the area that is least noticeable
is at the bottom of the ROM area. Thus, the boot loader code will
try to reside as close to 0x1FFF territory as possible.
Other traits a boot loader must have is
the ability to be invulnerable to overwriting by incoming code; this
is done by simply writing in checks and balances at the boot loader
level. One such check can be found at the top of bootldr.c
which is available for download.
The MAXADDR value of 0x1E00 is as far as the incoming code can load
relative to location 0x0005. Youıre wondering why the relative beginning
of Codeville starts at 0x0005, arenıt you?
For the PIC16F877, the reset vector is
0x0000 and the interrupt vector is at 0x0004. If you want to use interrupts
in the downloaded firmware, location 0x0004 must remain vacant and
available. So, the first four positions of the ROM area (0x0000, 0x0001,
0x0002, and 0x0003) must vector the program execution around location
0x0004. In this case, that vector at the top of ROM will point to
the beginning of the boot loader code. Thus, every time a microcontroller
restart is initiated, the boot loader code runs first.
Referencing Listing 1 again, our reset
vector will immediately point the execution point to the C main routine
located at 0x1E44. This really hits home when you look at the Intel
hex file for the boot loader. Itıs no manıs land from location 0x0003
to 0x1E44.
Because the microcontrollerıs reset vector
is reserved for the boot loader, you must make arrangements to identify
and relocate the reset vector code for the code that is being downloaded
by the boot loader. This is simple to do in PIC assembler, but itıs
another thing in C. You donıt want much of anything hanging around
in the stack when you finish the download and turn over control to
the new code. So, to effect this, keep all of the code and volatile
areas you can inside the main braces. Also, because the PIC16F877
can write to ROM, I only have to define an area and reserve it for
the incoming reset vector information. This is done with assembler
directives at and around the bootcode label in Listing 1.
There are four NOPs representing relative
locations 0x0000 through 0x0003 following the bootcode label. The
incoming codeıs reset vector information overwrites these locations.
This means that all of the code the boot loader will handle must have
reset vector code that can be relocated to these four words. To make
sure that the new reset vector thinks itıs at the top of ROM (0x0000),
the PCLATH register is cleared. This effectively sets the high-order
bits of the PIC program counter to zero. The goto 0x00 instruction
following the NOPs takes care of the low-order bits of the program
counter. The result is a vector that resides somewhere near the bottom
of ROM but looks like it resides at 0x0000 through 0x0003.
Before reaching this gaggle of NOPs,
some necessary boot loader code must be executed. The first order
of business is to determine where the bootcode label is. This is done
using a couple of PCW assembler commands that translate to real PIC
instructions. MOVPHW and MOVPLW are equivalent to the native PIC assembler
MOVLW high and MOVLW low instructions. The high- and low-order bytes
of the location of the bootcode label are stored in the variables
addrh and addrl. The values are then ORed and stored
as a long integer in the variable bootcodeaddr.
It helps to tell the PIC how quickly
(or slowly in this case) the serial link will be running. On the PIC,
stuffing a couple of registers with the correct values does this.
The values can be acquired using a formula or by consulting the SPBRG
(serial port baud rate generator) tables in the PIC16F877 datasheet.
PCW automatically calculates this in a normal application, and that
code resides as close to the top of ROM as it can. Because I had to
corral the code here, I "turned off" the automatic transfer
rate generation. To do this, I simply did not include the #USE RS-232
statement in the code. The CREN and SPEN instructions refer to PIC16F877
USART registers and effectively enable the PIC USART for transmitting
and receiving.
The code that follows the USART and serial
port definitions looks for a character from the Tera Term Pro emulator
session. If a "u" is received, you have chosen to upload
new code into the area above the boot loader and below the boot loader
reset vector at the top of ROM. If no characters are received within
a time-out period, the do/while loop ends and the code execution falls
through to the bootcode area. If thereıs real reset vector code, the
branch will occur and the code residing in ROM will begin execution.
If there is no reset vector code, the NOPs are executed and a jump
to the boot loader reset vector at 0x0000 takes place.
If a "u" is received before
the time-out period, the code beginning with the upload label reads
an Intel hex file line by line and converts the incoming ASCII to
binary and writes the converted code to the ROM area designated by
the address field of the Intel hex line. Hardware handshaking is also
implemented in this segment of C code.
The PIC16C877 is instructed to allocate
two I/O lines for hardware handshaking purposes. Port B, pin 5 is
defined as the Clear To Send (CTS) output to Tera Term Pro, and Port
B, pin 4 is the Request To Send (RTS) input signal from the terminal
emulator. CTS is toggled to gate data from the Tera Term Pro session.
The Serialtest Async screen shot in Photo 6 uses arrows to show where
the CTS signals toggle and how the data flow reacts to the control
signals. In Photo 6, you can
see a depiction of data flowing without terminal pacing.
Terminal pacing is the value of milliseconds
between each character or line transmission. Tera Term Pro allows
the setting of a character or line pacing value in terms of milliseconds.
Note that a character following the CTS deactivation is buffered and
read after CTS is reactivated in Photo 6. By simply adding a 1-ms
delay between characters, the buffered character between the arrows
in Photo 6 is no longer there in Photo
7 and resides cleanly on one
side of the activation and deactivation of the CTS signal. This level
of data flow analysis is why Serialtest Async is so important to have
for this project. You can look at the data flow using Serialtest Async
and adjust the code for the desired results.
If everything transfers correctly, the
boot loaderıs Intel hex checksum calculation matches the incoming
data lineıs checksum. If every checksum matches, a "g" is
sent to the Tera Term VT100 emulator session. If any checksums do
not match, an "E" is sent. Tera Term Pro looks for these
characters and notifies you of the status of the upload. In either
event, the last assembler instruction of the boot loader vector to
the boot loaderıs reset vector and the newly uploaded program are
allowed to run or another upload session is initiated.
PREVIOUS
NEXT
Circuit Cellar provides up-to-date information for engineers. Visit
www.circuitcellar.com for
more information and additional articles.
For subscription information, call (860) 875-2199, subscribe@circuitcellar.com
or subscribe online.
ıCircuit Cellar, the Magazine for Computer Applications. Posted with
permission. |