Skip to content

Commit b048e4b

Browse files
committed
Add OpenAMP rough example
1 parent 9e1e5d5 commit b048e4b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+9965
-0
lines changed

libraries/OpenAMP/.mbedignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
openamp/*.h
2+
metal/*.h

libraries/OpenAMP/condition.c

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
/*
8+
* @file generic/condition.c
9+
* @brief Generic libmetal condition variable handling.
10+
*/
11+
12+
#include <metal/condition.h>
13+
#include <metal/irq.h>
14+
15+
extern void metal_generic_default_poll(void);
16+
17+
int metal_condition_wait(struct metal_condition *cv,
18+
metal_mutex_t *m)
19+
{
20+
metal_mutex_t *tmpm = 0;
21+
int v;
22+
unsigned int flags;
23+
24+
/* Check if the mutex has been acquired */
25+
if (!cv || !m || !metal_mutex_is_acquired(m))
26+
return -EINVAL;
27+
28+
if (!atomic_compare_exchange_strong(&cv->m->v, &tmpm->v, m->v)) {
29+
if (m != tmpm)
30+
return -EINVAL;
31+
}
32+
33+
v = atomic_load(&cv->v);
34+
35+
/* Release the mutex first. */
36+
metal_mutex_release(m);
37+
do {
38+
flags = metal_irq_save_disable();
39+
if (atomic_load(&cv->v) != v) {
40+
metal_irq_restore_enable(flags);
41+
break;
42+
}
43+
metal_generic_default_poll();
44+
metal_irq_restore_enable(flags);
45+
} while(1);
46+
/* Acquire the mutex again. */
47+
metal_mutex_acquire(m);
48+
return 0;
49+
}

libraries/OpenAMP/device.c

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
#include <string.h>
8+
#include <metal/errno.h>
9+
#include <metal/assert.h>
10+
#include <metal/device.h>
11+
#include <metal/list.h>
12+
#include <metal/log.h>
13+
#include <metal/sys.h>
14+
#include <metal/utilities.h>
15+
#include <metal/dma.h>
16+
#include <metal/cache.h>
17+
18+
int metal_bus_register(struct metal_bus *bus)
19+
{
20+
if (!bus || !bus->name || !strlen(bus->name))
21+
return -EINVAL;
22+
if (metal_bus_find(bus->name, NULL) == 0)
23+
return -EEXIST;
24+
metal_list_init(&bus->devices);
25+
metal_list_add_tail(&_metal.common.bus_list, &bus->node);
26+
metal_log(METAL_LOG_DEBUG, "registered %s bus\n", bus->name);
27+
return 0;
28+
}
29+
30+
int metal_bus_unregister(struct metal_bus *bus)
31+
{
32+
metal_list_del(&bus->node);
33+
if (bus->ops.bus_close)
34+
bus->ops.bus_close(bus);
35+
metal_log(METAL_LOG_DEBUG, "unregistered %s bus\n", bus->name);
36+
return 0;
37+
}
38+
39+
int metal_bus_find(const char *name, struct metal_bus **result)
40+
{
41+
struct metal_list *node;
42+
struct metal_bus *bus;
43+
44+
metal_list_for_each(&_metal.common.bus_list, node) {
45+
bus = metal_container_of(node, struct metal_bus, node);
46+
if (strcmp(bus->name, name) != 0)
47+
continue;
48+
if (result)
49+
*result = bus;
50+
return 0;
51+
}
52+
return -ENOENT;
53+
}
54+
55+
int metal_device_open(const char *bus_name, const char *dev_name,
56+
struct metal_device **device)
57+
{
58+
struct metal_bus *bus;
59+
int error;
60+
61+
if (!bus_name || !strlen(bus_name) ||
62+
!dev_name || !strlen(dev_name) ||
63+
!device)
64+
return -EINVAL;
65+
66+
error = metal_bus_find(bus_name, &bus);
67+
if (error)
68+
return error;
69+
70+
if (!bus->ops.dev_open)
71+
return -ENODEV;
72+
73+
error = (*bus->ops.dev_open)(bus, dev_name, device);
74+
if (error)
75+
return error;
76+
77+
return 0;
78+
}
79+
80+
void metal_device_close(struct metal_device *device)
81+
{
82+
metal_assert(device && device->bus);
83+
if (device->bus->ops.dev_close)
84+
device->bus->ops.dev_close(device->bus, device);
85+
}
86+
87+
int metal_register_generic_device(struct metal_device *device)
88+
{
89+
if (!device->name || !strlen(device->name) ||
90+
device->num_regions > METAL_MAX_DEVICE_REGIONS)
91+
return -EINVAL;
92+
93+
device->bus = &metal_generic_bus;
94+
metal_list_add_tail(&_metal.common.generic_device_list,
95+
&device->node);
96+
return 0;
97+
}
98+
99+
int metal_generic_dev_open(struct metal_bus *bus, const char *dev_name,
100+
struct metal_device **device)
101+
{
102+
struct metal_list *node;
103+
struct metal_device *dev;
104+
105+
(void)bus;
106+
107+
metal_list_for_each(&_metal.common.generic_device_list, node) {
108+
dev = metal_container_of(node, struct metal_device, node);
109+
if (strcmp(dev->name, dev_name) != 0)
110+
continue;
111+
*device = dev;
112+
return metal_generic_dev_sys_open(dev);
113+
}
114+
115+
return -ENODEV;
116+
}
117+
118+
int metal_generic_dev_dma_map(struct metal_bus *bus,
119+
struct metal_device *device,
120+
uint32_t dir,
121+
struct metal_sg *sg_in,
122+
int nents_in,
123+
struct metal_sg *sg_out)
124+
{
125+
(void)bus;
126+
(void)device;
127+
int i;
128+
129+
if (sg_out != sg_in)
130+
memcpy(sg_out, sg_in, nents_in*(sizeof(struct metal_sg)));
131+
for (i = 0; i < nents_in; i++) {
132+
if (dir == METAL_DMA_DEV_W) {
133+
metal_cache_flush(sg_out[i].virt, sg_out[i].len);
134+
}
135+
metal_cache_invalidate(sg_out[i].virt, sg_out[i].len);
136+
}
137+
138+
return nents_in;
139+
}
140+
141+
void metal_generic_dev_dma_unmap(struct metal_bus *bus,
142+
struct metal_device *device,
143+
uint32_t dir,
144+
struct metal_sg *sg,
145+
int nents)
146+
{
147+
(void)bus;
148+
(void)device;
149+
(void)dir;
150+
int i;
151+
152+
for (i = 0; i < nents; i++) {
153+
metal_cache_invalidate(sg[i].virt, sg[i].len);
154+
}
155+
}
156+
157+
struct metal_bus metal_weak metal_generic_bus = {
158+
.name = "generic",
159+
.ops = {
160+
.bus_close = NULL,
161+
.dev_open = metal_generic_dev_open,
162+
.dev_close = NULL,
163+
.dev_irq_ack = NULL,
164+
.dev_dma_map = metal_generic_dev_dma_map,
165+
.dev_dma_unmap = metal_generic_dev_dma_unmap,
166+
},
167+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#define LED_BUILTIN (16*('I'-'A')+15)
2+
3+
extern "C" {
4+
#define boolean boolean_t
5+
#include "openamp.h"
6+
}
7+
8+
#define RPMSG_SERVICE_NAME "openamp_cm4_serial"
9+
10+
static uint32_t message;
11+
static volatile int message_received;
12+
static volatile unsigned int received_data;
13+
14+
static struct rpmsg_endpoint rp_endpoint;
15+
16+
HSEM_TypeDef * HSEM_DEBUG = HSEM;
17+
18+
static int rpmsg_recv_callback(struct rpmsg_endpoint *ept, void *data,
19+
size_t len, uint32_t src, void *priv)
20+
{
21+
received_data = *((unsigned int *) data);
22+
message_received = 1;
23+
24+
if (received_data == 0x7F7F7F7F) {
25+
NVIC_SystemReset();
26+
}
27+
28+
return 0;
29+
}
30+
31+
unsigned int receive_message(void)
32+
{
33+
while (message_received == 0)
34+
{
35+
OPENAMP_check_for_message();
36+
}
37+
message_received = 0;
38+
39+
return received_data;
40+
}
41+
42+
void setup()
43+
{
44+
int32_t status = 0;
45+
46+
#if 1
47+
/*HW semaphore Clock enable*/
48+
__HAL_RCC_HSEM_CLK_ENABLE();
49+
/*HW semaphore Notification enable*/
50+
HAL_HSEM_ActivateNotification(__HAL_HSEM_SEMID_TO_MASK(HSEM_ID_0));
51+
52+
/* Inilitize the mailbox use notify the other core on new message */
53+
MAILBOX_Init();
54+
55+
/* Inilitize OpenAmp and libmetal libraries */
56+
if (MX_OPENAMP_Init(RPMSG_REMOTE, NULL) != 0) {
57+
while (1) {}
58+
}
59+
60+
/* create a endpoint for rmpsg communication */
61+
status = OPENAMP_create_endpoint(&rp_endpoint, RPMSG_SERVICE_NAME, RPMSG_ADDR_ANY,
62+
rpmsg_recv_callback, NULL);
63+
if (status < 0)
64+
{
65+
while (1) {}
66+
}
67+
#endif
68+
69+
pinMode(LED_BUILTIN, OUTPUT);
70+
}
71+
72+
// the loop function runs over and over again forever
73+
void loop() {
74+
75+
#if 1
76+
OPENAMP_check_for_message();
77+
message++;
78+
OPENAMP_send(&rp_endpoint, &message, sizeof(message));
79+
#endif
80+
81+
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
82+
delay(1000); // wait for a second
83+
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
84+
delay(1000); // wait for a second
85+
}

libraries/OpenAMP/generic_device.c

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2017, Xilinx Inc. and Contributors. All rights reserved.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
/*
8+
* @file generic/device.c
9+
* @brief Generic libmetal device operations.
10+
*/
11+
12+
#include <metal/device.h>
13+
#include <metal/io.h>
14+
#include <metal/sys.h>
15+
#include <metal/utilities.h>
16+
17+
int metal_generic_dev_sys_open(struct metal_device *dev)
18+
{
19+
struct metal_io_region *io;
20+
unsigned i;
21+
22+
/* map I/O memory regions */
23+
for (i = 0; i < dev->num_regions; i++) {
24+
io = &dev->regions[i];
25+
if (!io->size)
26+
break;
27+
metal_sys_io_mem_map(io);
28+
}
29+
30+
return 0;
31+
}
32+

libraries/OpenAMP/generic_init.c

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
/*
8+
* @file generic/init.c
9+
* @brief Generic libmetal initialization.
10+
*/
11+
12+
#include <metal/sys.h>
13+
#include <metal/utilities.h>
14+
#include <metal/device.h>
15+
16+
struct metal_state _metal;
17+
18+
int metal_sys_init(const struct metal_init_params *params)
19+
{
20+
metal_unused(params);
21+
metal_bus_register(&metal_generic_bus);
22+
return 0;
23+
}
24+
25+
void metal_sys_finish(void)
26+
{
27+
metal_bus_unregister(&metal_generic_bus);
28+
}

0 commit comments

Comments
 (0)