samples: Add mctp host and client samples

Samples work by sending MCTP encoded messages over a uart between two
boards.

Signed-off-by: Tom Burdick <thomas.burdick@intel.com>
This commit is contained in:
Tom Burdick 2024-08-14 09:03:11 -05:00 committed by Henrik Brix Andersen
parent 4148512567
commit be4a3d91e1
11 changed files with 252 additions and 0 deletions

View file

@ -0,0 +1,5 @@
.. zephyr:code-sample-category:: mctp
:name: MCTP
:show-listing:
These samples demonstrate how to build communicating firmwares using MCTP in Zephyr.

View file

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(mctp_endpoint)
target_sources(app PRIVATE src/main.c)

View file

@ -0,0 +1,41 @@
.. zephyr:code-sample:: mctp_endpoint_sample
:name: MCTP Endpoint Sample
Create an MCTP endpoint over UART.
Overview
********
Sets up an MCTP node that listens on a UART for messages targeting a particular
MCTP endpoint id with the message "hello". Responds to this "hello" message with
"world".
Requirements
************
A board and SoC that provide access to a UART and a driver that implements the
UART async API.
Wiring
******
The listening UART pins should be wired to a board which will run the MCTP host
sample such that this board's UART tx pin connects to the host board's rx pin,
and this board's UART rx pin connects to the host board's tx pin. The boards'
grounds should also be wired together.
Optionally a logic analyzer can be wired up and listening to the UART to inspect
the data flowing.
Building and Running
********************
.. zephyr-app-commands::
:zephyr-app: samples/modules/mctp/mctp_endpoint
:host-os: unix
:board: nrf52840_nrf52840dk
:goals: run
:compact:
References
**********
`MCTP Base Specification 2019 <https://www.dmtf.org/sites/default/files/standards/documents/DSP0236_1.3.1.pdf>`_

View file

@ -0,0 +1,3 @@
&arduino_serial{
status = "okay";
};

View file

@ -0,0 +1,8 @@
CONFIG_SERIAL=y
CONFIG_UART_ASYNC_API=y
CONFIG_MCTP=y
CONFIG_MCTP_UART=y
CONFIG_LOG=y
CONFIG_LOG_BUFFER_SIZE=4096
CONFIG_MCTP_LOG_LEVEL_DBG=y
CONFIG_ISR_STACK_SIZE=4096

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2024 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <zephyr/kernel.h>
#include <zephyr/types.h>
#include <zephyr/mctp/mctp_uart.h>
#include <libmctp.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(mctp_endpoint);
#include <zephyr/drivers/uart.h>
static struct mctp *mctp_ctx;
#define LOCAL_HELLO_EID 10
#define REMOTE_HELLO_EID 20
K_SEM_DEFINE(mctp_rx, 0, 1);
static void rx_message(uint8_t eid, bool tag_owner, uint8_t msg_tag, void *data, void *msg,
size_t len)
{
switch (eid) {
case REMOTE_HELLO_EID:
LOG_INF("got mctp message %s for eid %d, replying to 5 with \"world\"", (char *)msg,
eid);
mctp_message_tx(mctp_ctx, LOCAL_HELLO_EID, false, 0, "world", sizeof("world"));
break;
default:
LOG_INF("Unknown endpoint %d", eid);
break;
}
k_sem_give(&mctp_rx);
}
MCTP_UART_DT_DEFINE(mctp_endpoint, DEVICE_DT_GET(DT_NODELABEL(arduino_serial)));
#define RX_BUF_SZ 128
int main(void)
{
LOG_INF("MCTP Endpoint EID:%d on %s\n", LOCAL_HELLO_EID, CONFIG_BOARD_TARGET);
mctp_set_alloc_ops(malloc, free, realloc);
mctp_ctx = mctp_init();
__ASSERT_NO_MSG(mctp_ctx != NULL);
mctp_register_bus(mctp_ctx, &mctp_endpoint.binding, LOCAL_HELLO_EID);
mctp_set_rx_all(mctp_ctx, rx_message, NULL);
/* MCTP poll loop */
while (true) {
mctp_uart_start_rx(&mctp_endpoint);
k_sem_take(&mctp_rx, K_FOREVER);
}
LOG_INF("exiting");
return 0;
}

View file

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(mctp_host)
target_sources(app PRIVATE src/main.c)

View file

@ -0,0 +1,40 @@
.. zephyr:code-sample:: mctp_host_sample
:name: MCTP Host Sample
Create an MCTP host over UART.
Overview
********
Sets up an MCTP node that sends a request on a UART targeting a particular MCTP
endpoint id with the message "hello". Expects and waits for a response to this
"hello" message containing "world".
Requirements
************
A board and SoC that provide access to a UART and a driver that implements the
UART async API.
Wiring
******
The UART pins should be wired to a board which will run the MCTP endpoint
sample such that this board's UART tx pin connects to the endpoint board's rx
pin, and this board's UART rx pin connects to the endpoint board's tx pin. The
boards' grounds should also be wired together.
Optionally a logic analyzer can be wired up and listening to the UART to inspect
the data flowing.
Building and Running
********************
.. zephyr-app-commands::
:zephyr-app: samples/modules/mctp/mctp_host
:host-os: unix
:board: nrf52840_nrf52840dk
:goals: run
:compact:
References
**********
`MCTP Base Specification 2019 <https://www.dmtf.org/sites/default/files/standards/documents/DSP0236_1.3.1.pdf>`_

View file

@ -0,0 +1,3 @@
&arduino_serial{
status = "okay";
};

View file

@ -0,0 +1,8 @@
# nothing here
CONFIG_SERIAL=y
CONFIG_UART_ASYNC_API=y
CONFIG_MCTP=y
CONFIG_MCTP_UART=y
CONFIG_MCTP_LOG_LEVEL_DBG=y
CONFIG_LOG=y
CONFIG_LOG_BUFFER_SIZE=4096

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2024 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <zephyr/types.h>
#include <zephyr/kernel.h>
#include <libmctp.h>
#include <zephyr/mctp/mctp_uart.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(mctp_host);
#define LOCAL_HELLO_EID 20
#define REMOTE_HELLO_EID 10
K_SEM_DEFINE(mctp_rx, 0, 1);
static void rx_message(uint8_t eid, bool tag_owner, uint8_t msg_tag, void *data, void *msg,
size_t len)
{
LOG_INF("received message %s for endpoint %d, msg_tag %d, len %zu", (char *)msg, eid,
msg_tag, len);
k_sem_give(&mctp_rx);
}
MCTP_UART_DT_DEFINE(mctp_host, DEVICE_DT_GET(DT_NODELABEL(arduino_serial)));
int main(void)
{
int rc;
struct mctp *mctp_ctx;
LOG_INF("MCTP Host EID:%d on %s\n", LOCAL_HELLO_EID, CONFIG_BOARD_TARGET);
mctp_set_alloc_ops(malloc, free, realloc);
mctp_ctx = mctp_init();
__ASSERT_NO_MSG(mctp_ctx != NULL);
mctp_register_bus(mctp_ctx, &mctp_host.binding, LOCAL_HELLO_EID);
mctp_set_rx_all(mctp_ctx, rx_message, NULL);
mctp_uart_start_rx(&mctp_host);
/* MCTP poll loop, send "hello" and get "world" back */
while (true) {
rc = mctp_message_tx(mctp_ctx, REMOTE_HELLO_EID, false, 0, "hello",
sizeof("hello"));
if (rc != 0) {
LOG_WRN("Failed to send message, errno %d\n", rc);
k_msleep(1000);
} else {
k_sem_take(&mctp_rx, K_MSEC(10));
}
rc = 0;
}
return 0;
}