Skip to content

Commit 81aba82

Browse files
iabdalkaderdpgeorge
authored andcommitted
extmod/modopenamp_remoteproc: Add new OpenAMP RemoteProc class.
RemoteProc provides an API to load firmware and control remote processors. Note: port-specific operations must be implemented to support this class. Signed-off-by: iabdalkader <[email protected]>
1 parent 14dae42 commit 81aba82

6 files changed

+402
-0
lines changed

extmod/extmod.mk

+16
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ SRC_EXTMOD_C += \
3232
extmod/modnetwork.c \
3333
extmod/modonewire.c \
3434
extmod/modopenamp.c \
35+
extmod/modopenamp_remoteproc.c \
36+
extmod/modopenamp_remoteproc_store.c \
3537
extmod/modos.c \
3638
extmod/modplatform.c\
3739
extmod/modrandom.c \
@@ -529,6 +531,10 @@ include $(TOP)/extmod/libmetal/libmetal.mk
529531
INC += -I$(TOP)/$(OPENAMP_DIR)
530532
CFLAGS += -DMICROPY_PY_OPENAMP=1
531533

534+
ifeq ($(MICROPY_PY_OPENAMP_REMOTEPROC),1)
535+
CFLAGS += -DMICROPY_PY_OPENAMP_REMOTEPROC=1
536+
endif
537+
532538
CFLAGS_THIRDPARTY += \
533539
-I$(BUILD)/openamp \
534540
-I$(TOP)/$(OPENAMP_DIR) \
@@ -547,6 +553,16 @@ SRC_OPENAMP_C += $(addprefix $(OPENAMP_DIR)/lib/,\
547553
virtio_mmio/virtio_mmio_drv.c \
548554
)
549555

556+
# OpenAMP's remoteproc source files.
557+
ifeq ($(MICROPY_PY_OPENAMP_REMOTEPROC),1)
558+
SRC_OPENAMP_C += $(addprefix $(OPENAMP_DIR)/lib/remoteproc/,\
559+
elf_loader.c \
560+
remoteproc.c \
561+
remoteproc_virtio.c \
562+
rsc_table_parser.c \
563+
)
564+
endif # MICROPY_PY_OPENAMP_REMOTEPROC
565+
550566
# Disable compiler warnings in OpenAMP (variables used only for assert).
551567
$(BUILD)/$(OPENAMP_DIR)/lib/rpmsg/rpmsg_virtio.o: CFLAGS += -Wno-unused-but-set-variable
552568
$(BUILD)/$(OPENAMP_DIR)/lib/virtio_mmio/virtio_mmio_drv.o: CFLAGS += -Wno-unused-but-set-variable

extmod/modopenamp.c

+7
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ static const char openamp_trace_buf[128];
7777

7878
#define debug_printf(...) // mp_printf(&mp_plat_print, __VA_ARGS__)
7979

80+
#if MICROPY_PY_OPENAMP_REMOTEPROC
81+
extern mp_obj_type_t openamp_remoteproc_type;
82+
#endif
83+
8084
static struct metal_device shm_device = {
8185
.name = METAL_SHM_NAME,
8286
// The number of IO regions is fixed and must match the number and
@@ -381,6 +385,9 @@ static const mp_rom_map_elem_t globals_dict_table[] = {
381385
{ MP_ROM_QSTR(MP_QSTR_ENDPOINT_ADDR_ANY), MP_ROM_INT(RPMSG_ADDR_ANY) },
382386
{ MP_ROM_QSTR(MP_QSTR_new_service_callback), MP_ROM_PTR(&openamp_new_service_callback_obj) },
383387
{ MP_ROM_QSTR(MP_QSTR_Endpoint), MP_ROM_PTR(&endpoint_type) },
388+
#if MICROPY_PY_OPENAMP_REMOTEPROC
389+
{ MP_ROM_QSTR(MP_QSTR_RemoteProc), MP_ROM_PTR(&openamp_remoteproc_type) },
390+
#endif
384391
};
385392
static MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table);
386393

extmod/modopenamp.h

+12
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@
4747
#define MICROPY_PY_OPENAMP_TRACE_BUF_ENABLE (1)
4848
#endif
4949

50+
// For ports that don't define a custom image store, this enables a generic
51+
// VFS-based image store that supports loading elf files from storage.
52+
#ifndef MICROPY_PY_OPENAMP_REMOTEPROC_STORE_ENABLE
53+
#define MICROPY_PY_OPENAMP_REMOTEPROC_STORE_ENABLE (1)
54+
#endif
55+
56+
// Enable or disable support for loading elf files. This option saves
57+
// around 7KBs when disabled.
58+
#ifndef MICROPY_PY_OPENAMP_REMOTEPROC_ELFLD_ENABLE
59+
#define MICROPY_PY_OPENAMP_REMOTEPROC_ELFLD_ENABLE (1)
60+
#endif
61+
5062
// The resource table is used for sharing the configuration of the virtio
5163
// device, vrings and other resources, between the host and remote cores.
5264
// The layout and address the table structure must match the one used in

extmod/modopenamp_remoteproc.c

+175
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2023-2024 Arduino SA
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*
26+
* OpenAMP's remoteproc class.
27+
*/
28+
29+
#if MICROPY_PY_OPENAMP_REMOTEPROC
30+
31+
#include "py/obj.h"
32+
#include "py/nlr.h"
33+
#include "py/runtime.h"
34+
#include "py/stream.h"
35+
#include "extmod/vfs.h"
36+
37+
#include "metal/sys.h"
38+
#include "metal/alloc.h"
39+
#include "metal/errno.h"
40+
#include "metal/io.h"
41+
42+
#include "openamp/open_amp.h"
43+
#include "openamp/remoteproc.h"
44+
#include "openamp/remoteproc_loader.h"
45+
46+
#include "modopenamp.h"
47+
#include "modopenamp_remoteproc.h"
48+
49+
#define DEBUG_printf(...) // mp_printf(&mp_plat_print, __VA_ARGS__)
50+
51+
#if !MICROPY_PY_OPENAMP
52+
#error "MICROPY_PY_OPENAMP_REMOTEPROC requires MICROPY_PY_OPENAMP"
53+
#endif
54+
55+
typedef struct openamp_remoteproc_obj {
56+
mp_obj_base_t base;
57+
struct remoteproc rproc;
58+
} openamp_remoteproc_obj_t;
59+
60+
const mp_obj_type_t openamp_remoteproc_type;
61+
62+
// Port-defined image store operations.
63+
extern struct image_store_ops openamp_remoteproc_store_ops;
64+
65+
// Port-defined remote-proc operations.
66+
const struct remoteproc_ops openamp_remoteproc_ops = {
67+
.init = mp_openamp_remoteproc_init,
68+
.mmap = mp_openamp_remoteproc_mmap,
69+
.start = mp_openamp_remoteproc_start,
70+
.stop = mp_openamp_remoteproc_stop,
71+
.config = mp_openamp_remoteproc_config,
72+
.remove = mp_openamp_remoteproc_remove,
73+
.shutdown = mp_openamp_remoteproc_shutdown,
74+
};
75+
76+
static mp_obj_t openamp_remoteproc_start(mp_obj_t self_in) {
77+
openamp_remoteproc_obj_t *self = MP_OBJ_TO_PTR(self_in);
78+
79+
// Start the processor to run the application.
80+
int error = remoteproc_start(&self->rproc);
81+
if (error != 0) {
82+
self->rproc.state = RPROC_ERROR;
83+
mp_raise_OSError(error);
84+
}
85+
return mp_const_none;
86+
}
87+
static MP_DEFINE_CONST_FUN_OBJ_1(openamp_remoteproc_start_obj, openamp_remoteproc_start);
88+
89+
static mp_obj_t openamp_remoteproc_stop(mp_obj_t self_in) {
90+
openamp_remoteproc_obj_t *self = MP_OBJ_TO_PTR(self_in);
91+
92+
// Stop the processor, but the processor is not powered down.
93+
int error = remoteproc_stop(&self->rproc);
94+
if (error != 0) {
95+
mp_raise_OSError(error);
96+
}
97+
return mp_const_none;
98+
}
99+
static MP_DEFINE_CONST_FUN_OBJ_1(openamp_remoteproc_stop_obj, openamp_remoteproc_stop);
100+
101+
static mp_obj_t openamp_remoteproc_shutdown(mp_obj_t self_in) {
102+
openamp_remoteproc_obj_t *self = MP_OBJ_TO_PTR(self_in);
103+
104+
// Shutdown the remoteproc and release its resources.
105+
int error = remoteproc_shutdown(&self->rproc);
106+
if (error != 0) {
107+
mp_raise_OSError(error);
108+
}
109+
return mp_const_none;
110+
}
111+
static MP_DEFINE_CONST_FUN_OBJ_1(openamp_remoteproc_shutdown_obj, openamp_remoteproc_shutdown);
112+
113+
mp_obj_t openamp_remoteproc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
114+
enum { ARG_entry };
115+
static const mp_arg_t allowed_args[] = {
116+
{ MP_QSTR_entry, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_NONE } },
117+
};
118+
119+
// Parse args.
120+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
121+
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
122+
123+
openamp_remoteproc_obj_t *self = mp_obj_malloc_with_finaliser(openamp_remoteproc_obj_t, &openamp_remoteproc_type);
124+
125+
// Make sure OpenAMP is initialized.
126+
if (MP_STATE_PORT(virtio_device) == NULL) {
127+
openamp_init();
128+
}
129+
130+
// Create a remoteproc instance.
131+
// NOTE: ports should use rproc->priv to allocate the image store,
132+
// which gets passed to remoteproc_load(), and all of the store ops.
133+
remoteproc_init(&self->rproc, &openamp_remoteproc_ops, NULL);
134+
135+
// Configure the remote before loading applications (optional).
136+
int error = remoteproc_config(&self->rproc, NULL);
137+
if (error != 0) {
138+
mp_raise_OSError(error);
139+
}
140+
141+
if (mp_obj_is_int(args[ARG_entry].u_obj)) {
142+
self->rproc.bootaddr = mp_obj_get_int(args[ARG_entry].u_obj);
143+
} else {
144+
#if MICROPY_PY_OPENAMP_REMOTEPROC_ELFLD_ENABLE
145+
// Load firmware.
146+
const char *path = mp_obj_str_get_str(args[ARG_entry].u_obj);
147+
int error = remoteproc_load(&self->rproc, path, self->rproc.priv, &openamp_remoteproc_store_ops, NULL);
148+
if (error != 0) {
149+
mp_raise_OSError(error);
150+
}
151+
#else
152+
mp_raise_TypeError(MP_ERROR_TEXT("loading firmware is not supported."));
153+
#endif
154+
}
155+
return MP_OBJ_FROM_PTR(self);
156+
}
157+
158+
static const mp_rom_map_elem_t openamp_remoteproc_dict_table[] = {
159+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_RemoteProc) },
160+
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&openamp_remoteproc_shutdown_obj) },
161+
{ MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&openamp_remoteproc_start_obj) },
162+
{ MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&openamp_remoteproc_stop_obj) },
163+
{ MP_ROM_QSTR(MP_QSTR_shutdown), MP_ROM_PTR(&openamp_remoteproc_shutdown_obj) },
164+
};
165+
static MP_DEFINE_CONST_DICT(openamp_remoteproc_dict, openamp_remoteproc_dict_table);
166+
167+
MP_DEFINE_CONST_OBJ_TYPE(
168+
openamp_remoteproc_type,
169+
MP_QSTR_RemoteProc,
170+
MP_TYPE_FLAG_NONE,
171+
make_new, openamp_remoteproc_make_new,
172+
locals_dict, &openamp_remoteproc_dict
173+
);
174+
175+
#endif // MICROPY_PY_OPENAMP_REMOTEPROC

extmod/modopenamp_remoteproc.h

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2023-2024 Arduino SA
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*
26+
* OpenAMP's remoteproc class.
27+
*/
28+
#ifndef MICROPY_INCLUDED_MODOPENAMP_REMOTEPROC_H
29+
#define MICROPY_INCLUDED_MODOPENAMP_REMOTEPROC_H
30+
31+
#include "openamp/remoteproc.h"
32+
#include "openamp/remoteproc_loader.h"
33+
34+
void *mp_openamp_remoteproc_store_alloc(void);
35+
struct remoteproc *mp_openamp_remoteproc_init(struct remoteproc *rproc,
36+
const struct remoteproc_ops *ops, void *arg);
37+
void *mp_openamp_remoteproc_mmap(struct remoteproc *rproc, metal_phys_addr_t *pa,
38+
metal_phys_addr_t *da, size_t size, unsigned int attribute,
39+
struct metal_io_region **io);
40+
int mp_openamp_remoteproc_start(struct remoteproc *rproc);
41+
int mp_openamp_remoteproc_stop(struct remoteproc *rproc);
42+
int mp_openamp_remoteproc_config(struct remoteproc *rproc, void *data);
43+
void mp_openamp_remoteproc_remove(struct remoteproc *rproc);
44+
int mp_openamp_remoteproc_shutdown(struct remoteproc *rproc);
45+
46+
#endif // MICROPY_INCLUDED_MODOPENAMP_REMOTEPROC_H

0 commit comments

Comments
 (0)