Skip to content

Commit e10dfd2

Browse files
authored
Merge pull request #934 from iabdalkader/rpc_openamp_updates
RPC/OpenAMP: Support loading sketches to SDRAM.
2 parents 92eaf0e + 3b4c179 commit e10dfd2

File tree

10 files changed

+487
-156
lines changed

10 files changed

+487
-156
lines changed

libraries/RPC/LICENSE

+373
Large diffs are not rendered by default.

libraries/RPC/src/RPC.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Copyright (c) 2024 Arduino SA
2+
// SPDX-License-Identifier: MPL-2.0
13
#include "RPC.h"
24

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

163165
#ifdef CORE_CM4
166+
#if (CM4_BINARY_START >= 0x60000000) && (CM4_BINARY_START < 0xe0000000)
167+
class M4Init {
168+
public:
169+
M4Init() {
170+
// If the Cortex-M4 core is booting from SDRAM, the memory region must be
171+
// configured as Strongly Ordered. Note that the Cortex-M4 core does not
172+
// seem to implement speculative prefetching, so there is no need to protect
173+
// the whole region from speculative prefetching with a second MPU region.
174+
HAL_MPU_Disable();
175+
MPU_Region_InitTypeDef MPU_InitStruct;
176+
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
177+
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
178+
MPU_InitStruct.BaseAddress = CM4_BINARY_START;
179+
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
180+
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
181+
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
182+
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
183+
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
184+
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
185+
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
186+
MPU_InitStruct.SubRegionDisable = 0x00;
187+
HAL_MPU_ConfigRegion(&MPU_InitStruct);
188+
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
189+
}
190+
};
191+
192+
M4Init __m4init __attribute__ ((init_priority (101)));
193+
#endif
194+
164195
int RPCClass::begin() {
165196
eventThread = new rtos::Thread(osPriorityHigh, 16*1024, nullptr, "rpc_evt");
166197
eventThread->start(&eventHandler);

libraries/RPC/src/RPC.h

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Copyright (c) 2024 Arduino SA
2+
// SPDX-License-Identifier: MPL-2.0
13
#ifdef __cplusplus
24

35
#ifndef __ARDUINO_RPC_IMPLEMENTATION__

libraries/RPC/src/RPC_client.h

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Copyright (c) 2024 Arduino SA
2+
// SPDX-License-Identifier: MPL-2.0
13
#include "Arduino.h"
24
#include "mbed.h"
35
#include "rpc/dispatcher.h"

libraries/RPC/src/SerialRPC.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Copyright (c) 2024 Arduino SA
2+
// SPDX-License-Identifier: MPL-2.0
13
#include "SerialRPC.h"
24
#include "RPC.h"
35

@@ -22,4 +24,4 @@ arduino::SerialRPCClass::operator bool() {
2224
return RPC;
2325
}
2426

25-
arduino::SerialRPCClass SerialRPC;
27+
arduino::SerialRPCClass SerialRPC;

libraries/RPC/src/SerialRPC.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Copyright (c) 2024 Arduino SA
2+
// SPDX-License-Identifier: MPL-2.0
13
#ifndef __SERIAL_RPC__
24
#define __SERIAL_RPC__
35

@@ -69,4 +71,4 @@ class SerialRPCClass : public Stream {
6971

7072
extern arduino::SerialRPCClass SerialRPC;
7173

72-
#endif
74+
#endif

libraries/openamp_arduino/src/openamp_conf.h

+3
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ extern int __OPENAMP_region_end__[];
151151
#define SHM_START_ADDRESS ((metal_phys_addr_t)__OPENAMP_region_start__)
152152
#define SHM_SIZE (size_t)((void *)__OPENAMP_region_end__ - (void *) __OPENAMP_region_start__)
153153

154+
#define SHM_RSC_SIZE (1024)
155+
#define SHM_RSC_ADDR ((void *)__OPENAMP_region_start__ - SHM_RSC_SIZE)
156+
154157
#endif
155158

156159
#define VRING_RX_ADDRESS SHM_START_ADDRESS

libraries/openamp_arduino/src/rsc_table.c

+44-123
Original file line numberDiff line numberDiff line change
@@ -21,137 +21,58 @@
2121
******************************************************************************
2222
*/
2323

24-
/** @addtogroup RSC_TABLE
25-
* @{
26-
*/
27-
28-
/** @addtogroup resource_table
29-
* @{
30-
*/
31-
32-
/** @addtogroup resource_table_Private_Includes
33-
* @{
34-
*/
35-
36-
3724
#if defined(__ICCARM__) || defined (__CC_ARM)
3825
#include <stddef.h> /* needed for offsetof definition*/
3926
#endif
4027
#include "rsc_table.h"
4128
#include "openamp/open_amp.h"
4229

43-
/**
44-
* @}
45-
*/
46-
47-
/** @addtogroup resource_table_Private_TypesDefinitions
48-
* @{
49-
*/
50-
51-
/**
52-
* @}
53-
*/
54-
55-
/** @addtogroup resource_table_Private_Defines
56-
* @{
57-
*/
58-
59-
/* Place resource table in special ELF section */
60-
#if defined(__GNUC__)
61-
#define __section_t(S) __attribute__((__section__(#S)))
62-
#define __resource __section_t(.resource_table)
63-
#endif
64-
65-
#define RPMSG_IPU_C0_FEATURES 1
66-
#define VRING_COUNT 2
67-
68-
/* VirtIO rpmsg device id */
69-
#define VIRTIO_ID_RPMSG_ 7
70-
7130
#if defined (__LOG_TRACE_IO_)
7231
extern char system_log_buf[];
7332
#endif
7433

75-
#if defined(__GNUC__)
76-
#if !defined (__CC_ARM)
77-
/* Since GCC is not initializing the resource_table at startup, it is declared as volatile to avoid compiler optimization
78-
* for the CM4 (see resource_table_init() below)
79-
*/
80-
volatile struct shared_resource_table __resource __attribute__((used)) resource_table;
81-
#else
82-
struct shared_resource_table __resource __attribute__((used)) resource_table = {
83-
#endif
84-
#elif defined(__ICCARM__)
85-
__root struct shared_resource_table resource_table @ ".resource_table" = {
86-
#endif
87-
88-
#if defined(__ICCARM__) || defined (__CC_ARM)
89-
.version = 1,
90-
.num = 2,
91-
.reserved = {0, 0},
92-
.offset = {
93-
offsetof(struct shared_resource_table, vdev),
94-
offsetof(struct shared_resource_table, cm_trace),
95-
},
96-
97-
/* Virtio device entry */
98-
.vdev= {
99-
RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0,
100-
VRING_COUNT, {0, 0},
101-
},
102-
103-
/* Vring rsc entry - part of vdev rsc entry */
104-
.vring0 = {VRING_TX_ADDRESS, VRING_ALIGNMENT, VRING_NUM_BUFFS, VRING0_ID, 0},
105-
.vring1 = {VRING_RX_ADDRESS, VRING_ALIGNMENT, VRING_NUM_BUFFS, VRING1_ID, 0},
106-
107-
#if defined (__LOG_TRACE_IO_)
108-
.cm_trace = {
109-
RSC_TRACE,
110-
(uint32_t)system_log_buf, SYSTEM_TRACE_BUF_SZ, 0, "cm4_log",
111-
},
112-
#endif
113-
} ;
114-
#endif
115-
116-
void resource_table_init(int RPMsgRole, void **table_ptr, int *length)
117-
{
118-
119-
#if defined (__GNUC__) && ! defined (__CC_ARM)
120-
#ifdef CORE_CM7
121-
/*
122-
* Currently the GCC linker doesn't initialize the resource_table global variable at startup
123-
* it is done here by the CM7 application.
124-
*/
125-
memset(&resource_table, '\0', sizeof(struct shared_resource_table));
126-
resource_table.num = 1;
127-
resource_table.version = 1;
128-
resource_table.offset[0] = offsetof(struct shared_resource_table, vdev);
129-
130-
resource_table.vring0.da = VRING_TX_ADDRESS;
131-
resource_table.vring0.align = VRING_ALIGNMENT;
132-
resource_table.vring0.num = VRING_NUM_BUFFS;
133-
resource_table.vring0.notifyid = VRING0_ID;
134-
135-
resource_table.vring1.da = VRING_RX_ADDRESS;
136-
resource_table.vring1.align = VRING_ALIGNMENT;
137-
resource_table.vring1.num = VRING_NUM_BUFFS;
138-
resource_table.vring1.notifyid = VRING1_ID;
139-
140-
141-
resource_table.vdev.type = RSC_VDEV;
142-
resource_table.vdev.id = VIRTIO_ID_RPMSG_;
143-
resource_table.vdev.num_of_vrings=VRING_COUNT;
144-
resource_table.vdev.dfeatures = RPMSG_IPU_C0_FEATURES;
145-
#else
146-
/* For CM4 let's wait until the resource_table is correctly initialized */
147-
while(resource_table.vring1.da != VRING_RX_ADDRESS)
148-
{
149-
150-
}
151-
#endif
152-
#endif
153-
154-
(void)RPMsgRole;
155-
*length = sizeof(resource_table);
156-
*table_ptr = &resource_table;
34+
void resource_table_init(int RPMsgRole, void **table_ptr, int *length) {
35+
(void)RPMsgRole;
36+
volatile struct shared_resource_table *resource_table = SHM_RSC_ADDR;
37+
38+
#ifdef CORE_CM7
39+
memset(resource_table, 0, SHM_RSC_SIZE);
40+
resource_table->num = 1;
41+
resource_table->version = 1;
42+
resource_table->offset[0] = offsetof(struct shared_resource_table, vdev);
43+
#if defined (__LOG_TRACE_IO_)
44+
resource_table->offset[1] = offsetof(struct shared_resource_table, cm_trace);
45+
#endif
46+
47+
resource_table->vring0.da = VRING_TX_ADDRESS;
48+
resource_table->vring0.align = VRING_ALIGNMENT;
49+
resource_table->vring0.num = VRING_NUM_BUFFS;
50+
resource_table->vring0.notifyid = VRING0_ID;
51+
52+
resource_table->vring1.da = VRING_RX_ADDRESS;
53+
resource_table->vring1.align = VRING_ALIGNMENT;
54+
resource_table->vring1.num = VRING_NUM_BUFFS;
55+
resource_table->vring1.notifyid = VRING1_ID;
56+
57+
#if defined (__LOG_TRACE_IO_)
58+
resource_table->cm_trace.type;
59+
resource_table->cm_trace.da;
60+
resource_table->cm_trace.len;
61+
resource_table->cm_trace.reserved = 0;
62+
resource_table->cm_trace.name = (uint8_t[]){"cm_trace"};
63+
#endif
64+
65+
resource_table->vdev.type = RSC_VDEV;
66+
resource_table->vdev.id = VIRTIO_ID_RPMSG;
67+
resource_table->vdev.num_of_vrings=VRING_COUNT;
68+
resource_table->vdev.dfeatures = (1 << VIRTIO_RPMSG_F_NS);
69+
#else
70+
// For CM4, wait until the resource_table is initialized by the host
71+
while(resource_table->vring1.da != VRING_RX_ADDRESS) {
72+
73+
}
74+
#endif
75+
76+
*length = SHM_RSC_SIZE;
77+
*table_ptr = resource_table;
15778
}

mbed-os-to-arduino

+19-21
Original file line numberDiff line numberDiff line change
@@ -187,31 +187,16 @@ generate_flags () {
187187
echo "Patching '-fno-exceptions' flag for $ARDUINOVARIANT/${fl}flags.txt"
188188
sed -i '/-fno-exceptions/d' "$ARDUINOVARIANT"/${fl}flags.txt
189189
set +e
190-
HAS_OPENAMP_SECTION=`grep openamp_section "$ARDUINOVARIANT"/linker_script.ld`
190+
HAS_PDM_SECTION=`grep pdm_section "$ARDUINOVARIANT"/linker_script.ld`
191191
set -e
192-
if [ x"$HAS_OPENAMP_SECTION" == x ]; then
193-
echo "Adding OpenAMP section to $ARDUINOVARIANT/linker_script.ld"
194-
OPENAMP_SECTION=".openamp_section (NOLOAD) : {\n \
195-
. = ABSOLUTE(0x38000000);\n \
196-
*(.resource_table)\n \
197-
} >RAM_D3 AT > FLASH\n \
198-
.pdm_section (NOLOAD) : {\n \
199-
. = ABSOLUTE(0x3800FC00);\n \
192+
if [ x"$HAS_PDM_SECTION" == x ]; then
193+
echo "Adding PDM section to $ARDUINOVARIANT/linker_script.ld"
194+
PDM_SECTION=".pdm_section 0x3800FC00 (NOLOAD): {\n \
200195
*(.pdm_buffer)\n \
201196
} > RAM_D3\n"
202197

203-
if [[ $ARDUINOVARIANT == *GENERIC*M4 ]]; then
204-
echo "Fixing VTOR base in $ARDUINOVARIANT/linker_script.ld"
205-
VTOR_SECTION="#if (CM4_BINARY_START == 0x60000000)\n \
206-
REGION_ALIAS(\"RAM\", FLASH);\n \
207-
#else\n \
208-
REGION_ALIAS(\"RAM\", RAM_D2);\n \
209-
#endif\n"
210-
sed -i "s?REGION_ALIAS.*?${VTOR_SECTION}?g" $ARDUINOVARIANT/linker_script.ld
211-
fi
212-
213198
if [[ $ARDUINOVARIANT == *PORTENTA*M7* || $ARDUINOVARIANT == *GIGA* || $ARDUINOVARIANT == *OPTA* ]]; then
214-
OPENAMP_SECTION="${OPENAMP_SECTION} \
199+
PDM_SECTION="${PDM_SECTION} \
215200
_dtcm_lma = __etext + SIZEOF(.data);\n \
216201
.dtcm : AT(_dtcm_lma) {\n \
217202
_sdtcm = .;\n \
@@ -220,9 +205,22 @@ generate_flags () {
220205
} > DTCMRAM"
221206
fi
222207

223-
sed -i "s?.heap (COPY):?${OPENAMP_SECTION}\n .heap (COPY):?g" $ARDUINOVARIANT/linker_script.ld
208+
sed -i "s?.heap (COPY):?${PDM_SECTION}\n .heap (COPY):?g" $ARDUINOVARIANT/linker_script.ld
224209
OPENAMP_REGIONS="__OPENAMP_region_start__ = 0x38000400;\n__OPENAMP_region_end__ = 0x38000400 + LENGTH(RAM_D3) - 1K;"
225210
sed -i "s?ENTRY(Reset_Handler)?${OPENAMP_REGIONS}\nENTRY(Reset_Handler)?g" $ARDUINOVARIANT/linker_script.ld
211+
212+
if [[ $ARDUINOVARIANT == *GENERIC*M4 ]]; then
213+
echo "Fixing VTOR base in $ARDUINOVARIANT/linker_script.ld"
214+
VTOR_SECTION="#if (CM4_BINARY_START == 0x60000000)\n \
215+
REGION_ALIAS(\"RAM\", FLASH);\n \
216+
#else\n \
217+
REGION_ALIAS(\"RAM\", RAM_D2);\n \
218+
#endif\n"
219+
sed -i "s?REGION_ALIAS.*?${VTOR_SECTION}?g" $ARDUINOVARIANT/linker_script.ld
220+
echo "Fixing shared memory attributes in $ARDUINOVARIANT/linker_script.ld"
221+
sed -i "s?.heap (COPY)?.heap (NOLOAD)?g" $ARDUINOVARIANT/linker_script.ld
222+
sed -i "s?.stack_dummy (COPY)?.stack_dummy (NOLOAD)?g" $ARDUINOVARIANT/linker_script.ld
223+
fi
226224
fi
227225
echo "Patching linker scripts"
228226
sed -i 's/0x8100000/CM4_BINARY_START/g' "$ARDUINOVARIANT"/linker_script.ld

variants/GENERIC_STM32H747_M4/linker_script.ld

+7-10
Original file line numberDiff line numberDiff line change
@@ -91,24 +91,21 @@ SECTIONS
9191
__bss_end__ = .;
9292
_ebss = .;
9393
} > RAM
94-
.openamp_section (NOLOAD) : {
95-
. = ABSOLUTE(0x38000000);
96-
*(.resource_table)
97-
} >RAM_D3 AT > FLASH
98-
.pdm_section (NOLOAD) : {
99-
. = ABSOLUTE(0x3800FC00);
100-
*(.pdm_buffer)
101-
} > RAM_D3
10294

103-
.heap (COPY):
95+
.pdm_section 0x3800FC00 (NOLOAD): {
96+
*(.pdm_buffer)
97+
} > RAM_D3
98+
99+
.heap (NOLOAD):
104100
{
105101
__end__ = .;
106102
PROVIDE(end = .);
107103
*(.heap*)
108104
. = ORIGIN(RAM) + LENGTH(RAM) - 0x400;
109105
__HeapLimit = .;
110106
} > RAM
111-
.stack_dummy (COPY):
107+
108+
.stack_dummy (NOLOAD):
112109
{
113110
*(.stack*)
114111
} > RAM

0 commit comments

Comments
 (0)