Skip to content
Snippets Groups Projects
Verified Commit 0df3f9d0 authored by rahix's avatar rahix
Browse files

feat: Add dual-core example


This dual-core example works by creating two separate elfs and
flashing them to different offsets.

Co-authored-by: default avatarschneider <schneider@blinkenlichts.net>
Signed-off-by: default avatarRahix <rahix@rahix.de>
parent e318b389
No related branches found
No related tags found
No related merge requests found
......@@ -61,6 +61,7 @@ Initialize the build-system by running `meson --cross-file card10-cross.ini buil
- `hw-tests/hello-world/hello-world.elf`
- `hw-tests/imutest/imutest.elf`
- `hw-tests/ips/ips.elf`
- `hw-tests/dual-core/dual-core{0,1}.elf`
## Flashing
Run `arm-none-eabi-gdb` in the applications folder. It should connect to OpenOCD and say something like:
......
../hello-world/Heart.h
\ No newline at end of file
#include "board.h"
#include "gpio.h"
#include "mxc_delay.h"
static const gpio_cfg_t motor_pin = {PORT_0, PIN_8, GPIO_FUNC_OUT, GPIO_PAD_NONE};
int main(void)
{
for (int i = 0; 1; i++) {
printf("Hello from core 1! %d\n", i);
#if 0
GPIO_OutSet(&motor_pin);
mxc_delay(30000);
GPIO_OutClr(&motor_pin);
#endif
mxc_delay(970000);
}
}
source ../../.gdbinit
set confirm off
echo Loading core1 image ...
file ../../build/hw-tests/dual-core/dual-core1.elf
load
echo Loading core0 image ...
file ../../build/hw-tests/dual-core/dual-core0.elf
load
reset
quit
/*******************************************************************************
* License: TBD
******************************************************************************/
/***** Includes *****/
#include "pmic.h"
#include "leds.h"
#include "card10.h"
#include "GUI_Paint.h"
#include "tmr_utils.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <Heart.h>
void Core1_Start(void) {
//MXC_GCR->gp0 = (uint32_t)(&__isr_vector_core1);
MXC_GCR->gp0 = 0x10040000;
MXC_GCR->perckcn1 &= ~MXC_F_GCR_PERCKCN1_CPU1;
}
void Core1_Stop(void) {
MXC_GCR->perckcn1 |= MXC_F_GCR_PERCKCN1_CPU1;
}
int main(void)
{
card10_init();
card10_diag();
Paint_DrawImage(Heart, 0, 0, 160, 80);
LCD_Update();
for(int i=0; i<11; i++) {
leds_set_dim(i, 1);
}
int h = 0;
// Release core1
Core1_Start();
while (1) {
#define NUM 15
for(int i=0; i<NUM; i++) {
if(i < 12) {
leds_set_hsv(i, (h + 360/NUM * i) % 360, 1., 1./8);
} else {
leds_set_hsv(i, (h + 360/NUM * i) % 360, 1., 1.);
}
}
leds_update();
TMR_Delay(MXC_TMR0, MSEC(10), 0);
h++;
}
}
name = 'dual-core0'
executable(
name + '.elf',
'main.c',
dependencies: [libcard10, max32665_startup_core0],
link_args: [
'-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
],
)
name = 'dual-core1'
executable(
name + '.elf',
'core1.c',
dependencies: [periphdriver, board_card10, max32665_startup_core1],
link_args: [
'-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
],
)
subdir('bmatest/')
subdir('bmetest/')
subdir('dual-core/')
subdir('ecgtest/')
subdir('hello-freertos/')
subdir('hello-world/')
......
/*******************************************************************************
* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*
* $Date: 2018-12-03 22:29:43 +0000 (Mon, 03 Dec 2018) $
* $Revision: 39576 $
*
******************************************************************************/
/* SPID and SPIX Sections here are maximum possible sizes */
/* If used, they should be adjusted for the external Flash/RAM size */
MEMORY {
SPIX (rx) : ORIGIN = 0x08000000, LENGTH = 128M
FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 256k
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256k
SPID (r) : ORIGIN = 0x80000000, LENGTH = 512M
}
SECTIONS {
.text :
{
_text = .;
KEEP(*(.isr_vector))
*(.text*) /* program code */
*(.rodata*) /* read-only data: "const" */
KEEP(*(.init))
KEEP(*(.fini))
/* C++ Exception handling */
KEEP(*(.eh_frame*))
_etext = .;
} > FLASH
/* This section will keep the SPIX data until loaded into the external device */
/* Upon initialization of SPIX (user code needs to do this) */
.xip_section :
{
KEEP(*(.xip_section*))
} > SPIX AT>FLASH
__load_start_xip = LOADADDR(.xip_section);
__load_length_xip = SIZEOF(.xip_section);
/* it's used for C++ exception handling */
/* we need to keep this to avoid overlapping */
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > FLASH
.data :
{
_data = ALIGN(., 4);
*(.data*) /*read-write initialized data: initialized global variable*/
*(.spix_config*) /* SPIX configuration functions need to be run from SRAM */
*(.flashprog*) /* Flash program */
/* These array sections are used by __libc_init_array to call static C++ constructors */
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
_edata = ALIGN(., 4);
} > SRAM AT>FLASH
__load_data = LOADADDR(.data);
.bss :
{
. = ALIGN(4);
_bss = .;
*(.bss*) /*read-write zero initialized data: uninitialzed global variable*/
*(COMMON)
_ebss = ALIGN(., 4);
} > SRAM
/* Setup the stack for Core 1, it will only be used if the user code
* includes a definition of Stack_Size_Core1, which defines the space
* reserved above the main core's stack for core 1's stack */
__StackTop_Core1 = ORIGIN(SRAM) + LENGTH(SRAM);
__StackLimit_Core1 = DEFINED(Stack_Size_Core1) ? __StackTop_Core1 - Stack_Size_Core1 : __StackTop_Core1;
/* Set stack top to end of RAM, and stack limit move down by Stack_Size.
* If core 1 is used, set the stack to the bottom of Core 1's stack region */
__StackTop = DEFINED(Stack_Size_Core1) ? __StackLimit_Core1 : ORIGIN(SRAM) + LENGTH(SRAM);
__StackLimit = __StackTop - Stack_Size;
.heap (COPY):
{
. = ALIGN(4);
*(.heap*)
__HeapLimit = ABSOLUTE(__StackLimit);
} > SRAM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack(s) exceeds RAM limit */
ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack")
}
/*******************************************************************************
* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*
* $Date: 2018-12-03 22:29:43 +0000 (Mon, 03 Dec 2018) $
* $Revision: 39576 $
*
******************************************************************************/
/* SPID and SPIX Sections here are maximum possible sizes */
/* If used, they should be adjusted for the external Flash/RAM size */
MEMORY {
SPIX (rx) : ORIGIN = 0x08000000, LENGTH = 128M
FLASH (rx) : ORIGIN = 0x10040000, LENGTH = 256k
SRAM (rwx) : ORIGIN = 0x20040000, LENGTH = 256k
SPID (r) : ORIGIN = 0x80000000, LENGTH = 512M
}
SECTIONS {
.text :
{
_text = .;
KEEP(*(.isr_vector))
*(.text*) /* program code */
*(.rodata*) /* read-only data: "const" */
KEEP(*(.init))
KEEP(*(.fini))
/* C++ Exception handling */
KEEP(*(.eh_frame*))
_etext = .;
} > FLASH
/* This section will keep the SPIX data until loaded into the external device */
/* Upon initialization of SPIX (user code needs to do this) */
.xip_section :
{
KEEP(*(.xip_section*))
} > SPIX AT>FLASH
__load_start_xip = LOADADDR(.xip_section);
__load_length_xip = SIZEOF(.xip_section);
/* it's used for C++ exception handling */
/* we need to keep this to avoid overlapping */
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > FLASH
.data :
{
_data = ALIGN(., 4);
*(.data*) /*read-write initialized data: initialized global variable*/
*(.spix_config*) /* SPIX configuration functions need to be run from SRAM */
*(.flashprog*) /* Flash program */
/* These array sections are used by __libc_init_array to call static C++ constructors */
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
_edata = ALIGN(., 4);
} > SRAM AT>FLASH
__load_data = LOADADDR(.data);
.bss :
{
. = ALIGN(4);
_bss = .;
*(.bss*) /*read-write zero initialized data: uninitialzed global variable*/
*(COMMON)
_ebss = ALIGN(., 4);
} > SRAM
/* Setup the stack for Core 1, it will only be used if the user code
* includes a definition of Stack_Size_Core1, which defines the space
* reserved above the main core's stack for core 1's stack */
__StackTop_Core1 = ORIGIN(SRAM) + LENGTH(SRAM);
__StackLimit_Core1 = DEFINED(Stack_Size_Core1) ? __StackTop_Core1 - Stack_Size_Core1 : __StackTop_Core1;
/* Set stack top to end of RAM, and stack limit move down by Stack_Size.
* If core 1 is used, set the stack to the bottom of Core 1's stack region */
__StackTop = DEFINED(Stack_Size_Core1) ? __StackLimit_Core1 : ORIGIN(SRAM) + LENGTH(SRAM);
__StackLimit = __StackTop - Stack_Size;
.heap (COPY):
{
. = ALIGN(4);
*(.heap*)
__HeapLimit = ABSOLUTE(__StackLimit);
} > SRAM
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack(s) exceeds RAM limit */
ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack")
}
/*******************************************************************************
* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*
* $Date: 2018-11-07 19:23:01 +0000 (Wed, 07 Nov 2018) $
* $Revision: 39007 $
*
******************************************************************************/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "max32665.h"
#include "mxc_sys.h"
#include "gcr_regs.h"
#include "icc_regs.h"
#include "pwrseq_regs.h"
// Backup mode entry point
extern void Reset_Handler(void);
extern void (* const __isr_vector[])(void);
// Part defaults to HIRC/2 out of reset
uint32_t SystemCoreClock = HIRC_FREQ >> 1;
__weak void SystemCoreClockUpdate(void)
{
uint32_t base_freq, div, clk_src;
// Determine the clock source and frequency
clk_src = (MXC_GCR->clkcn & MXC_F_GCR_CLKCN_CLKSEL);
switch (clk_src)
{
case MXC_S_GCR_CLKCN_CLKSEL_HIRC:
base_freq = HIRC_FREQ;
break;
case MXC_S_GCR_CLKCN_CLKSEL_XTAL32M:
base_freq = XTAL32M_FREQ;
break;
case MXC_S_GCR_CLKCN_CLKSEL_LIRC8:
base_freq = LIRC8_FREQ;
break;
case MXC_S_GCR_CLKCN_CLKSEL_HIRC96:
base_freq = HIRC96_FREQ;
break;
case MXC_S_GCR_CLKCN_CLKSEL_HIRC8:
base_freq = HIRC8_FREQ;
break;
case MXC_S_GCR_CLKCN_CLKSEL_XTAL32K:
base_freq = XTAL32K_FREQ;
break;
default:
// Values 001 and 111 are reserved, and should never be encountered.
base_freq = HIRC_FREQ;
break;
}
// Clock divider is retrieved to compute system clock
div = (MXC_GCR->clkcn & MXC_F_GCR_CLKCN_PSC) >> MXC_F_GCR_CLKCN_PSC_POS;
SystemCoreClock = base_freq >> div;
}
/* This function is called before C runtime initialization and can be
* implemented by the application for early initializations. If a value other
* than '0' is returned, the C runtime initialization will be skipped.
*
* You may over-ride this function in your program by defining a custom
* PreInit(), but care should be taken to reproduce the initialization steps
* or a non-functional system may result.
*/
__weak int PreInit(void)
{
// Do nothing
return 0;
}
// This function can be implemented by the application to initialize the board
__weak int Board_Init(void)
{
// Do nothing
return 0;
}
/* This function is called just before control is transferred to main().
*
* You may over-ride this function in your program by defining a custom
* SystemInit(), but care should be taken to reproduce the initialization
* steps or a non-functional system may result.
*/
__weak void SystemInit(void)
{
/* Configure the interrupt controller to use the application vector
* table in flash. Initially, VTOR points to the ROM's table.
*/
SCB->VTOR = (unsigned long)&__isr_vector;
/* Enable FPU on Cortex-M4, which occupies coprocessor slots 10 & 11
* Grant full access, per "Table B3-24 CPACR bit assignments".
* DDI0403D "ARMv7-M Architecture Reference Manual"
*/
SCB->CPACR |= SCB_CPACR_CP10_Msk | SCB_CPACR_CP11_Msk;
__DSB();
__ISB();
// Enable ICache1 Clock
MXC_GCR->perckcn1 &= ~(1 << 22);
// Invalidate cache and wait until ready
MXC_ICC1->invalidate = 1;
while (!(MXC_ICC1->cache_ctrl & MXC_F_ICC_CACHE_CTRL_CACHE_RDY));
// Enable Cache
MXC_ICC1->cache_ctrl |= MXC_F_ICC_CACHE_CTRL_CACHE_EN;
SystemCoreClockUpdate();
// No board init on core1
//Board_Init();
}
#############################################################
# For applications using just core0 or not dual-binaries
#############################################################
sources = files(
'./Source/GCC/startup_max32665.S',
'./Source/system_max32665.c',
......@@ -17,3 +21,51 @@ max32665_startup = declare_dependency(
'--entry', 'Reset_Handler',
],
)
#############################################################
# For core0 applications with dual-binaries
#############################################################
sources = files(
'./Source/GCC/startup_max32665.S',
'./Source/system_max32665.c',
'./Source/heap.c',
)
lib = static_library(
'max32665-startup-core0',
sources,
dependencies: periphdriver,
)
max32665_startup_core0 = declare_dependency(
link_whole: lib,
link_args: [
'-T', meson.current_source_dir() + 'Source/GCC/max32665_core0.ld',
'--entry', 'Reset_Handler',
],
)
#############################################################
# For core1 applications with dual-binaries
#############################################################
sources = files(
'./Source/GCC/startup_max32665.S',
'./Source/system_max32665_core1.c',
'./Source/heap.c',
)
lib = static_library(
'max32665-startup-core1',
sources,
dependencies: periphdriver,
)
max32665_startup_core1 = declare_dependency(
link_whole: lib,
link_args: [
'-T', meson.current_source_dir() + 'Source/GCC/max32665_core1.ld',
'--entry', 'Reset_Handler',
],
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment