Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable stm32 core coupled memory #897

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added cmake configuration option `AVM_CONFIG_REBOOT_ON_NOT_OK` for STM32
- New gpio driver for STM32 with nif and port support for read and write functions.
- Added support for interrupts to STM32 GPIO port driver.
- Enabled Core Coupled Memory on stm32 for VM stack, interrupt handler functions, and the .data and .bss segments

### Changed

- Moved GPIO interrupt handlers from flash to CCM for lower latency

## [0.6.0-alpha.1] - 2023-10-09

Expand Down
2 changes: 1 addition & 1 deletion src/platforms/stm32/cmake/libopencm3.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ JOIN("${ARCH_FLAGS}" " " ARCH_FLAGS)
string(REPLACE " " ";" ARCH_FLAGS ${ARCH_FLAGS})
# ------------------
execute_process(
COMMAND ${ARM_CXX} ${ARCH_FLAGS} ${GENLINK_DEFS} "-P" "-E" "${LIBOPENCM3_DIR}/ld/linker.ld.S"
COMMAND ${ARM_CXX} ${ARCH_FLAGS} ${GENLINK_DEFS} "-P" "-E" "${CMAKE_SOURCE_DIR}/ld/linker.ld.S"
OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${LINKER_SCRIPT}"
)
message("-----------Target Specific Info---------")
Expand Down
211 changes: 211 additions & 0 deletions src/platforms/stm32/ld/linker.ld.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
* Copyright (C) 2013 Frantisek Burian <BuFran@seznam.cz>
*
* This file is customized for AtomVM.
*
* Copyright (C) 2023 Winford (Uncle Grumpy) <winford@object.stream>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have an issue distributing this under the Apache 2.0 license? I am not sure what the implications are of this. @bettio any thoughts?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to avoid (L)GPL only sources, in order to keep licensing simple.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then maybe we really need to consider basing this port on something other than libopencm3 as it is licensed under GPL-3.0, LGPL-3.0 licenses.

* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tag is wrong anyway I think.

*/

/* Generic linker script for all targets using libopencm3. */

/* Enforce emmition of the vector table. */
EXTERN(vector_table)

/* Define the entry point of the output file. */
ENTRY(reset_handler)

/* Define memory regions. */
MEMORY
{
/* RAM is always used */
ram (rwx) : ORIGIN = _RAM_OFF, LENGTH = _RAM

#if defined(_ROM)
rom (rx) : ORIGIN = _ROM_OFF, LENGTH = _ROM
#endif
#if defined(_ROM1)
rom1 (rx) : ORIGIN = _ROM1_OFF, LENGTH = _ROM1
#endif
#if defined(_ROM2)
rom2 (rx) : ORIGIN = _ROM2_OFF, LENGTH = _ROM2
#endif
#if defined(_RAM1)
ram1 (rwx) : ORIGIN = _RAM1_OFF, LENGTH = _RAM1
#endif
#if defined(_RAM2)
ram2 (rwx) : ORIGIN = _RAM2_OFF, LENGTH = _RAM2
#endif
#if defined(_RAM3)
ram3 (rwx) : ORIGIN = _RAM3_OFF, LENGTH = _RAM3
#endif
#if defined(_CCM)
ccm (rwx) : ORIGIN = _CCM_OFF, LENGTH = _CCM
#endif
#if defined(_EEP)
eep (r) : ORIGIN = _EEP_OFF, LENGTH = _EEP
#endif
#if defined(_XSRAM)
xsram (rw) : ORIGIN = _XSRAM_OFF, LENGTH = _XSRAM
#endif
#if defined(_XDRAM)
xdram (rw) : ORIGIN = _XDRAM_OFF, LENGTH = _XDRAM
#endif
#if defined(_NFCRAM)
nfcram (rw) : ORIGIN _NFCRAM_OFF, LENGTH = _NFCRAM
#endif
}

/* Define sections. */
SECTIONS
{
#if defined(_CCM)
.ccm : {
*(.ccmram*)
. = ALIGN(4);
} >ccm
#endif
.text : {
*(.vectors) /* Vector table */
*(.text*) /* Program code */
. = ALIGN(4);
*(.rodata*) /* Read-only data */
. = ALIGN(4);
} >rom

/* C++ Static constructors/destructors, also used for
* __attribute__((constructor)) and the likes.
*/
.preinit_array : {
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
} >rom
.init_array : {
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} >rom
.fini_array : {
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
} >rom

/*
* Another section used by C++ stuff, appears when using newlib with
* 64bit (long long) printf support
*/
.ARM.extab : {
*(.ARM.extab*)
} >rom
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >rom

. = ALIGN(4);
_etext = .;

.data : {
_data = .;
*(.data*) /* Read-write initialized data */
. = ALIGN(4);
_edata = .;
#if defined(_CCM)
} >ccm AT >rom
#else
} >ram AT >rom
#endif
_data_loadaddr = LOADADDR(.data);

.bss : {
*(.bss*) /* Read-write zero initialized data */
*(COMMON)
. = ALIGN(4);
_ebss = .;
#if defined(_CCM)
} >ccm
#else
} >ram
#endif
#if defined(_RAM1)
.ram1 : {
*(.ram1*)
. = ALIGN(4);
} >ram1
#endif

#if defined(_RAM2)
.ram2 : {
*(.ram2*)
. = ALIGN(4);
} >ram2
#endif

#if defined(_RAM3)
.ram3 : {
*(.ram3*)
. = ALIGN(4);
} >ram3
#endif

#if defined(_XSRAM)
.xsram : {
*(.xsram*)
. = ALIGN(4);
} >xsram
#endif

#if defined(_XDRAM)
.xdram : {
*(.xdram*)
. = ALIGN(4);
} >xdram
#endif

#if defined(_NFCRAM)
.nfcram : {
*(.nfcram*)
. = ALIGN(4);
} >nfcram
#endif

/*
* The .eh_frame section appears to be used for C++ exception handling.
* You may need to fix this if you're using C++.
*/
/DISCARD/ : { *(.eh_frame) }

. = ALIGN(4);
end = .;
}

#if defined(_CCM)
PROVIDE(_stack = ORIGIN(ccm) + LENGTH(ccm));
#else
PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));
#endif
14 changes: 7 additions & 7 deletions src/platforms/stm32/src/lib/gpio_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,42 +590,42 @@ void isr_handler(Context *ctx, uint32_t exti)
}
}

void exti0_isr()
void __attribute__((section("ccm"))) exti0_isr()
{
exti_reset_request(EXTI0);
TRACE("gpio_driver: exti0 interrupt triggered.\n");
isr_handler(NULL, EXTI0);
}

void exti1_isr()
void __attribute__((section("ccm"))) exti1_isr()
{
exti_reset_request(EXTI1);
TRACE("gpio_driver: exti1 interrupt triggered\n");
isr_handler(NULL, EXTI1);
}

void exti2_isr()
void __attribute__((section("ccm"))) exti2_isr()
{
exti_reset_request(EXTI2);
TRACE("gpio_driver: exti2 interrupt triggered\n");
isr_handler(NULL, EXTI2);
}

void exti3_isr()
void __attribute__((section("ccm"))) exti3_isr()
{
exti_reset_request(EXTI3);
TRACE("gpio_driver: exti3 interrupt triggered\n");
isr_handler(NULL, EXTI3);
}

void exti4_isr()
void __attribute__((section("ccm"))) exti4_isr()
{
exti_reset_request(EXTI4);
TRACE("gpio_driver: exti4 interrupt triggered\n");
isr_handler(NULL, EXTI4);
}

void exti9_5_isr()
void __attribute__((section("ccm"))) exti9_5_isr()
{
if (exti_get_flag_status(EXTI5) == EXTI5) {
exti_reset_request(EXTI5);
Expand All @@ -652,7 +652,7 @@ void exti9_5_isr()
}
}

void exti15_10_isr()
void __attribute__((section("ccm"))) exti15_10_isr()
{
if (exti_get_flag_status(EXTI10)) {
exti_reset_request(EXTI10);
Expand Down
2 changes: 1 addition & 1 deletion src/platforms/stm32/src/lib/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct NifCollectionDefListItem *nif_collection_list;
static volatile uint64_t system_millis;

// Called when systick fires
void sys_tick_handler()
void __attribute__((section("ccm"))) sys_tick_handler()
{
system_millis++;
}
Expand Down