This blog is an understanding and introduction to multicore platform, working with existing multicore blinky example (M4 core as master, M0 as slave). This multicore example sets up the M4 core as the MCU master that communicates with the M0 core running as a slave. This project is meant to work with the m0slave_blinky project as the slave and the m4master_blinky project as the master.
The LPC54102 is a member of the LPC54100 family of devices, integrating two 32-bit ARM cores. Targeted for low power applications, this device is optimized for the lowest power consumption in active mode and also provides excellent power numbers in stand-by and power-down modes.
The two cores, a Cortex-M4F and a Cortex-M0+, can work independent of each other or team up to work on shared tasks.
LPC54102 Dual Core Overview
The Cortex-M4F in LPC54102 has the following features:
• MPU and single precision FPU
• Three interrupt priority levels and VTOR register
• SysTick timer
• Sleep mode power saving + NXP’s extended modes
• SW-DP with 8 breakpoints, 4 data watchpoints
The Cortex-M0+ in LPC54102 has the following features:
• Multiply support in hardware (32-clock cycle version)
• SysTick timer
• VTOR register
• Sleep mode power saving + NXP’s extended modes
• SW-DP with 4 breakpoints and 2 data watchpoints
Dual core system integration
Both ARM cores are implemented as AHB masters (Advanced High Performance Bus), this means that they both have full control of the available resources on the LPC54102 device.
It is clear that an access to the same resource may result in bus contention; therefore, proper planning of the tasks for the two cores is beneficial. The part provides adequate flexibility to alleviate this issue.
• Depending on the application setup, one core is designated the master and owns the Flash while the other core uses SRAM for code
Access to the flash can happen in parallel, the Cortex-M4F uses the I-code and the D-code bus for code execution whereas the Cortex-M0+ uses the System bus. Access to SRAM can also be split onto SRAM0 and SRAM1.
• Access to the same resource causes bus arbitration.
The resource planning is an important part of a dual core software project because only the Cortex-M4F owns a Memory Protection Unit (MPU).This MPU can be used to prevent the Cortex-M4F to run into areas, such as the stack area of the Cortex-M0+.
On the Cortex-M0+ side this is not possible, there is no safe way to prevent the Cortex-M0+ from poaching in memory areas which are dedicated to the Cortex-M4F.
The two cores are an asymmetric implementation, compared to application processors with two Cortex-A9 for example. So any type of parallel processing would be difficult to implement, due to the different capabilities of the cores and the way the cores share the on-chip resources.
Core-to-Core Communication
To share tasks between the two cores, a certain level of communication and hand-shaking is required.
The Mailbox unit provides low level features for an inter-core communication. To enable this block the bit MAILBOX in register AHBCLKCTRL0 needs to be set (SYSCON unit).
Mailbox implementation
There is no optimal hardware mailbox structure implemented in LPC54102. There is no dedicated hardware controlled FIFO or ring buffer to stream data from one core to the other. The following three mechanisms allow for creation of a mailbox structure in software:
• Core-to-core interrupts
• Mutex register
• Equal access to SRAM memory areas
Core-to-core interrupts
Each CPU can cause up to 32 user-defined interrupts to the other core. For this there are two 32-bit R/W registers IRQ0 and IRQ1 with their corresponding write-only SET and CLEAR registers.
• Writing a ‘1’ into a bit of IRQ0 (either direct in IRQ0 or via IRQ0SET) fires an interrupt into direction Cortex-M0+.
• Writing a ‘1’ into a bit of IRQ1 (either direct in IRQ1 or via IRQ1SET) fires an interrupt into direction Cortex-M4F.
These 32 bits can be defined by the programmer to have a specific meaning.
Mutex mechanism
The register MUTEX is intended to be used for a mutual exclusion mechanism. It can be accessed by both cores in atomic operation. When read for any reason, the current value will be returned and the bit will be cleared. The bit will be set again following any write.
Shared RAM usage
As both cores have equal access to the chip resources, the internal SRAM can be used to create a communication pipeline in both directions. The access priority scheme on the AHB matrix can be influenced.
The Multilayer AHB Matrix arbitrates between several masters, only if they attempt to access the same matrix slave port at the same time. Care should be taken if the value in this register is changed, improper settings can seriously degrade performance. Priority values are 3 = highest, 0 = lowest. When the priority is the same, the master with the lower number is given priority.
Dual core access with SWD
There is one Serial Wire Debug interface for both cores. The LPC54000 family does not support the JTAG interface for debugging, the interface can only be used for boundary scan.
One debug probe(for example LPC-Link2 Jlink ULINK2ULINK2 ULINKPro can connect to both cores at the same time The following two scenarios are possible
• One SW debugger instance connects to one of the cores through one HW interface.
• Two SW debugger instances connect to both cores through one HW interface. For this the debugger software needs to know which Memory Access Port (MAP) needs to be addressed.
• One SW debugger to both cores
To proceed further the below are the prerequisites:
- Installed LPCXpresso IDE tool chain or you can download it from below link:
https://www.lpcware.com/lpcxpresso/download
- LPCOpen examples and libraries:
or
C:\nxp\LPCXpresso_8.1.4_606\lpcxpresso\Examples\LPCOpen
- LPCXpresso 54102 development board hardware OM13077OM13077
LPCOpen Dual Core Software Setup
Basically the projects for the Cortex-M4F and the Cortex-M0+ are separate projects. Each is compiled with its own settings for the respective instruction set. This means that at the end of the compilation for the two cores, there are two images which need to be programmed into flash. It is also possible to integrate one image into the other (as C-array source file or as AXF file) and program only one image.
Both methods come with pros and cons which will depend mostly on user preference.
Combined image download
There are a few different ways to integrate one image into the other. One is to generate a C-array from the linked code and put this as a source file into the other project. This is the most convenient method if one core executes from ROM and the other one from RAM.
Separate image downloads
If both code images reside in flash memory, they are normally compiled and programmed separately. The only hard dependency between the two projects is the start address of the Cortex-M0+ image, this is something the Cortex-M4F code needs to know.
Boot process
After a power-up or hardware reset, the boot process is handled by the on-chip boot ROM and is always executed by the Cortex-M4F core. After the bootloader code and the system init section, the Cortex-M4F can set up the environment for the Cortex-M0+.
• Provide a reset handler start address to the Cortex-M0+
• Provide a stack pointer address to the Cortex-M0+
Let’s begin the process of debugging the multicore. This example toggles the green and red RGB LED
The Cortex-M4 acts as the master and the cortex-M0+ as the slave, sharing the state of the led through a hardware mutex and communicating by means of a mailbox mechanism
Open LPCXpress and select the workspace as shown below:
Now import the example project into the workspace as shown below
Browse the project archives (zip) from the location:
“C:\nxp\LPCXpresso_8.1.4_606\lpcxpresso\Examples\LPCOpen\lpc5410x_lpcxpresso_54102_lpcxpresso_3.01a.zip”
Next select the example project folder “multicore_m0slave_blinky” , “multicore_m4master_blinky” and required LPC chip library and LPC board library as shown below:
Now compile both the project or select “Build all projects” option from quick start panel once to ensure there are no errors:
Now set a breakpoint at “Chip_MBOX_Init(LPC_MBOX);” inside the “m4master_blinky.c” of multicore_m4master_blinkyproject
Now plug in the board and click on the Debug "multicore_m4_master_blinky" from quickstart panel, after compiling it will ask the connection to emulator as shown below:
it will prompt you to select LPCLINK2 RedLink emulator
Next you have to select one of the SWD devices available, we are selecting M4 here
Now click on Resume button to execute the master project:
The Debugger will stop at “Chip_MBOX_Init(LPC_MBOX);” line as shown below
Now this will be ready to start other debugging core (i.e M0+)
Next select the “multicore_m0slave_blinky” project folder and click the debug button from quickstart panel as we did for master
Select the LPC-Link2
Now select Cortex-M0+ for SWD device
Now the second debug session is ready to run in ‘attach only’ mode.
You can see there are two debug sessions running one for Cortex-M4 (master) and other for M0+ (slave)
Now click on resume button on master side where we had stopped earlier
After resuming the cortex-M4 the Chip_CPU_CM0Boot() function wakes up the cortex-M0+ core and its debugging session pops up at the main() waiting for you to click resume at slave end side
And finally have both cores running through the debugger at once, If everything goes on well then you can see the toggling of the Red/Green led at your board.
Explanation of the project:
When this example works correctly and both cores are running, board LEDs 0 and 1
will toggle at about 1Hz. When one LED is on, the other LED is off.
m4master_blinky:
Sets up the system via SystemInit() and initializes the board layer via Board_Init(). The M0 slave does not repeat this step.
- Shares a 32-bit value bewteen both cores that contains LED on/off state for board LEDs 0 and 1 in bit position 0 for the master and bit position 1 for the slave. A 0 or 1 in these bit locations indicates the LED off(0) or on(1) state for board LEDs 0 or 1, respectively.
- Sets up the mailbox and hardware mutex. This is only performed once by the master core. Enables the mailbox interrupt.
- Initializes the M0 slave core boot entry address and stack pointer. The startup code for both the M0 and M4 cores is shared with the M0 core being placed into a safe, low power state. Once the master sets up the necessary addresses, the M0 slave core is reset and boots with the address and stack given by the master. Note the shared M0/M4 startup code handles this part of the boot sequence.
- Grabs the hardware mutex for the shared LED state value.
- Sets up a periodic system tick event which toggles the LED0 state value at about 1Hz. This doesn't yet toggle board LED0 yet, only the state value.
- Triggers a mailbox event to the M0 slave core with the address of the shared LED state value.
- Returns the hardware mutex for the shared LED state value.
There might be a small overlap period where both cores attempt to access the hardware mutex. The core attempted to get the mutex will keep trying until the
mutex is available.
- At some point, the mailbox will be triggered from the slave core. When this happens, a mailbox interrupt is generated and both of the board LED states are
updated from the shared LED state value.
- The mailbox interrupt is cleared.
- The master MCU sleeps while not performing any other tasks.
m0slave_blinky:
Uses a special version of the startup code that bypasses SystemInit().
- Does not link agains tthe board library (M4 does board init)
- Enables the mailbox interrupt.
- At some point, the mailbox will be triggered from the master core. When this happens, a mailbox interrupt is generated. The mailbox contains an addrsss that
points to the M4's shared LED state value.
- Grabs the hardware mutex for the shared LED state value.
- The LED1 state value is toggled in the shared LED state value. This doesn't yet toggle board LED1 yet, only the state value.
- Returns the hardware mutex for the shared LED state value.
- The mailbox interrupt is cleared.
- Triggers a mailbox event to the M4 master core that the M0 slave side is done.
- The slave MCU sleeps while not performing any other tasks.
Happy working on with multicore platform





















