STM32H745: Two Processors, One Flash, and Half a Delivery
Most microcontrollers answer the question “what is the program” with one vector table and one entry point. This part answers it twice. There are two cores on the die, they share one flash array, and the second one starts not because the first one tells it to but because a configuration bit was programmed at the factory or on the line. An image can be read out completely, checksum correctly, disassemble into sensible code, and still be half of the program.
The arrangement
One core is the high-performance processor, the other is a smaller and slower one intended for the work that does not need the big core: a communication stack, a real-time loop, housekeeping. They share memory and they share the flash array.
| element | high-performance core | second core |
|---|---|---|
| clock | up to twice the second core’s rate | half the first core’s rate |
| vector table | at the flash base by default | at an address configured separately |
| startup trigger | reset | a configuration bit, not a software call |
| typical role | application, display, maths | protocol stack, control loop, supervision |
The third row is the one that decides whether a recovery is complete. Nothing in the first core’s code has to contain a “start the other core” call for the second core to run. It boots because the configuration says it should.
Where the second program lives
The second core’s code is in the same array, at an address the first core does not use. That address is not fixed by the silicon — it is a design decision, recorded in configuration and in the first core’s linker script.
| what to look for | how it appears in a dump | what it tells you |
|---|---|---|
| a second vector table | an initial stack pointer inside a RAM region the first core does not use, followed by a reset vector inside the flash | the second program exists and where it begins |
| a large unclaimed gap in the address map | flash that is neither code nor erased | where the split was drawn |
| two different initial stack pointers | two words at two addresses, both plausible | both programs are present |
| strings and tables with no referencing code | data in a region nothing in the first program points at | the second program’s constants |
The first row is the reliable test, and it works because the two cores do not share a RAM layout. The high-performance core’s stack sits in one region; the second core’s sits in another. Two initial stack pointers in two different RAM regions is not a coincidence.
Why a half delivery looks complete
The failure is not that the tool fails. It is that everything succeeds.
| observation during the job | the wrong conclusion | what is actually true |
|---|---|---|
| a vector table at the base, sensible code after it | the program has been recovered | one of the two programs has been recovered |
| the rest of the array reads as data or erased | nothing else is programmed | the second program may be there but not recognised |
| the image runs on a bench setup | the recovery is validated | it validates one core, with the other held in reset |
| the customer reports the device does not work | the image is damaged | the second core never started |
The last row is the one that costs a second round trip. A board with the second core held in reset often still boots far enough to look alive, which makes “it works” a premature conclusion.
The configuration bit that enables it
The second core’s start is controlled by an option byte, and the state of that byte is as much a part of the deliverable as the code is.
| option state | behaviour at reset | consequence for a restore |
|---|---|---|
| second core enabled, boot address set | both cores start | restore must include both programs and the option bytes |
| second core disabled | only the first core starts | a restore of both programs alone will not bring the second one up |
| boot address left erased | second core starts from an undefined location | behaviour depends on what happens to be at that address |
The second row is the trap. A customer who has erased the device and restored the two program images, without restoring the option byte, gets a board that runs half the application and reports no error. The code is right and the configuration is missing.
Communication leaves traces
Where two programs cooperate, they have to synchronise, and the mechanisms used for that are visible in both programs.
| mechanism | what appears in the image | what it proves |
|---|---|---|
| hardware semaphores | an initialisation loop taking a fixed number of them, and take/release pairs | the two programs coordinate, so both are expected to run |
| inter-processor channels | channel configuration and a shared buffer address | one core is a producer and the other a consumer |
| shared memory with a flag word | a word written by one side and polled by the other | the split is a protocol, not just two programs in one array |
Finding the semaphore initialisation in the first program is close to proof that a second program exists, even before it is located. Designs do not take hardware semaphores for their own use.
What a complete return looks like
The return set is both program images with their boundaries stated, the vector table of each resolved, the option bytes decoded with the second core’s enable state called out, a disassembly annotated at both entry points, and a statement of how the two programs exchange data.
A related reading of the same generation, from the flash bank angle rather than the core angle, is at STM32H743 flash recovery. The display pipeline that occupies the largest structured block of memory on the sibling part is covered in STM32H747 heximal recovery, and the clock and voltage mode that bounds both cores’ speed in STM32H723 heximal extraction. For the read-out restrictions on a smaller STM32 part, STM32F358VC flash breaking covers the protection side.
FAQ
Does the first core have to start the second one? No. The second core starts because of a configuration bit, independently of anything the first core’s code does.
Can both programs be recovered in one read? Yes, they are in the same array; the work is recognising where one ends and the other begins.
Why does the board appear to work after a partial restore? Because the first core runs, and a board with one core running often looks alive until something asks it to do the second core’s job.
Conclusion
Two processors sharing one array means two programs, two entry points and one configuration bit that decides whether the second one ever runs. Delivering both images without the bit is a half delivery that validates on a bench and fails in the field, and the difference is stated in a report or discovered by the customer.