Skip to content

Commit 5eb8829

Browse files
Kristian Klomsten SkordalMaureenHelm
Kristian Klomsten Skordal
authored andcommitted
sample: add OpenAMP sample application
This commit adds a sample application using OpenAMP for remote procedure calls on the LPCXpresso54114. It is adapted from the RPMsg-Lite sample application added in PR #5960, and uses the IPM driver to provide interprocessor interrupts. Signed-off-by: Kristian Klomsten Skordal <[email protected]> Signed-off-by: Kumar Gala <[email protected]>
1 parent 17b64ba commit 5eb8829

File tree

15 files changed

+653
-0
lines changed

15 files changed

+653
-0
lines changed

boards/arm/lpcxpresso54114_m0/lpcxpresso54114_m0_defconfig

+4
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ CONFIG_SERIAL=n
1414
CONFIG_CORTEX_M_SYSTICK=y
1515
CONFIG_GPIO=n
1616
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=48000000
17+
18+
# Heap is needed by OpenAMP:
19+
CONFIG_HEAP_MEM_POOL_SIZE=4096
20+

boards/arm/lpcxpresso54114_m4/lpcxpresso54114_m4_defconfig

+4
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ CONFIG_CORTEX_M_SYSTICK=y
1515
CONFIG_GPIO=y
1616
CONFIG_PINMUX=y
1717
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=48000000
18+
19+
# Heap is needed by OpenAMP:
20+
CONFIG_HEAP_MEM_POOL_SIZE=4096
21+
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright (c) 2018 Nordic Semiconductor ASA
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
set(BOARD lpcxpresso54114_m4)
6+
7+
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
8+
project(NONE)
9+
10+
enable_language(C ASM)
11+
12+
# Location of external dependencies:
13+
set(ZEPHYR_KERNEL_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/zephyr/kernel/libkernel.a")
14+
set(PLATFORM_DIR "${CMAKE_CURRENT_SOURCE_DIR}/platform")
15+
16+
target_include_directories(app PRIVATE $ENV{ZEPHYR_BASE}/drivers)
17+
18+
target_sources(app PRIVATE src/main_master.c ${PLATFORM_DIR}/platform.c
19+
${PLATFORM_DIR}/platform_ops.c ${PLATFORM_DIR}/resource_table.c)
20+
21+
include($ENV{ZEPHYR_BASE}/ext/lib/ipc/open-amp.cmake)
22+
23+
add_dependencies(app open-amp)
24+
25+
ExternalProject_Add(
26+
openamp_remote
27+
SOURCE_DIR ${APPLICATION_SOURCE_DIR}/remote
28+
INSTALL_COMMAND "" # This particular build system has no install command
29+
)
30+
add_dependencies(core_m0_inc_target openamp_remote)
31+
32+
target_include_directories(app PRIVATE ${LIBMETAL_INCLUDE_DIR}
33+
${OPENAMP_INCLUDE_DIR} ${PLATFORM_DIR})
34+
35+
target_link_libraries(app
36+
${OPENAMP_LIBRARY}
37+
${LIBMETAL_LIBRARY}
38+
${ZEPHYR_KERNEL_LIBRARY})
39+

samples/subsys/ipc/openamp/README.rst

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
.. _openAMP_sample:
2+
3+
OpenAMP Sample Application
4+
###########################
5+
6+
Overview
7+
********
8+
9+
This application demostrates how to use OpenAMP with Zephyr. It is designed to
10+
demonstrate how to integrate OpenAMP with Zephyr both from a build perspective
11+
and code.
12+
13+
Building the application
14+
*************************
15+
16+
.. zephyr-app-commands::
17+
:zephyr-app: samples/subsys/ipc/openamp
18+
:board: lpcxpresso54114_m4
19+
:goals: debug
20+
21+
Open a serial terminal (minicom, putty, etc.) and connect the board with the
22+
following settings:
23+
24+
- Speed: 115200
25+
- Data: 8 bits
26+
- Parity: None
27+
- Stop bits: 1
28+
29+
Reset the board and the following message will appear on the corresponding
30+
serial port:
31+
32+
.. code-block:: console
33+
34+
***** Booting Zephyr OS v1.11.0-1377-g580b9add47 *****
35+
Starting application thread!
36+
37+
OpenAMP demo started
38+
Primary core received a message: 1
39+
Primary core received a message: 3
40+
Primary core received a message: 5
41+
...
42+
Primary core received a message: 101
43+
OpenAMP demo ended.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2018 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr.h>
8+
9+
#include "platform.h"
10+
#include "resource_table.h"
11+
12+
extern struct hil_platform_ops platform_ops;
13+
14+
static metal_phys_addr_t shm_physmap[] = { SHM_START_ADDRESS };
15+
static struct metal_device shm_device = {
16+
.name = SHM_DEVICE_NAME,
17+
.bus = NULL,
18+
.num_regions = 1,
19+
{
20+
{
21+
.virt = (void *) SHM_START_ADDRESS,
22+
.physmap = shm_physmap,
23+
.size = SHM_SIZE,
24+
.page_shift = 0xffffffff,
25+
.page_mask = 0xffffffff,
26+
.mem_flags = 0,
27+
.ops = { NULL },
28+
},
29+
},
30+
.node = { NULL },
31+
.irq_num = 0,
32+
.irq_info = NULL
33+
};
34+
35+
struct hil_proc *platform_init(int role)
36+
{
37+
int status;
38+
39+
status = metal_register_generic_device(&shm_device);
40+
if (status != 0) {
41+
printk("metal_register_generic_device(): could not register "
42+
"shared memory device: error code %d\n", status);
43+
return NULL;
44+
}
45+
46+
struct hil_proc *proc = hil_create_proc(&platform_ops,
47+
role != RPMSG_MASTER, NULL);
48+
if (proc == NULL) {
49+
printk("platform_create(): could not allocate hil_proc\n");
50+
return NULL;
51+
}
52+
53+
hil_set_shm(proc, "generic", SHM_DEVICE_NAME, SHM_START_ADDRESS,
54+
SHM_SIZE);
55+
return proc;
56+
}
57+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2018 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef PLATFORM_H__
8+
#define PLATFORM_H__
9+
10+
#include <openamp/open_amp.h>
11+
12+
#define SHM_START_ADDRESS 0x04000400
13+
#define SHM_SIZE 0x7c00
14+
#define SHM_DEVICE_NAME "sramx.shm"
15+
16+
#define VRING_COUNT 2
17+
#define VRING_RX_ADDRESS 0x04007800
18+
#define VRING_TX_ADDRESS 0x04007C00
19+
#define VRING_ALIGNMENT 4
20+
#define VRING_SIZE 16
21+
22+
struct hil_proc *platform_init(int role);
23+
24+
#endif
25+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright (c) 2018 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr.h>
8+
#include <ipm.h>
9+
10+
#include <openamp/open_amp.h>
11+
#include "platform.h"
12+
13+
static K_SEM_DEFINE(data_sem, 0, 1);
14+
static struct device *ipm_handle;
15+
16+
static void platform_ipm_callback(void *context, u32_t id, volatile void *data)
17+
{
18+
k_sem_give(&data_sem);
19+
}
20+
21+
static int enable_interrupt(struct proc_intr *intr)
22+
{
23+
return ipm_set_enabled(ipm_handle, 1);
24+
}
25+
26+
static void notify(struct hil_proc *proc, struct proc_intr *intr_info)
27+
{
28+
u32_t dummy_data = 0x12345678; /* Some data must be provided */
29+
30+
ipm_send(ipm_handle, 0, 0, &dummy_data, sizeof(dummy_data));
31+
}
32+
33+
static int boot_cpu(struct hil_proc *proc, unsigned int load_addr)
34+
{
35+
return -1;
36+
}
37+
38+
static void shutdown_cpu(struct hil_proc *proc)
39+
{
40+
}
41+
42+
static int poll(struct hil_proc *proc, int nonblock)
43+
{
44+
int status = k_sem_take(&data_sem, nonblock ? K_NO_WAIT : K_FOREVER);
45+
46+
if (status == 0) {
47+
hil_notified(proc, 0xffffffff);
48+
}
49+
50+
return status;
51+
}
52+
53+
static struct metal_io_region *alloc_shm(struct hil_proc *proc,
54+
metal_phys_addr_t physical,
55+
size_t size,
56+
struct metal_device **device)
57+
{
58+
int status = metal_device_open("generic", SHM_DEVICE_NAME, device);
59+
60+
if (status != 0) {
61+
return NULL;
62+
}
63+
64+
return metal_device_io_region(*device, 0);
65+
}
66+
67+
static void release_shm(struct hil_proc *proc, struct metal_device *device,
68+
struct metal_io_region *io)
69+
{
70+
metal_device_close(device);
71+
}
72+
73+
static int initialize(struct hil_proc *proc)
74+
{
75+
ipm_handle = device_get_binding("MAILBOX_0");
76+
if (!ipm_handle) {
77+
return -1;
78+
}
79+
80+
ipm_register_callback(ipm_handle, platform_ipm_callback, NULL);
81+
return 0;
82+
}
83+
84+
static void release(struct hil_proc *proc)
85+
{
86+
ipm_set_enabled(ipm_handle, 0);
87+
}
88+
89+
struct hil_platform_ops platform_ops = {
90+
.enable_interrupt = enable_interrupt,
91+
.notify = notify,
92+
.boot_cpu = boot_cpu,
93+
.shutdown_cpu = shutdown_cpu,
94+
.poll = poll,
95+
.alloc_shm = alloc_shm,
96+
.release_shm = release_shm,
97+
.initialize = initialize,
98+
.release = release
99+
};
100+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2018 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "platform.h"
8+
#include "resource_table.h"
9+
10+
struct lpc_resource_table *rsc_table_ptr = (void *) RSC_TABLE_ADDRESS;
11+
12+
#if defined(CPU_LPC54114J256BD64_cm4)
13+
static const struct lpc_resource_table rsc_table = {
14+
.ver = 1,
15+
.num = 2,
16+
.offset = {
17+
offsetof(struct lpc_resource_table, mem),
18+
offsetof(struct lpc_resource_table, vdev),
19+
},
20+
.mem = {
21+
RSC_RPROC_MEM, SHM_START_ADDRESS, SHM_START_ADDRESS, SHM_SIZE,
22+
0,
23+
},
24+
25+
.vdev = {
26+
RSC_VDEV, VIRTIO_ID_RPMSG, 0, 1 << VIRTIO_RPMSG_F_NS, 0, 0, 0,
27+
VRING_COUNT, { 0, 0 },
28+
},
29+
30+
.vring0 = { VRING_TX_ADDRESS, VRING_ALIGNMENT, VRING_SIZE, 1, 0 },
31+
.vring1 = { VRING_RX_ADDRESS, VRING_ALIGNMENT, VRING_SIZE, 2, 0 },
32+
};
33+
#endif
34+
35+
void resource_table_init(void **table_ptr, int *length)
36+
{
37+
#if defined(CPU_LPC54114J256BD64_cm4)
38+
/* Master: copy the resource table to shared memory. */
39+
memcpy(rsc_table_ptr, &rsc_table, sizeof(struct lpc_resource_table));
40+
#endif
41+
42+
*length = sizeof(struct lpc_resource_table);
43+
*table_ptr = rsc_table_ptr;
44+
}
45+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2018 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef RESOURCE_TABLE_H__
8+
#define RESOURCE_TABLE_H__
9+
10+
#include <openamp/open_amp.h>
11+
12+
#define RSC_TABLE_ADDRESS 0x04000000
13+
14+
OPENAMP_PACKED_BEGIN
15+
struct lpc_resource_table {
16+
uint32_t ver;
17+
uint32_t num;
18+
uint32_t reserved[2];
19+
uint32_t offset[2];
20+
struct fw_rsc_rproc_mem mem;
21+
struct fw_rsc_vdev vdev;
22+
struct fw_rsc_vdev_vring vring0, vring1;
23+
} OPENAMP_PACKED_END;
24+
25+
void resource_table_init(void **table_ptr, int *length);
26+
27+
#endif
28+

samples/subsys/ipc/openamp/prj.conf

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CONFIG_PRINTK=y
2+
CONFIG_IPM=y
3+
CONFIG_IPM_MCUX=y
4+
CONFIG_SLAVE_CORE_MCUX=y
5+
CONFIG_SLAVE_IMAGE_MCUX="${ZEPHYR_BINARY_DIR}/../openamp_remote-prefix/src/openamp_remote-build/zephyr/zephyr.bin"
6+
CONFIG_TIMESLICE_SIZE=1
7+
CONFIG_MAIN_STACK_SIZE=2048
8+
CONFIG_HEAP_MEM_POOL_SIZE=4096
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright (c) 2018 Nordic Semiconductor ASA
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
set(BOARD lpcxpresso54114_m0)
6+
7+
set(ZEPHYR_KERNEL_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/zephyr/kernel/libkernel.a")
8+
set(PLATFORM_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../platform")
9+
10+
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
11+
project(NONE)
12+
13+
target_sources(app PRIVATE src/main_remote.c ${PLATFORM_DIR}/platform.c ${PLATFORM_DIR}/resource_table.c ${PLATFORM_DIR}/platform_ops.c)
14+
15+
include($ENV{ZEPHYR_BASE}/ext/lib/ipc/open-amp.cmake)
16+
17+
target_include_directories(app PRIVATE ${LIBMETAL_INCLUDE_DIR} ${OPENAMP_INCLUDE_DIR} ${PLATFORM_DIR})
18+
19+
add_dependencies(app open-amp)
20+
21+
target_link_libraries(app
22+
${OPENAMP_LIBRARY}
23+
${LIBMETAL_LIBRARY}
24+
${ZEPHYR_KERNEL_LIBRARY})
25+

0 commit comments

Comments
 (0)