I want to extend my application with a second core. I can't flash any code onto the second core. Only the first core gets updated when debugging.
First I tried creating a simple 3-core LED blink project and it worked fine (I had problems with uploading the code to the cores, but finally I found a workaround: I created a launch group with all the cores, and this way managed to flash code to all cores simultaneously).
I went on to the next step: I imported an example from NXP (the one that uses the LWIP stack, it is a single-core application), renamed it, and then tried to add a new project that has code for the Z2_2 core. This was impossible - you can't create a new project ONLY for the Z2_2 core. So, I created a regular project with 3 cores, and then created a debug launch group for 3 cores combining the NXP example and the new core in this way:
- Z4_0 uses the LWIP .elf from the NXP example
- Z4_1 uses the newly created code for the second core (Z4_1.elf)
- Z2_2 uses the newly created code for the third core (Z2_2.elf)
Then I tried debugging the launch group.
Unfortunately, this setup doesn't work - the debugger shows that Z4_1 and Z2_2 cores are "Running: User Request", but the code from these cores is not being executed - breakpoints set in main.c on the Z2_2 are never called, the pins are never initialized. The code for the first core runs fine - the application programed on the first core works. No errors are being shown. The other cores simply don't get flashed.
How to program the second and third core?
(I am using freeRTOS on all of the cores. Each core uses 256kB of SRAM, and the memory is correctly mapped in linker.flash for each core. The OpenSDA debugger can be only set to Z4_0, the other cores have their choice of debugger grayed out. By debugging, in the brackets, PE micro debugger is set. Using the same setup for RUN launch group results in the same behavior).
Hi,
Only the boot core Z4_0 debug configuration physically program the binary for all the cores.
Therefore it contains two additional (the other cores) elf files in its debug configuration:
In order to debug multicore project (step the other cores code) your boot core should initialize and start the other cores.
You can add and execute code like below into your boot core. Please replace the start addresses for the other cores to fit your project:
void hw_init(void)
{
#if defined(DEBUG_SECONDARY_CORES)
uint32_t mctl = MC_ME.MCTL.R;
#if defined(TURN_ON_CPU1)
/* enable core 1 in all modes */
MC_ME.CCTL[2].R = 0x00FE;
/* Set Start address for core 1: Will reset and start */
#if defined(START_FROM_FLASH)
MC_ME.CADDR[2].R = 0x11d0000 | 0x1;
#else
MC_ME.CADDR[2].R = 0x40040000 | 0x1;
#endif /* defined(START_FROM_FLASH) */
#endif
#if defined(TURN_ON_CPU2)
/* enable core 2 in all modes */
MC_ME.CCTL[3].R = 0x00FE;
/* Set Start address for core 2: Will reset and start */
#if defined(START_FROM_FLASH)
MC_ME.CADDR[3].R = 0x13a0000 | 0x1;
#else
MC_ME.CADDR[3].R = 0x40080000 | 0x1;
#endif /* defined(START_FROM_FLASH) */
#endif
MC_ME.MCTL.R = (mctl & 0xffff0000ul) | KEY_VALUE1;
MC_ME.MCTL.R = mctl; /* key value 2 always from MCTL */
#endif /* defined(DEBUG_SECONDARY_CORES) */
}
After you execute it all 3 cores are active and you should be able to debug them all.
For the relase project you don't need this code and the cores shall be automatically started according to rchw configuration (see the reference manual for more details).
Hope it helps.
Stan
I managed to adjust the code you provided to fit my project. I also figured out, that the "DEBUG_SECONDARY_CORES" and other defines can be set up as compiler flags in Project Settings->C/C++ Build -> Settings->Preprocessor.
I tried two solutions:
1. including the TURN_ON_CPU1, TURN_ON_CPU2 and DEBUG_SECONDARY_CORES into compiler variables, so that my SDK/platform/devices/MPC5748g/startup/system_MPC5748G.c sets up the other cores automatically;
2. writing my own hw_init() function (included below)
Unfortunately, both approaches fail: this time the second (Z4_1) and third core (Z2_2) run, however the first core freezes.
Furthermore, debugging session does not start anymore (when debugging a launch configuration that includes all the cores). The first core, when flashed alone, works.
My hw_init():
void my_hw_init3(){
/* Enable e200z4b and e200z2 cores in RUN0-RUN3, DRUN and SAFE modes */
MC_ME->CCTL2 = 0x00FC; /* e200z4b is active */
MC_ME->CCTL3 = 0x00FC; /* e200z2 is active */
#if defined(TURN_ON_CPU1)
#if defined(START_FROM_FLASH)
MC_ME->CADDR2 = 0x11d0000 | 0x1;
#else
MC_ME->CADDR2 = 0x40040000 | 0x1;
#endif //start from flash
#endif //TURN ON CPU1
#if defined(TURN_ON_CPU2)
#if defined(START_FROM_FLASH)
MC_ME->CADDR3 = 0x13a0000 | 0x1;
#else
MC_ME->CADDR3 = 0x40080000 | 0x1;
#endif //start from flash
#endif //TURN ON CPU2
/* Mode change - re-enter the DRUN mode to start cores */
MC_ME->MCTL = 0x30005AF0; /* Mode & Key */
MC_ME->MCTL = 0x3000A50F; /* Mode & Key inverted */
}
thank you very much for your suggestions. Few things however, are still not lcear for me.
1. Constants.
Where do I find the DEBUG_SECONDARY_CORES, TURN_ON_CPU1 and TURN_ON_CPU2 constants? I tried to search for them in different projects however, I can't find them declared anywhere. Should I declare them myself in main.c?
3. Registers
I can't make the code you provided fit in my project...
my MPC5748G.h has the following definitions:
/** MC_ME - Register Layout Typedef */
typedef struct {
__IO uint32_t MCTL; /**< Mode Control Register, offset: 0x4 */
} MC_ME_Type, *MC_ME_MemMapPtr;
/** Peripheral MC_ME base address */
#define MC_ME_BASE (0xFFFB8000u)
/** Peripheral MC_ME base pointer */
#define MC_ME ((MC_ME_Type *)MC_ME_BASE)
typedef struct {
__IO uint8_t GATE[SEMA42_GATE_COUNT]; /**< Gate Register, array offset: 0x0, array step: 0x1 */
uint8_t RESERVED_0[48];
union { /* offset: 0x40 */
__I uint16_t R; /**< Reset Gate Read, offset: 0x40 */
} RSTGT;
} SEMA42_Type, *SEMA42_MemMapPtr;
so the instructions you provided don't really fit.
For example:
uint32_t mctl = MC_ME.MCTL.R;
gives an error: request for member 'MCTL' in something not a structure or union.
The error can be partially fixed by addressing the MC_ME with a '->' operator but the MCTL is an int, and therefore has no 'R' element to it.
I would be grateful for any ideas how to solve this issue.