This example demonstrates spawning multiple threads using K_THREAD_DEFINE(). It spawns three threads. Each thread is then defined at compile time using K_THREAD_DEFINE.
The first two each control an LED. These LEDs, led0 and led1, have loop control and timing logic controlled by separate functions.
blink0() controls led0 and has a 100ms sleep cycle
blink1() controls led1 and has a 1000ms sleep cycle
When either of these threads toggles its LED, it also pushes information into a FIFO identifying the thread/LED and how many times it has been toggled.
The third thread uses printk() to print the information added to the FIFO to the device console.
The board must have two LEDs connected via GPIO pins. These are called “User LEDs” on many of Zephyr’s Supported Boards. The LEDs must be configured using the led0 and led1devicetree aliases, usually in the BOARD.dts file.
west build -b 96b_carbon samples/basic/threads
west flash
Code
/* * Copyright (c) 2017 Linaro Limited * * SPDX-License-Identifier: Apache-2.0 */#include<zephyr/kernel.h>#include<zephyr/device.h>#include<zephyr/drivers/gpio.h>#include<zephyr/sys/printk.h>#include<zephyr/sys/__assert.h>#include<string.h>/* size of stack area used by each thread */#defineSTACKSIZE1024/* scheduling priority used by each thread */#definePRIORITY7#defineLED0_NODEDT_ALIAS(led0)#defineLED1_NODEDT_ALIAS(led1)#if!DT_NODE_HAS_STATUS(LED0_NODE, okay)#error"Unsupported board: led0 devicetree alias is not defined"#endif#if!DT_NODE_HAS_STATUS(LED1_NODE, okay)#error"Unsupported board: led1 devicetree alias is not defined"#endifstructprintk_data_t {void*fifo_reserved; /* 1st word reserved for use by fifo */uint32_t led;uint32_t cnt;};K_FIFO_DEFINE(printk_fifo);struct led {struct gpio_dt_spec spec;uint8_t num;};staticconststruct led led0 = { .spec =GPIO_DT_SPEC_GET_OR(LED0_NODE, gpios, {0}), .num =0,};staticconststruct led led1 = { .spec =GPIO_DT_SPEC_GET_OR(LED1_NODE, gpios, {0}), .num =1,};voidblink(conststruct led *led,uint32_t sleep_ms,uint32_t id){conststruct gpio_dt_spec *spec =&led->spec;int cnt =0;int ret;if (!device_is_ready(spec->port)) {printk("Error: %s device is not ready\n",spec->port->name);return; } ret =gpio_pin_configure_dt(spec, GPIO_OUTPUT);if (ret !=0) {printk("Error %d: failed to configure pin %d (LED '%d')\n", ret,spec->pin,led->num);return; }while (1) {gpio_pin_set(spec->port,spec->pin, cnt %2);structprintk_data_t tx_data = { .led = id, .cnt = cnt };size_t size =sizeof(structprintk_data_t);char*mem_ptr =k_malloc(size);__ASSERT_NO_MSG(mem_ptr !=0);memcpy(mem_ptr,&tx_data, size);k_fifo_put(&printk_fifo, mem_ptr);k_msleep(sleep_ms); cnt++; }}voidblink0(void){blink(&led0,100,0);}voidblink1(void){blink(&led1,1000,1);}voiduart_out(void){while (1) {structprintk_data_t*rx_data =k_fifo_get(&printk_fifo, K_FOREVER);printk("Toggled led%d; counter=%d\n",rx_data->led,rx_data->cnt);k_free(rx_data); }}K_THREAD_DEFINE(blink0_id, STACKSIZE, blink0,NULL,NULL,NULL, PRIORITY,0,0);K_THREAD_DEFINE(blink1_id, STACKSIZE, blink1,NULL,NULL,NULL, PRIORITY,0,0);K_THREAD_DEFINE(uart_out_id, STACKSIZE, uart_out,NULL,NULL,NULL, PRIORITY,0,0);