Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | /* main.c - Hello World demo */ /* * Copyright (c) 2012-2014 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/kernel.h> #include <zephyr/sys/printk.h> /* * The hello world demo has two threads that utilize semaphores and sleeping * to take turns printing a greeting message at a controlled rate. The demo * shows both the static and dynamic approaches for spawning a thread; a real * world application would likely use the static approach for both threads. */ #define PIN_THREADS (IS_ENABLED(CONFIG_SMP) && IS_ENABLED(CONFIG_SCHED_CPU_MASK)) /* size of stack area used by each thread */ #define STACKSIZE 1024 /* scheduling priority used by each thread */ #define PRIORITY 7 /* delay between greetings (in ms) */ #define SLEEPTIME 500 /* * @param my_name thread identification string * @param my_sem thread's own semaphore * @param other_sem other thread's semaphore */ void helloLoop(const char *my_name, struct k_sem *my_sem, struct k_sem *other_sem) { const char *tname; uint8_t cpu; struct k_thread *current_thread; while (1) { /* take my semaphore */ k_sem_take(my_sem, K_FOREVER); current_thread = k_current_get(); tname = k_thread_name_get(current_thread); #if CONFIG_SMP cpu = arch_curr_cpu()->id; #else cpu = 0; #endif /* say "hello" */ if (tname == NULL) { printk("%s: Hello World from cpu %d on %s!\n", my_name, cpu, CONFIG_BOARD); } else { printk("%s: Hello World from cpu %d on %s!\n", tname, cpu, CONFIG_BOARD); } /* wait a while, then let other thread have a turn */ k_busy_wait(100000); k_msleep(SLEEPTIME); k_sem_give(other_sem); } } /* define semaphores */ K_SEM_DEFINE(threadA_sem, 1, 1); /* starts off "available" */ K_SEM_DEFINE(threadB_sem, 0, 1); /* starts off "not available" */ /* threadB is a dynamic thread that is spawned by threadA */ void threadB(void *dummy1, void *dummy2, void *dummy3) { ARG_UNUSED(dummy1); ARG_UNUSED(dummy2); ARG_UNUSED(dummy3); /* invoke routine to ping-pong hello messages with threadA */ helloLoop(__func__, &threadB_sem, &threadA_sem); } K_THREAD_STACK_DEFINE(threadA_stack_area, STACKSIZE); static struct k_thread threadA_data; K_THREAD_STACK_DEFINE(threadB_stack_area, STACKSIZE); static struct k_thread threadB_data; /* threadA is a static thread that is spawned automatically */ void threadA(void *dummy1, void *dummy2, void *dummy3) { ARG_UNUSED(dummy1); ARG_UNUSED(dummy2); ARG_UNUSED(dummy3); /* invoke routine to ping-pong hello messages with threadB */ helloLoop(__func__, &threadA_sem, &threadB_sem); } int main(void) { k_thread_create(&threadA_data, threadA_stack_area, K_THREAD_STACK_SIZEOF(threadA_stack_area), threadA, NULL, NULL, NULL, PRIORITY, 0, K_FOREVER); k_thread_name_set(&threadA_data, "thread_a"); #if PIN_THREADS if (arch_num_cpus() > 1) { k_thread_cpu_pin(&threadA_data, 0); } #endif k_thread_create(&threadB_data, threadB_stack_area, K_THREAD_STACK_SIZEOF(threadB_stack_area), threadB, NULL, NULL, NULL, PRIORITY, 0, K_FOREVER); k_thread_name_set(&threadB_data, "thread_b"); #if PIN_THREADS if (arch_num_cpus() > 1) { k_thread_cpu_pin(&threadB_data, 1); } #endif k_thread_start(&threadA_data); k_thread_start(&threadB_data); return 0; } |