Over the past ten years, the processors in almost all of our devices have become multi-core. They are followed by multi-core microcontrollers. In the catalogs of major manufacturers, you can already find general-purpose microcontrollers with several cores at reasonable prices. So it looks like it's time to start using multi-core microcontrollers in your own devices. Naturally, in cases where it is justified.
. , . , . . .
-. ARM Cortex M NXP (LPC), STMicroelectronics Infineon (Cypress).
, .
- . , , . - , , .
- . ( , , ), . , ( Cortex M0) (, Cortex M4). , . , .
- . , . , . , , . .
.
. . . .
, (Master Core). . , (Slave Core), , reset. . System Control ( ).
, . . .
, , . , (Cortex M0), , (Cortex M4 / M7).
, . , β , . . . , .
, . (, LPC55S6x Cypress CY8C6xx5) . . (bus matrix). , . , , .
, STM32H747. , . , . .
, . , . , , . , , .
, , . , .
. . () FLASH- SRAM. . .
, (AHB1, AHB2, APB1, APB2β¦). , , «» .
(NVIC). . , , , NVIC. , NVIC . , : , , / . , , . , GPIO , , , .
. -. STM32 Hardware Semaphore (HSEM), NXP β Inter-CPU mailbox, Cypress β Inter-Processor Communication Block (IPC). , .
. Β« Β» (mailbox). , . NVIC . , , , - ( ).
β , . . . , , . , . , . , , . , . , . .
. .
. (Debug Access Port). - . ( ) . . .
. , , .
LPC55S69-EVK NXP LPC55S69, Cortex M33. IAR Embedded Workbench 8. , , . , .
CMSIS. . , .
0
. CPU0.
.
- C: Project > Create New Project. C / main. , 0, . CPU0.
- : File > Save Workspace.
- General Options > Target .
: , , .
- General Options > Library Configuration Use CMSIS.
- (C/C++ Compiler > Preprocessor) :
< SDK>\devices\LPC55S69
. Defined symbolsCPU_LPC55S69JBD100_cm33_core0
( , ). - Linker > Config Override default
LPC55S69_cm33_core0_flash.icf
SDK (< SDK>\devices\LPC55S69\iar
). - Debugger > Setup (Driver) CMSIS DAP.
- , Debugger > Download Verify Download Use flash loader(s).
-
system_LPC55S69_cm33_core0.c
startup_LPC55S69_cm33_core0.s
(< SDK>\devices\LPC55S69
< SDK>\devices\LPC55S69\iar
). , . ,
GPIO1_7
.
#include "LPC55S69_cm33_core0.h" #define LED_GPIO_BLOCK 1 #define LED_GPIO_PIN 7 static inline void Delay(void) { for(int i = 0; i < 8000000; i++); } int main() { /**** LED setup ****/ // Enable clocking for GPIO1 (located on AHB bus) SYSCON->AHBCLKCTRLX[0] |= SYSCON_AHBCLKCTRL0_GPIO1_MASK; // Set direction for GPIO1 7 as output GPIO->DIR[LED_GPIO_BLOCK] |= GPIO_DIR_DIRP(1 << LED_GPIO_PIN); while(1) { /**** LED blinking ****/ GPIO->B[LED_GPIO_BLOCK][LED_GPIO_PIN] = 0; // Turn led On Delay(); GPIO->B[LED_GPIO_BLOCK][LED_GPIO_PIN] = 1; // Turn led off Delay(); } }
- , , , .
1
, . . , .
, 3, 5, 6, 9, 10 core0
core1
.
, , , GPIO1_4
:
#define LED_GPIO_PIN 7 --> #define LED_GPIO_PIN 4
. β¦ Reading CPU status failed
.
, , LPC55S69 . 0 , 1 β . 1 0 :
- 1.
- , 1 .
- 1.
- reset 1.
0 :
// Sequence required to be written
// to SYSCON->CPUCTRL register ORed with other bits
// to applay settings
// See UM11126 4.5.70 for more details
#define SYSCON_CPUCTRL_ENABLING_SEQ 0xC0C40000
// Warning!!! IAR specific code.
// core1_image_start is defined in
// LPC55S69_cm33_core0_flash.icf linker config file
extern unsigned char core1_image_start[];
#define CORE1_IMAGE_START core1_image_start
main()
1:
/**** CPU1 (slave) setup ****/
// Enable CPU1
SYSCON->CPUCFG |= SYSCON_CPUCFG_CPU1ENABLE_MASK;
// Setup firmware boot address
SYSCON->CPBOOT = SYSCON_CPBOOT_CPBOOT(CORE1_IMAGE_START);
// Enable clock and reset CPU1
SYSCON->CPUCTRL = SYSCON->CPUCTRL | SYSCON_CPUCTRL_ENABLING_SEQ |
SYSCON_CPUCTRL_CPU1RSTEN_MASK | SYSCON_CPUCTRL_CPU1CLKEN_MASK;
// Release reset for CPU1
SYSCON->CPUCTRL = (SYSCON->CPUCTRL | SYSCON_CPUCTRL_ENABLING_SEQ) &
(~SYSCON_CPUCTRL_CPU1RSTEN_MASK);
, 0.
1 . .
. . .
, :
- ( 1).
- . Converter > Output, Generate Additional Output Raw binary.
- Debugger > Download Verify Download. .
- .
- ( 0).
- Debugger > Multicore, Simple .
- Linker > Input . ( ).
_CPU1_image
, , 1,__sec_core
4
.
- . , . , .
IAR , .
Failed to synch with multicore partner
, . CPU1 CPU0.
The debugging session could not be started.
Either the debugger initialization filed, or else the file "iar_all_modules_loaded" was missing, corrupt or of an unsupported format.
, Verify download 3. , , .
: , , , , . . , 6 7. ( , ), , , . , .
SRAM
FLASH-. . . SRAM. FLASH-, SRAM . :
- ( 1).
- (Linker > Config)
LPC55S69_cm33_core1_flash.icf
LPC55S69_cm33_core1_ram.icf
. - .
- ( 0).
-
main.c
:
#include "string.h" // for memcpy
.- SRAM, 1.
// Address of RAM, where the image for CPU1 should be copied // According to UM11126 2.1.5 it is SRAM 3 on CM33 data bus #define CORE1_BOOT_ADDRESS (void *)0x20033000
- .
// Firmware image size calculation uint32_t get_core1_image_size(void) { uint32_t core1_image_size; #pragma section = "__sec_core" core1_image_size = (uint32_t)__section_end("__sec_core") - (uint32_t)&core1_image_start; return core1_image_size; }
- 1 FLASH- SRAM.
// Copy CPU1 image to an other SRAM block memcpy(CORE1_BOOT_ADDRESS, (void *)CORE1_IMAGE_START, get_core1_image_size());
- ( , ).
// Setup boot address SYSCON->CPBOOT = SYSCON_CPBOOT_CPBOOT(CORE1_BOOT_ADDRESS);
- 0, , .
, ( 2 7 ).
, . - MAILBOX
.
MAILBOX
, . .
/**** Mailbox setup for mutex ****/
// Enable mailbox clocking
SYSCON->AHBCLKCTRLX[0] |= SYSCON_AHBCLKCTRL0_MAILBOX_MASK;
- , , .
β , . .
// Try to acquire mutex
while (!(MAILBOX->MUTEX & MAILBOX_MUTEX_EX_MASK));
.
// Release mutex
MAILBOX->MUTEX = MAILBOX_MUTEX_EX_MASK;
.
, .
.
#include "LPC55S69_cm33_core0.h"
#include "string.h" // for memcpy
#define LED_GPIO_BLOCK 1
#define LED_GPIO_PIN 7
// Address of RAM, where the image for CPU1 should be copied
// According to UM11126 2.1.5 it is SRAM 3 on CM33 data bus
#define CORE1_BOOT_ADDRESS (void *) 0x20033000
// Sequence required to be written
// to SYSCON->CPUCTRL register ORed with other bits
// to applay settings
// See UM11126 4.5.70 for more details
#define SYSCON_CPUCTRL_ENABLING_SEQ 0xC0C40000
// Warning!!! IAR specific code.
// core1_image_start is defined in
// LPC55S69_cm33_core0_flash.icf linker config file
extern unsigned char core1_image_start[];
#define CORE1_IMAGE_START core1_image_start
static inline void Delay(void)
{
for(int i = 0; i < 8000000; i++);
}
// Firmware image size calculation
uint32_t get_core1_image_size(void)
{
uint32_t core1_image_size;
#pragma section = "__sec_core"
core1_image_size = (uint32_t)__section_end("__sec_core") -
(uint32_t)&core1_image_start;
return core1_image_size;
}
int main()
{
/**** LED setup ****/
// Enable clocking for GPIO1 (located on AHB bus)
SYSCON->AHBCLKCTRLX[0] |= SYSCON_AHBCLKCTRL0_GPIO1_MASK;
// Set direction for GPIO1 7 as output
GPIO->DIR[LED_GPIO_BLOCK] |= GPIO_DIR_DIRP(1 << LED_GPIO_PIN);
/**** Mailbox setup for mutex ****/
// Enable mailbox clocking
SYSCON->AHBCLKCTRLX[0] |= SYSCON_AHBCLKCTRL0_MAILBOX_MASK;
/**** CPU1 (slave) setup ****/
// Copy CPU1 image to an other SRAM block
memcpy(CORE1_BOOT_ADDRESS, (void *)CORE1_IMAGE_START, get_core1_image_size());
// Enable CPU1
SYSCON->CPUCFG |= SYSCON_CPUCFG_CPU1ENABLE_MASK;
// Setup firmware boot address
SYSCON->CPBOOT = SYSCON_CPBOOT_CPBOOT(CORE1_BOOT_ADDRESS);
// Enable clock and reset CPU1
SYSCON->CPUCTRL = SYSCON->CPUCTRL | SYSCON_CPUCTRL_ENABLING_SEQ |
SYSCON_CPUCTRL_CPU1RSTEN_MASK | SYSCON_CPUCTRL_CPU1CLKEN_MASK;
// Release reset for CPU1
SYSCON->CPUCTRL = (SYSCON->CPUCTRL | SYSCON_CPUCTRL_ENABLING_SEQ) &
(~SYSCON_CPUCTRL_CPU1RSTEN_MASK);
while(1)
{
/**** LED blinking ****/
while (!(MAILBOX->MUTEX & MAILBOX_MUTEX_EX_MASK)); // Try to acquire mutex
GPIO->B[LED_GPIO_BLOCK][LED_GPIO_PIN] = 0; // Turn led On
Delay();
GPIO->B[LED_GPIO_BLOCK][LED_GPIO_PIN] = 1; // Turn led off
MAILBOX->MUTEX = MAILBOX_MUTEX_EX_MASK; // Release mutex
Delay();
}
}
#include "LPC55S69_cm33_core1.h"
#define LED_GPIO_BLOCK 1
#define LED_GPIO_PIN 4
static inline void Delay(void)
{
for(int i = 0; i < 8000000; i++);
}
int main()
{
/**** LED setup ****/
// Enable clocking for GPIO1 (located on AHB bus)
SYSCON->AHBCLKCTRLX[0] |= SYSCON_AHBCLKCTRL0_GPIO1_MASK;
// Set direction for GPIO1 7 as output
GPIO->DIR[LED_GPIO_BLOCK] |= GPIO_DIR_DIRP(1 << LED_GPIO_PIN);
/**** Mailbox setup for mutex ****/
// Enable mailbox clocking
SYSCON->AHBCLKCTRLX[0] |= SYSCON_AHBCLKCTRL0_MAILBOX_MASK;
while(1)
{
/**** LED blinking ****/
while (!(MAILBOX->MUTEX & MAILBOX_MUTEX_EX_MASK)); // Try to acquire mutex
GPIO->B[LED_GPIO_BLOCK][LED_GPIO_PIN] = 0; // Turn led On
Delay();
GPIO->B[LED_GPIO_BLOCK][LED_GPIO_PIN] = 1; // Turn led off
MAILBOX->MUTEX = MAILBOX_MUTEX_EX_MASK; // Release mutex
Delay();
}
}
:
- AN12335 NXP LPC55xx/LPC55Sxx Dual Core Communication
- AN5286 STM32H7x5 / x7 dual-core microcontroller debugging
- STM32H7 System Hardware Semaphore (HSEM)
- IAR Multicore debugging
- AN215656 Cypress PSoC 6 MCU Dual-CPU System Design
- RM0399 STM32H745 / 755 and STM32H747 / 757 advanced Arm-based
32-bit MCUs Reference manual - Cypress CY8C6xx5 Architecture Technical Reference Manual (TRM)
- UM11126 NXP LPC55S6x / LPC55S2x / LPC552x User manual