Skip to content

Commit

Permalink
samples: drivers: ipm: added esp32 sample
Browse files Browse the repository at this point in the history
code to demonstrate the utilization of assymetric
dual core infrastructure based on soft-IPM implementation.

Signed-off-by: Felipe Neves <felipe.neves@linaro.org>
  • Loading branch information
uLipe authored and carlescufi committed Aug 16, 2022
1 parent 4bff7ec commit 0e17b83
Show file tree
Hide file tree
Showing 9 changed files with 1,871 additions and 0 deletions.
8 changes: 8 additions & 0 deletions samples/drivers/ipm/ipm_esp32/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(ipm_esp32)

target_sources(app PRIVATE src/main.c src/esp32_net_firmware.c)
62 changes: 62 additions & 0 deletions samples/drivers/ipm/ipm_esp32/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.. _ipm_esp32:

ESP32 Soft-IPM example
######################

Overview
********
This simple example can be used with multicore ESP32 Soc, and demonstrates
the software intercore messaging mechanism to be used in AMP applications.

ESP32 has two CPU named APP and PRO, in this simple example PRO send a
message to the APP using the IPM driver, and waits for the APP response
message and prints its contents on console.

ESP32 intercore messaging has up two four channels, the 0 and 1 are
reserved for BT and WIFI messages, and channels 2 and 3 is free to
any application, each channel supports up to 64 bytes of data per
message, so high level protocol is responsible to fragment larger
messages in chunks of 64bytes.

Building and Running the Zephyr Code
************************************

The sample requires two build commands to run, for that reason a pre built
version of esp32_net, the APP cpu side firmware is already provided for quick
tests just type on the console:

.. zephyr-app-commands::
:zephyr-app: samples/drivers/ipm/ipm_esp32
:board: esp32
:goals: build flash
:compact:

The other option is building from scratch just involve a single extra build command
and file moving, first of all you need to build the esp32_net firmware as follows:

.. zephyr-app-commands::
:zephyr-app: samples/drivers/ipm/ipm_esp32/ipm_esp32_net
:board: esp32_net
:goals: build
:compact:

Copy output file build/zephyr/esp32_net_firmware.c to samples/drivers/ipm/ipm_esp32/src,
then build the main project and flash as stated earlier, and you would see the following output:

.. code-block:: console
*** Booting Zephyr OS build zephyr-v3.0.0-1911-g610f489c861e ***
PRO_CPU is sending a fake request, waiting remote response...
PRO_CPU received a message from APP_CPU : APP_CPU: This is a response
PRO_CPU is sending a fake request, waiting remote response...
PRO_CPU received a message from APP_CPU : APP_CPU: This is a response
PRO_CPU is sending a fake request, waiting remote response...
PRO_CPU received a message from APP_CPU : APP_CPU: This is a response
PRO_CPU is sending a fake request, waiting remote response...
PRO_CPU received a message from APP_CPU : APP_CPU: This is a response
PRO_CPU is sending a fake request, waiting remote response...
PRO_CPU received a message from APP_CPU : APP_CPU: This is a response
PRO_CPU is sending a fake request, waiting remote response...
PRO_CPU received a message from APP_CPU : APP_CPU: This is a response
PRO_CPU is sending a fake request, waiting remote response...
PRO_CPU received a message from APP_CPU : APP_CPU: This is a response
8 changes: 8 additions & 0 deletions samples/drivers/ipm/ipm_esp32/ipm_esp32_net/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(ipm_esp32_net)

target_sources(app PRIVATE src/main.c)
4 changes: 4 additions & 0 deletions samples/drivers/ipm/ipm_esp32/ipm_esp32_net/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CONFIG_HEAP_MEM_POOL_SIZE=256
CONFIG_IPM=y
CONFIG_ESP32_SOFT_IPM=y
CONFIG_KERNEL_BIN_NAME="esp32_net_firmware"
37 changes: 37 additions & 0 deletions samples/drivers/ipm/ipm_esp32/ipm_esp32_net/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr.h>
#include <sys/printk.h>
#include <drivers/ipm.h>
#include <device.h>

static const struct device *ipm_dev;
static const char fake_resp[] = {"APP_CPU: This is a response"};
struct k_sem sync;

static void ipm_receive_callback(const struct device *ipmdev, void *user_data,
uint32_t id, volatile void *data)
{
k_sem_give(&sync);
}

void main(void)
{
k_sem_init(&sync, 0, 1);

ipm_dev = DEVICE_DT_GET(DT_NODELABEL(ipm0));
if (!ipm_dev) {
printk("Failed to get IPM device.\n\r");
}

ipm_register_callback(ipm_dev, ipm_receive_callback, NULL);

while (1) {
k_sem_take(&sync, K_FOREVER);
ipm_send(ipm_dev, -1, sizeof(fake_resp), &fake_resp, sizeof(fake_resp));
}
}
4 changes: 4 additions & 0 deletions samples/drivers/ipm/ipm_esp32/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CONFIG_ESP32_NETWORK_CORE=y
CONFIG_IPM=y
CONFIG_ESP32_SOFT_IPM=y
CONFIG_LOG=y
6 changes: 6 additions & 0 deletions samples/drivers/ipm/ipm_esp32/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sample:
name: ESP32 IPM Sample
tests:
sample.ipm.ipm_esp32:
platform_allow: esp32
tags: samples ipm
1,692 changes: 1,692 additions & 0 deletions samples/drivers/ipm/ipm_esp32/src/esp32_net_firmware.c

Large diffs are not rendered by default.

50 changes: 50 additions & 0 deletions samples/drivers/ipm/ipm_esp32/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr.h>
#include <sys/printk.h>
#include <drivers/ipm.h>
#include <device.h>
#include <string.h>

static const char fake_request[] = {"PRO_CPU: Fake request to APP_CPU"};

static const struct device *ipm_dev;
static char received_string[64];
static struct k_sem sync;

static void ipm_receive_callback(const struct device *ipmdev, void *user_data,
uint32_t id, volatile void *data)
{
ARG_UNUSED(ipmdev);
ARG_UNUSED(user_data);

strcpy(received_string, (const char *)data);
k_sem_give(&sync);
}

void main(void)
{
k_sem_init(&sync, 0, 1);

ipm_dev = DEVICE_DT_GET(DT_NODELABEL(ipm0));
if (!ipm_dev) {
printk("Failed to get IPM device.\n\r");
}

ipm_register_callback(ipm_dev, ipm_receive_callback, NULL);

while (1) {
printk("PRO_CPU is sending a fake request, waiting remote response...\n\r");

ipm_send(ipm_dev, -1, sizeof(fake_request), &fake_request, sizeof(fake_request));
k_sem_take(&sync, K_FOREVER);

printk("PRO_CPU received a message from APP_CPU : %s\n\r", received_string);

k_sleep(K_MSEC(200));
}
}

0 comments on commit 0e17b83

Please sign in to comment.