blob: 556dcc25b44ac6a5ae526c15ec84a4a83c6492f4 [file] [log] [blame]
/*
* Copyright (c) 2018, NXP
* Copyright (c) 2018, Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*
* This implements the master side of an OpenAMP system.
*/
#include <zephyr.h>
#include <misc/printk.h>
#include <device.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openamp/open_amp.h>
#include "platform.h"
#include "resource_table.h"
#define APP_TASK_STACK_SIZE (512)
K_THREAD_STACK_DEFINE(thread_stack, APP_TASK_STACK_SIZE);
static struct k_thread thread_data;
static struct rpmsg_channel *rp_channel;
static struct rpmsg_endpoint *rp_endpoint;
static K_SEM_DEFINE(channel_created, 0, 1);
static K_SEM_DEFINE(message_received, 0, 1);
static volatile unsigned int received_data;
static struct rsc_table_info rsc_info;
static struct hil_proc *proc;
static void rpmsg_recv_callback(struct rpmsg_channel *channel, void *data,
int data_length, void *private,
unsigned long src)
{
received_data = *((unsigned int *) data);
k_sem_give(&message_received);
}
static void rpmsg_channel_created(struct rpmsg_channel *channel)
{
rp_channel = channel;
rp_endpoint = rpmsg_create_ept(rp_channel, rpmsg_recv_callback,
RPMSG_NULL, RPMSG_ADDR_ANY);
k_sem_give(&channel_created);
}
static void rpmsg_channel_deleted(struct rpmsg_channel *channel)
{
rpmsg_destroy_ept(rp_endpoint);
}
static unsigned int receive_message(void)
{
while (k_sem_take(&message_received, K_NO_WAIT) != 0)
hil_poll(proc, 0);
return received_data;
}
static int send_message(unsigned int message)
{
return rpmsg_send(rp_channel, &message, sizeof(message));
}
void app_task(void *arg1, void *arg2, void *arg3)
{
ARG_UNUSED(arg1);
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
printk("\r\nOpenAMP demo started\r\n");
struct metal_init_params metal_params = METAL_INIT_DEFAULTS;
metal_init(&metal_params);
proc = platform_init(RPMSG_MASTER);
if (proc == NULL) {
printk("platform_init() failed\n");
goto _cleanup;
}
resource_table_init((void **) &rsc_info.rsc_tab, &rsc_info.size);
struct remote_proc *rproc_ptr = NULL;
int status = remoteproc_resource_init(&rsc_info, proc,
rpmsg_channel_created,
rpmsg_channel_deleted,
rpmsg_recv_callback,
&rproc_ptr, RPMSG_MASTER);
if (status != 0) {
printk("remoteproc_resource_init() failed with status %d\n",
status);
goto _cleanup;
}
while (k_sem_take(&channel_created, K_NO_WAIT) != 0)
hil_poll(proc, 0);
unsigned int message = 0;
status = send_message(message);
if (status < 0) {
printk("send_message(%d) failed with status %d\n",
message, status);
goto _cleanup;
}
while (message <= 100) {
message = receive_message();
printk("Primary core received a message: %d\n", message);
message++;
status = send_message(message);
if (status < 0) {
printk("send_message(%d) failed with status %d\n",
message, status);
goto _cleanup;
}
}
_cleanup:
if (rproc_ptr) {
remoteproc_resource_deinit(rproc_ptr);
}
metal_finish();
printk("OpenAMP demo ended.\n");
}
void main(void)
{
printk("Starting application thread!\n");
k_thread_create(&thread_data, thread_stack, APP_TASK_STACK_SIZE,
(k_thread_entry_t)app_task,
NULL, NULL, NULL, K_PRIO_COOP(7), 0, 0);
}