samples: net: echo-server: Add userspace support

Allow echo-server to start TCP/UDP threads in user mode for
testing purposes.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2020-06-03 09:14:41 +03:00
commit db9dca059e
5 changed files with 87 additions and 20 deletions

View file

@ -58,3 +58,6 @@ tests:
extra_args: OVERLAY_CONFIG="overlay-smsc911x.conf"
tags: net
platform_whitelist: mps2_an385
sample.net.sockets.echo_server.userspace:
extra_args: CONFIG_USERSPACE=y OVERLAY_CONFIG="overlay-e1000.conf"
platform_whitelist: qemu_x86

View file

@ -16,6 +16,17 @@
#define THREAD_PRIORITY K_PRIO_COOP(8)
#define RECV_BUFFER_SIZE 1280
#if defined(CONFIG_USERSPACE)
#include <app_memory/app_memdomain.h>
extern struct k_mem_partition app_partition;
extern struct k_mem_domain app_domain;
#define APP_BMEM K_APP_BMEM(app_partition)
#define APP_DMEM K_APP_DMEM(app_partition)
#else
#define APP_BMEM
#define APP_DMEM
#endif
struct data {
const char *proto;

View file

@ -33,10 +33,15 @@ static bool connected;
K_SEM_DEFINE(run_app, 0, 1);
static bool want_to_quit;
#if defined(CONFIG_USERSPACE)
K_APPMEM_PARTITION_DEFINE(app_partition);
struct k_mem_domain app_domain;
#endif
#define EVENT_MASK (NET_EVENT_L4_CONNECTED | \
NET_EVENT_L4_DISCONNECTED)
struct configs conf = {
APP_DMEM struct configs conf = {
.ipv4 = {
.proto = "IPv4",
},
@ -113,10 +118,22 @@ static void event_handler(struct net_mgmt_event_callback *cb,
static void init_app(void)
{
#if defined(CONFIG_USERSPACE)
struct k_mem_partition *parts[] = {
#if Z_LIBC_PARTITION_EXISTS
&z_libc_partition,
#endif
&app_partition
};
k_mem_domain_init(&app_domain, ARRAY_SIZE(parts), parts);
#endif
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) || \
defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
int err;
#endif
k_sem_init(&quit_lock, 0, UINT_MAX);
LOG_INF(APP_BANNER);

View file

@ -26,16 +26,14 @@ LOG_MODULE_DECLARE(net_echo_server_sample, LOG_LEVEL_DBG);
K_THREAD_STACK_ARRAY_DEFINE(tcp4_handler_stack, CONFIG_NET_SAMPLE_NUM_HANDLERS,
STACK_SIZE);
static struct k_thread tcp4_handler_thread[CONFIG_NET_SAMPLE_NUM_HANDLERS];
static k_tid_t tcp4_handler_tid[CONFIG_NET_SAMPLE_NUM_HANDLERS];
static bool tcp4_handler_in_use[CONFIG_NET_SAMPLE_NUM_HANDLERS];
static APP_BMEM bool tcp4_handler_in_use[CONFIG_NET_SAMPLE_NUM_HANDLERS];
#endif
#if defined(CONFIG_NET_IPV6)
K_THREAD_STACK_ARRAY_DEFINE(tcp6_handler_stack, CONFIG_NET_SAMPLE_NUM_HANDLERS,
STACK_SIZE);
static struct k_thread tcp6_handler_thread[CONFIG_NET_SAMPLE_NUM_HANDLERS];
static k_tid_t tcp6_handler_tid[CONFIG_NET_SAMPLE_NUM_HANDLERS];
static bool tcp6_handler_in_use[CONFIG_NET_SAMPLE_NUM_HANDLERS];
static APP_BMEM bool tcp6_handler_in_use[CONFIG_NET_SAMPLE_NUM_HANDLERS];
#endif
static void process_tcp4(void);
@ -43,11 +41,13 @@ static void process_tcp6(void);
K_THREAD_DEFINE(tcp4_thread_id, STACK_SIZE,
process_tcp4, NULL, NULL, NULL,
THREAD_PRIORITY, 0, -1);
THREAD_PRIORITY,
IS_ENABLED(CONFIG_USERSPACE) ? K_USER : 0, -1);
K_THREAD_DEFINE(tcp6_thread_id, STACK_SIZE,
process_tcp6, NULL, NULL, NULL,
THREAD_PRIORITY, 0, -1);
THREAD_PRIORITY,
IS_ENABLED(CONFIG_USERSPACE) ? K_USER : 0, -1);
static ssize_t sendall(int sock, const void *buf, size_t len)
{
@ -238,14 +238,16 @@ static int process_tcp(struct data *data)
if (client_addr.sin_family == AF_INET6) {
tcp6_handler_in_use[slot] = true;
tcp6_handler_tid[slot] = k_thread_create(
k_thread_create(
&tcp6_handler_thread[slot],
tcp6_handler_stack[slot],
K_THREAD_STACK_SIZEOF(tcp6_handler_stack[slot]),
(k_thread_entry_t)handle_data,
INT_TO_POINTER(slot), data, &tcp6_handler_in_use[slot],
THREAD_PRIORITY,
0, K_NO_WAIT);
IS_ENABLED(CONFIG_USERSPACE) ? K_USER |
K_INHERIT_PERMS : 0,
K_NO_WAIT);
}
#endif
@ -253,14 +255,16 @@ static int process_tcp(struct data *data)
if (client_addr.sin_family == AF_INET) {
tcp4_handler_in_use[slot] = true;
tcp4_handler_tid[slot] = k_thread_create(
k_thread_create(
&tcp4_handler_thread[slot],
tcp4_handler_stack[slot],
K_THREAD_STACK_SIZEOF(tcp4_handler_stack[slot]),
(k_thread_entry_t)handle_data,
INT_TO_POINTER(slot), data, &tcp4_handler_in_use[slot],
THREAD_PRIORITY,
0, K_NO_WAIT);
IS_ENABLED(CONFIG_USERSPACE) ? K_USER |
K_INHERIT_PERMS : 0,
K_NO_WAIT);
}
#endif
@ -335,13 +339,35 @@ void start_tcp(void)
#endif
}
if (IS_ENABLED(CONFIG_NET_IPV6)) {
k_thread_start(tcp6_thread_id);
}
#if defined(CONFIG_NET_IPV6)
#if defined(CONFIG_USERSPACE)
k_mem_domain_add_thread(&app_domain, tcp6_thread_id);
if (IS_ENABLED(CONFIG_NET_IPV4)) {
k_thread_start(tcp4_thread_id);
for (i = 0; i < CONFIG_NET_SAMPLE_NUM_HANDLERS; i++) {
k_mem_domain_add_thread(&app_domain, &tcp6_handler_thread[i]);
k_thread_access_grant(tcp6_thread_id, &tcp6_handler_thread[i]);
k_thread_access_grant(tcp6_thread_id, &tcp6_handler_stack[i]);
}
#endif
k_thread_start(tcp6_thread_id);
#endif
#if defined(CONFIG_NET_IPV4)
#if defined(CONFIG_USERSPACE)
k_mem_domain_add_thread(&app_domain, tcp4_thread_id);
for (i = 0; i < CONFIG_NET_SAMPLE_NUM_HANDLERS; i++) {
k_mem_domain_add_thread(&app_domain, &tcp4_handler_thread[i]);
k_thread_access_grant(tcp4_thread_id, &tcp4_handler_thread[i]);
k_thread_access_grant(tcp4_thread_id, &tcp4_handler_stack[i]);
}
#endif
k_thread_start(tcp4_thread_id);
#endif
}
void stop_tcp(void)
@ -361,7 +387,7 @@ void stop_tcp(void)
for (i = 0; i < CONFIG_NET_SAMPLE_NUM_HANDLERS; i++) {
#if defined(CONFIG_NET_IPV6)
if (tcp6_handler_in_use[i] == true) {
k_thread_abort(tcp6_handler_tid[i]);
k_thread_abort(&tcp6_handler_thread[i]);
}
#endif
if (conf.ipv6.tcp.accepted[i].sock >= 0) {
@ -379,7 +405,7 @@ void stop_tcp(void)
for (i = 0; i < CONFIG_NET_SAMPLE_NUM_HANDLERS; i++) {
#if defined(CONFIG_NET_IPV4)
if (tcp4_handler_in_use[i] == true) {
k_thread_abort(tcp4_handler_tid[i]);
k_thread_abort(&tcp4_handler_thread[i]);
}
#endif
if (conf.ipv4.tcp.accepted[i].sock >= 0) {

View file

@ -25,11 +25,13 @@ static void process_udp6(void);
K_THREAD_DEFINE(udp4_thread_id, STACK_SIZE,
process_udp4, NULL, NULL, NULL,
THREAD_PRIORITY, 0, -1);
THREAD_PRIORITY,
IS_ENABLED(CONFIG_USERSPACE) ? K_USER : 0, -1);
K_THREAD_DEFINE(udp6_thread_id, STACK_SIZE,
process_udp6, NULL, NULL, NULL,
THREAD_PRIORITY, 0, -1);
THREAD_PRIORITY,
IS_ENABLED(CONFIG_USERSPACE) ? K_USER : 0, -1);
static int start_udp_proto(struct data *data, struct sockaddr *bind_addr,
socklen_t bind_addrlen)
@ -187,10 +189,18 @@ static void process_udp6(void)
void start_udp(void)
{
if (IS_ENABLED(CONFIG_NET_IPV6)) {
#if defined(CONFIG_USERSPACE)
k_mem_domain_add_thread(&app_domain, udp6_thread_id);
#endif
k_thread_start(udp6_thread_id);
}
if (IS_ENABLED(CONFIG_NET_IPV4)) {
#if defined(CONFIG_USERSPACE)
k_mem_domain_add_thread(&app_domain, udp4_thread_id);
#endif
k_thread_start(udp4_thread_id);
}
}