When the device comes out of reset, only CPU1's boot ROM
executes. CPU2 is held in reset by hardware and cannot run any code
until CPU1 explicitly releases it. This means:
-
System clocks and PLL are initialized
exclusively by CPU1. Until CPU1 configures the PLL and waits for it
to lock, the device is running on the internal oscillator at
reduced speed. CPU2 inherits whatever clock state CPU1 has
established.
-
Peripheral ownership is assigned by CPU1.
The device has a set of peripherals that can be assigned to either
core - but the assignment registers are write-protected from CPU2.
Only CPU1 can decide which core owns which peripheral.
-
GPIO initialization is done by CPU1. All
GPIO mux, direction, and pull-up settings must be configured by
CPU1 before CPU2 can safely use any GPIO.
-
Watchdog for the overall system is
managed by CPU1. CPU2 has its own watchdog, but system-level
protection starts with CPU1.
On every reset, the following sequence occurs:
-
CPU1 boot ROM executes. The boot ROM reads the
boot mode pins (GPIO84, GPIO72, etc. depending on the device) and
determines how to boot - JTAG, SCI, SPI, CAN, I2C, parallel, or
directly from flash. This is the bootloader phase and it runs
entirely on CPU1.
-
CPU1 application starts. Once the bootloader
hands off, CPU1 begins executing the application. The first thing a
well-written CPU1 application does is:
-
- Initialize the device (PLL, clocks, flash wait states)
- Assign peripheral and memory ownership
- Initialize any shared memory regions that CPU2 will need
-
CPU1 releases CPU2 from reset. CPU2 cannot
start on its own. CPU1 must call the boot sequence for CPU2 - in
driverlib this is Device_bootCPU2(). This function writes to the
IPC registers to signal CPU2's boot ROM to execute and specifies
the boot mode for CPU2 (typically boot from flash or boot from a
specific RAM address loaded by CPU1).
-
CPU2 boot ROM executes. CPU2's boot ROM runs
its own boot sequence, using the boot mode that CPU1 specified via
IPC. If CPU1 directed CPU2 to boot from flash, CPU2 jumps to its
flash entry point. If CPU1 directed CPU2 to boot from SARAM (useful
in RAM debug builds where CPU1 has already copied CPU2's image),
CPU2 jumps to the loaded code.
-
Both cores run independently. After this
point, both CPUs execute their respective applications
concurrently. Coordination between the two is handled entirely
through IPC flags and shared/message RAM - there is no further
hardware dependency between them during normal execution.