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

RPC/OpenAMP: Support loading sketches to SDRAM. #934

Merged
merged 5 commits into from
Sep 9, 2024
Merged
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
373 changes: 373 additions & 0 deletions libraries/RPC/LICENSE

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions libraries/RPC/src/RPC.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2024 Arduino SA
// SPDX-License-Identifier: MPL-2.0
#include "RPC.h"

#define ENDPOINT_ID_RAW 0
Expand Down Expand Up @@ -161,6 +163,35 @@ int RPCClass::begin() {
#endif

#ifdef CORE_CM4
#if (CM4_BINARY_START >= 0x60000000) && (CM4_BINARY_START < 0xe0000000)
class M4Init {
public:
M4Init() {
// If the Cortex-M4 core is booting from SDRAM, the memory region must be
// configured as Strongly Ordered. Note that the Cortex-M4 core does not
// seem to implement speculative prefetching, so there is no need to protect
// the whole region from speculative prefetching with a second MPU region.
HAL_MPU_Disable();
MPU_Region_InitTypeDef MPU_InitStruct;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = CM4_BINARY_START;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.SubRegionDisable = 0x00;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
};

M4Init __m4init __attribute__ ((init_priority (101)));
#endif

int RPCClass::begin() {
eventThread = new rtos::Thread(osPriorityHigh, 16*1024, nullptr, "rpc_evt");
eventThread->start(&eventHandler);
Expand Down
2 changes: 2 additions & 0 deletions libraries/RPC/src/RPC.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2024 Arduino SA
// SPDX-License-Identifier: MPL-2.0
#ifdef __cplusplus

#ifndef __ARDUINO_RPC_IMPLEMENTATION__
Expand Down
2 changes: 2 additions & 0 deletions libraries/RPC/src/RPC_client.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2024 Arduino SA
// SPDX-License-Identifier: MPL-2.0
#include "Arduino.h"
#include "mbed.h"
#include "rpc/dispatcher.h"
Expand Down
4 changes: 3 additions & 1 deletion libraries/RPC/src/SerialRPC.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2024 Arduino SA
// SPDX-License-Identifier: MPL-2.0
#include "SerialRPC.h"
#include "RPC.h"

Expand All @@ -22,4 +24,4 @@ arduino::SerialRPCClass::operator bool() {
return RPC;
}

arduino::SerialRPCClass SerialRPC;
arduino::SerialRPCClass SerialRPC;
4 changes: 3 additions & 1 deletion libraries/RPC/src/SerialRPC.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2024 Arduino SA
// SPDX-License-Identifier: MPL-2.0
#ifndef __SERIAL_RPC__
#define __SERIAL_RPC__

Expand Down Expand Up @@ -69,4 +71,4 @@ class SerialRPCClass : public Stream {

extern arduino::SerialRPCClass SerialRPC;

#endif
#endif
3 changes: 3 additions & 0 deletions libraries/openamp_arduino/src/openamp_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ extern int __OPENAMP_region_end__[];
#define SHM_START_ADDRESS ((metal_phys_addr_t)__OPENAMP_region_start__)
#define SHM_SIZE (size_t)((void *)__OPENAMP_region_end__ - (void *) __OPENAMP_region_start__)

#define SHM_RSC_SIZE (1024)
#define SHM_RSC_ADDR ((void *)__OPENAMP_region_start__ - SHM_RSC_SIZE)

#endif

#define VRING_RX_ADDRESS SHM_START_ADDRESS
Expand Down
167 changes: 44 additions & 123 deletions libraries/openamp_arduino/src/rsc_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,137 +21,58 @@
******************************************************************************
*/

/** @addtogroup RSC_TABLE
* @{
*/

/** @addtogroup resource_table
* @{
*/

/** @addtogroup resource_table_Private_Includes
* @{
*/


#if defined(__ICCARM__) || defined (__CC_ARM)
#include <stddef.h> /* needed for offsetof definition*/
#endif
#include "rsc_table.h"
#include "openamp/open_amp.h"

/**
* @}
*/

/** @addtogroup resource_table_Private_TypesDefinitions
* @{
*/

/**
* @}
*/

/** @addtogroup resource_table_Private_Defines
* @{
*/

/* Place resource table in special ELF section */
#if defined(__GNUC__)
#define __section_t(S) __attribute__((__section__(#S)))
#define __resource __section_t(.resource_table)
#endif

#define RPMSG_IPU_C0_FEATURES 1
#define VRING_COUNT 2

/* VirtIO rpmsg device id */
#define VIRTIO_ID_RPMSG_ 7

#if defined (__LOG_TRACE_IO_)
extern char system_log_buf[];
#endif

#if defined(__GNUC__)
#if !defined (__CC_ARM)
/* Since GCC is not initializing the resource_table at startup, it is declared as volatile to avoid compiler optimization
* for the CM4 (see resource_table_init() below)
*/
volatile struct shared_resource_table __resource __attribute__((used)) resource_table;
#else
struct shared_resource_table __resource __attribute__((used)) resource_table = {
#endif
#elif defined(__ICCARM__)
__root struct shared_resource_table resource_table @ ".resource_table" = {
#endif

#if defined(__ICCARM__) || defined (__CC_ARM)
.version = 1,
.num = 2,
.reserved = {0, 0},
.offset = {
offsetof(struct shared_resource_table, vdev),
offsetof(struct shared_resource_table, cm_trace),
},

/* Virtio device entry */
.vdev= {
RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0,
VRING_COUNT, {0, 0},
},

/* Vring rsc entry - part of vdev rsc entry */
.vring0 = {VRING_TX_ADDRESS, VRING_ALIGNMENT, VRING_NUM_BUFFS, VRING0_ID, 0},
.vring1 = {VRING_RX_ADDRESS, VRING_ALIGNMENT, VRING_NUM_BUFFS, VRING1_ID, 0},

#if defined (__LOG_TRACE_IO_)
.cm_trace = {
RSC_TRACE,
(uint32_t)system_log_buf, SYSTEM_TRACE_BUF_SZ, 0, "cm4_log",
},
#endif
} ;
#endif

void resource_table_init(int RPMsgRole, void **table_ptr, int *length)
{

#if defined (__GNUC__) && ! defined (__CC_ARM)
#ifdef CORE_CM7
/*
* Currently the GCC linker doesn't initialize the resource_table global variable at startup
* it is done here by the CM7 application.
*/
memset(&resource_table, '\0', sizeof(struct shared_resource_table));
resource_table.num = 1;
resource_table.version = 1;
resource_table.offset[0] = offsetof(struct shared_resource_table, vdev);

resource_table.vring0.da = VRING_TX_ADDRESS;
resource_table.vring0.align = VRING_ALIGNMENT;
resource_table.vring0.num = VRING_NUM_BUFFS;
resource_table.vring0.notifyid = VRING0_ID;

resource_table.vring1.da = VRING_RX_ADDRESS;
resource_table.vring1.align = VRING_ALIGNMENT;
resource_table.vring1.num = VRING_NUM_BUFFS;
resource_table.vring1.notifyid = VRING1_ID;


resource_table.vdev.type = RSC_VDEV;
resource_table.vdev.id = VIRTIO_ID_RPMSG_;
resource_table.vdev.num_of_vrings=VRING_COUNT;
resource_table.vdev.dfeatures = RPMSG_IPU_C0_FEATURES;
#else
/* For CM4 let's wait until the resource_table is correctly initialized */
while(resource_table.vring1.da != VRING_RX_ADDRESS)
{

}
#endif
#endif

(void)RPMsgRole;
*length = sizeof(resource_table);
*table_ptr = &resource_table;
void resource_table_init(int RPMsgRole, void **table_ptr, int *length) {
(void)RPMsgRole;
volatile struct shared_resource_table *resource_table = SHM_RSC_ADDR;

#ifdef CORE_CM7
memset(resource_table, 0, SHM_RSC_SIZE);
resource_table->num = 1;
resource_table->version = 1;
resource_table->offset[0] = offsetof(struct shared_resource_table, vdev);
#if defined (__LOG_TRACE_IO_)
resource_table->offset[1] = offsetof(struct shared_resource_table, cm_trace);
#endif

resource_table->vring0.da = VRING_TX_ADDRESS;
resource_table->vring0.align = VRING_ALIGNMENT;
resource_table->vring0.num = VRING_NUM_BUFFS;
resource_table->vring0.notifyid = VRING0_ID;

resource_table->vring1.da = VRING_RX_ADDRESS;
resource_table->vring1.align = VRING_ALIGNMENT;
resource_table->vring1.num = VRING_NUM_BUFFS;
resource_table->vring1.notifyid = VRING1_ID;

#if defined (__LOG_TRACE_IO_)
resource_table->cm_trace.type;
resource_table->cm_trace.da;
resource_table->cm_trace.len;
resource_table->cm_trace.reserved = 0;
resource_table->cm_trace.name = (uint8_t[]){"cm_trace"};
#endif

resource_table->vdev.type = RSC_VDEV;
resource_table->vdev.id = VIRTIO_ID_RPMSG;
resource_table->vdev.num_of_vrings=VRING_COUNT;
resource_table->vdev.dfeatures = (1 << VIRTIO_RPMSG_F_NS);
#else
// For CM4, wait until the resource_table is initialized by the host
while(resource_table->vring1.da != VRING_RX_ADDRESS) {

}
#endif

*length = SHM_RSC_SIZE;
*table_ptr = resource_table;
}
40 changes: 19 additions & 21 deletions mbed-os-to-arduino
Original file line number Diff line number Diff line change
Expand Up @@ -187,31 +187,16 @@ generate_flags () {
echo "Patching '-fno-exceptions' flag for $ARDUINOVARIANT/${fl}flags.txt"
sed -i '/-fno-exceptions/d' "$ARDUINOVARIANT"/${fl}flags.txt
set +e
HAS_OPENAMP_SECTION=`grep openamp_section "$ARDUINOVARIANT"/linker_script.ld`
HAS_PDM_SECTION=`grep pdm_section "$ARDUINOVARIANT"/linker_script.ld`
set -e
if [ x"$HAS_OPENAMP_SECTION" == x ]; then
echo "Adding OpenAMP section to $ARDUINOVARIANT/linker_script.ld"
OPENAMP_SECTION=".openamp_section (NOLOAD) : {\n \
. = ABSOLUTE(0x38000000);\n \
*(.resource_table)\n \
} >RAM_D3 AT > FLASH\n \
.pdm_section (NOLOAD) : {\n \
. = ABSOLUTE(0x3800FC00);\n \
if [ x"$HAS_PDM_SECTION" == x ]; then
echo "Adding PDM section to $ARDUINOVARIANT/linker_script.ld"
PDM_SECTION=".pdm_section 0x3800FC00 (NOLOAD): {\n \
*(.pdm_buffer)\n \
} > RAM_D3\n"

if [[ $ARDUINOVARIANT == *GENERIC*M4 ]]; then
echo "Fixing VTOR base in $ARDUINOVARIANT/linker_script.ld"
VTOR_SECTION="#if (CM4_BINARY_START == 0x60000000)\n \
REGION_ALIAS(\"RAM\", FLASH);\n \
#else\n \
REGION_ALIAS(\"RAM\", RAM_D2);\n \
#endif\n"
sed -i "s?REGION_ALIAS.*?${VTOR_SECTION}?g" $ARDUINOVARIANT/linker_script.ld
fi

if [[ $ARDUINOVARIANT == *PORTENTA*M7* || $ARDUINOVARIANT == *GIGA* || $ARDUINOVARIANT == *OPTA* ]]; then
OPENAMP_SECTION="${OPENAMP_SECTION} \
PDM_SECTION="${PDM_SECTION} \
_dtcm_lma = __etext + SIZEOF(.data);\n \
.dtcm : AT(_dtcm_lma) {\n \
_sdtcm = .;\n \
Expand All @@ -220,9 +205,22 @@ generate_flags () {
} > DTCMRAM"
fi

sed -i "s?.heap (COPY):?${OPENAMP_SECTION}\n .heap (COPY):?g" $ARDUINOVARIANT/linker_script.ld
sed -i "s?.heap (COPY):?${PDM_SECTION}\n .heap (COPY):?g" $ARDUINOVARIANT/linker_script.ld
OPENAMP_REGIONS="__OPENAMP_region_start__ = 0x38000400;\n__OPENAMP_region_end__ = 0x38000400 + LENGTH(RAM_D3) - 1K;"
sed -i "s?ENTRY(Reset_Handler)?${OPENAMP_REGIONS}\nENTRY(Reset_Handler)?g" $ARDUINOVARIANT/linker_script.ld

if [[ $ARDUINOVARIANT == *GENERIC*M4 ]]; then
echo "Fixing VTOR base in $ARDUINOVARIANT/linker_script.ld"
VTOR_SECTION="#if (CM4_BINARY_START == 0x60000000)\n \
REGION_ALIAS(\"RAM\", FLASH);\n \
#else\n \
REGION_ALIAS(\"RAM\", RAM_D2);\n \
#endif\n"
sed -i "s?REGION_ALIAS.*?${VTOR_SECTION}?g" $ARDUINOVARIANT/linker_script.ld
echo "Fixing shared memory attributes in $ARDUINOVARIANT/linker_script.ld"
sed -i "s?.heap (COPY)?.heap (NOLOAD)?g" $ARDUINOVARIANT/linker_script.ld
sed -i "s?.stack_dummy (COPY)?.stack_dummy (NOLOAD)?g" $ARDUINOVARIANT/linker_script.ld
fi
fi
echo "Patching linker scripts"
sed -i 's/0x8100000/CM4_BINARY_START/g' "$ARDUINOVARIANT"/linker_script.ld
Expand Down
17 changes: 7 additions & 10 deletions variants/GENERIC_STM32H747_M4/linker_script.ld
Original file line number Diff line number Diff line change
Expand Up @@ -91,24 +91,21 @@ SECTIONS
__bss_end__ = .;
_ebss = .;
} > RAM
.openamp_section (NOLOAD) : {
. = ABSOLUTE(0x38000000);
*(.resource_table)
} >RAM_D3 AT > FLASH
.pdm_section (NOLOAD) : {
. = ABSOLUTE(0x3800FC00);
*(.pdm_buffer)
} > RAM_D3

.heap (COPY):
.pdm_section 0x3800FC00 (NOLOAD): {
*(.pdm_buffer)
} > RAM_D3

.heap (NOLOAD):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
. = ORIGIN(RAM) + LENGTH(RAM) - 0x400;
__HeapLimit = .;
} > RAM
.stack_dummy (COPY):

.stack_dummy (NOLOAD):
{
*(.stack*)
} > RAM
Expand Down
Loading