This is actually two questions:
Q1. What happens when the F2812 is powering up in free
running mode (i.e. inside your customer's product)?
Q2. What happens differently when I run the (exact same)
code under Code Composer Studio?
I have partial answers to both questions and am seeking the
wisdom of this larger body of knowledge, because what I do
understand has been wrestled from the claws of 'burn &
learn' experience. I want to document it for my own use, and
if anyone else benefits, so much the better.
Here are my answers:
A1. Free running F2812
a. When the F2812 comes out of reset, and is strapped
in microcomputer mode (pin 17 = XMP/MC = 0),
internal hardware transfers a 32-bit word from
address 0x3F FFC0 to the program counter (PC). This
address is inside the 'boot ROM vector table,' which
is factory-programmed and contains 32, 32-bit
vectors (64 words) in little endian order. All but
the first are vestiges of a legacy architecture and
not used.
The first vector is the reset vector, which (always)
points to boot ROM address 0x3F FC00 (Note that this
is not the same address as 0x3F FFC0).
b. The code block at 0x3F FC00 is called the bootloader
and configures GPIOF, so it can then read in the
values from GPIOF4, GPIOF12, GPIOF3, & GPIOF2 (the
so-called 'boot-mode jumpers') before deciding what
to do.
If you have strapped your boot ROM jumpers for
boot-from-flash, it will transfer control to
0x3F 7FF6, which is 2 words near the end of the
flash memory and immediately before the 'password
locations.' This is the first memory address
actually under programmer control.
Two words is just enough room for a long branch. If
you want to initialize the C environment
immediately, this branch should go to _c_int00. If
you are afraid the watchdog will time out while
_c_int00 is transfering constants from flash to RAM,
this branch should go to another sub-section of the
compiler .text section you created in assembly file
CodeStartBranch.asm, beginning at label wd_disable.
This code block disables the watchdog timer and THEN
transfers control to _c_int_00.
c. Function _c_int00 is a pre-compiled library
object that comes from the C compiler run-time
support (RTS) library. It is NOT factory-
programmed and must be programmed into flash
at an address chosen by the linker at build
time. Its 3 most important tasks are:
- Put an initial value in the stack pointer,
- Copy flash section .cinit to RAM section
.bss so that all mutable global and static
variables start with the initial values in
your source files.
- Transfer control to the top of main().
e. The first instruction in your (C) application
executes. (We are not out of the woods,
yet.)
f. If you have functions you want to run out of RAM,
either to speed them up or because you want to tweak
the performance of the flash, you must copy them
(before calling them) from their flash (a.k.a 'load'
address) to their RAM (a.k.a. 'run') address. The
same goes for any data constants you want to fetch
from SARAM to achieve higher execution rates.
g. When you lower the XRS-L input to the
F2812, control follows the exact same
execution sequence as described above for
power up.
A2. Running boot-from-flash F2812 app under Code
Composer Studio
A. When you bring the application up under the emulator
in CCS (Target >> Debug active project), the first
thing you see is the PC pointing to the first
instruction in main(). Apparently, all the
activities described in steps a-c are performed out
of your sight by CCS.
B. If you have functions you want to run out of
RAM, but forget to copy them from flash to
RAM, as mandated in step f, CCS still
executes them from their 'load' address, without
complaint, thus preventing you from noticing a fatal
error that will get you a brain-dead micro in the
real world.
C. If you execute menu command Target » Reset » Reset
CPU, the PC value is reset to 0x3F FC00: which means
the second time you run your app in CCS, it launches
from step b, instead of step d.
Today I have an application that runs perfectly under CCS
supervision, but when I free run, some codes I write to LEDS
indicate that certain RAM locations have different initial
values at power up than they did with the emulator in place.
The rest of the app runs normally, however.
I invite anyone to critique, correct, or expand on my
observations. I fear there are still major differences
between emulator mode and free run that I have never heard
about.