Getting Started

This guide walks through setting up a workspace, building your first POSIX application on Zephyr, and running it on a simulator or real hardware.

Prerequisites

Set up the workspace

# Create and activate a Python virtual environment
python3 -m venv ~/posix-next/.venv
source ~/posix-next/.venv/bin/activate
pip install west

# Create a new west workspace with posix-next as the manifest repo
west init -m https://github.com/cfriedt/posix-next --mr main ~/posix-next
cd ~/posix-next
west update

# Re-home the manifest repo to modules/lib/posix (to workaround a bug in west)
mv posix-next modules/lib/posix
sed -i 's|manifest/path:.*|manifest/path = modules/lib/posix|' .west/config

Install the Zephyr SDK

If you already have a Zephyr SDK installed, point the appropriate environment variables to it:

export ZEPHYR_BASE=$HOME/posix-next/zephyr
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
export ZEPHYR_SDK_INSTALL_DIR=/path/to/zephyr-sdk

Otherwise, install the SDK using west:

west sdk install

Hello, POSIX world!

A primary goal for Zephyr’s POSIX implementation is to ensure that POSIX APIs can be used portably, with as few source modifications as possible. This sample uses automatic thread allocation as well as automatic thread stack allocation to conform to standard POSIX API usage.

/*
 * Copyright (c) The Zephyr Project Contributors
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <pthread.h>
#include <stdio.h>
#include <stdint.h>

static void *worker(void *arg)
{
	printf("Hello World! %s from pthread_t %p\n", CONFIG_BOARD_TARGET,
	       (void *)(uintptr_t)pthread_self());

	return (void *)(intptr_t)42;
}

int main(void)
{
	void *res;
	pthread_t tid;

	pthread_create(&tid, NULL, worker, NULL);
	pthread_join(tid, &res);

	printf("pthread_t returned %d\n", (int)(intptr_t)res);

	return 0;
}

Build and run

To build and run on a simulator such as native_sim or qemu_riscv64:

west build -b native_sim -t run samples/posix/hello_world

To build and run on real hardware, first build the application, then flash it:

west build -b <your_board> samples/posix/hello_world
west flash

Expected output:

*** Booting Zephyr OS build v4.3.0 ***
Hello World! native_sim/native from pthread_t 0x8058400
pthread_t returned 42

Hello, Zephyr world!

Some Zephyr applications do not use automatic thread or thread-stack allocation because it can be viewed as a form of dynamic memory allocation. Dynamic memory allocation is prohibited by some industry standards for safety reasons. Supporting those applications with as few pain points as possible is of paramount importance for both The Zephyr Project and Zephyr’s POSIX reference implementation.

Although the POSIX API does not directly support operations on pre-initialized threads or threading primitives, posix-next has moved to a model where there is a 1:1 correspondence between Zephyr and POSIX threading primitives:

  • k_condvar <=> pthread_cond_t

  • k_mutex <=> pthread_mutex_t

  • k_thread <=> pthread_t

With that, converting between Zephyr and POSIX threading primitives is as simple as a pointer cast.

/*
 * Copyright (c) The Zephyr Project Contributors
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <pthread.h>
#include <stdio.h>

#include <zephyr/kernel.h>

void worker_entry(void *p1, void *p2, void *p3)
{
	printf("Hello World! %s from k_thread %p\n", CONFIG_BOARD_TARGET, k_current_get());

	/* Zephyr's native threading API still does not support a direct return value */
	k_thread_result_set(INT_TO_POINTER(42));
}

K_THREAD_DEFINE(kth, 2048, worker_entry, NULL, NULL, NULL, K_LOWEST_APPLICATION_THREAD_PRIO,
		0, SYS_FOREVER_MS);

int main(void)
{
	void *res;
	pthread_t th = (pthread_t)(uintptr_t)kth;

	k_thread_start(kth);
	pthread_join(th, &res);

	printf("k_thread returned %d\n", (int)POINTER_TO_INT(res));

	return 0;
}

Build and run

west build -b native_sim -t run samples/posix/hello_zephyr

To build for real hardware, substitute the board name:

west build -b <your_board> samples/posix/hello_zephyr
west flash

Expected output:

*** Booting Zephyr OS build v4.3.0 ***
Hello World! native_sim/native from k_thread 0x8057420
k_thread returned 42

Build documentation locally

Building documentation for posix-next follows the same process as Zephyr. Before continuing, please ensure that all Zephyr documentation build requirements are met.

cmake -GNinja -Bdoc/_build doc
ninja -C doc/_build html
python3 -m http.server -d doc/_build/html --bind 127.0.0.1