Zephyr Project API 4.0.0
A Scalable Open Source RTOS
|
Functions | |
void | arch_new_thread (struct k_thread *thread, k_thread_stack_t *stack, char *stack_ptr, k_thread_entry_t entry, void *p1, void *p2, void *p3) |
Handle arch-specific logic for setting up new threads. | |
static void | arch_switch (void *switch_to, void **switched_from) |
Cooperative context switch primitive. | |
void | arch_switch_to_main_thread (struct k_thread *main_thread, char *stack_ptr, k_thread_entry_t _main) |
Custom logic for entering main thread context at early boot. | |
int | arch_float_disable (struct k_thread *thread) |
Disable floating point context preservation. | |
int | arch_float_enable (struct k_thread *thread, unsigned int options) |
Enable floating point context preservation. | |
int arch_float_disable | ( | struct k_thread * | thread | ) |
#include <kernel/include/kernel_arch_interface.h>
Disable floating point context preservation.
The function is used to disable the preservation of floating point context information for a particular thread.
0 | On success. |
-EINVAL | If the floating point disabling could not be performed. |
-ENOTSUP | If the operation is not supported |
#include <kernel/include/kernel_arch_interface.h>
Enable floating point context preservation.
The function is used to enable the preservation of floating point context information for a particular thread. This API depends on each architecture implementation. If the architecture does not support enabling, this API will always be failed.
The options parameter indicates which floating point register sets will be used by the specified thread. Currently it is used by x86 only.
thread | ID of thread. |
options | architecture dependent options |
0 | On success. |
-EINVAL | If the floating point enabling could not be performed. |
-ENOTSUP | If the operation is not supported |
void arch_new_thread | ( | struct k_thread * | thread, |
k_thread_stack_t * | stack, | ||
char * | stack_ptr, | ||
k_thread_entry_t | entry, | ||
void * | p1, | ||
void * | p2, | ||
void * | p3 | ||
) |
#include <kernel/include/kernel_arch_interface.h>
Handle arch-specific logic for setting up new threads.
The stack and arch-specific thread state variables must be set up such that a later attempt to switch to this thread will succeed and we will enter z_thread_entry with the requested thread and arguments as its parameters.
At some point in this function's implementation, z_setup_new_thread() must be called with the true bounds of the available stack buffer within the thread's stack object.
The provided stack pointer is guaranteed to be properly aligned with respect to the CPU and ABI requirements. There may be space reserved between the stack pointer and the bounds of the stack buffer for initial stack pointer randomization and thread-local storage.
Fields in thread->base will be initialized when this is called.
thread | Pointer to uninitialized struct k_thread |
stack | Pointer to the stack object |
stack_ptr | Aligned initial stack pointer |
entry | Thread entry function |
p1 | 1st entry point parameter |
p2 | 2nd entry point parameter |
p3 | 3rd entry point parameter |
|
inlinestatic |
#include <kernel/include/kernel_arch_interface.h>
Cooperative context switch primitive.
The action of arch_switch() should be to switch to a new context passed in the first argument, and save a pointer to the current context into the address passed in the second argument.
The actual type and interpretation of the switch handle is specified by the architecture. It is the same data structure stored in the "switch_handle" field of a newly-created thread in arch_new_thread(), and passed to the kernel as the "interrupted" argument to z_get_next_switch_handle().
Note that on SMP systems, the kernel uses the store through the second pointer as a synchronization point to detect when a thread context is completely saved (so another CPU can know when it is safe to switch). This store must be done AFTER all relevant state is saved, and must include whatever memory barriers or cache management code is required to be sure another CPU will see the result correctly.
The simplest implementation of arch_switch() is generally to push state onto the thread stack and use the resulting stack pointer as the switch handle. Some architectures may instead decide to use a pointer into the thread struct as the "switch handle" type. These can legally assume that the second argument to arch_switch() is the address of the switch_handle field of struct thread_base and can use an offset on this value to find other parts of the thread struct. For example a (C pseudocode) implementation of arch_switch() might look like:
void arch_switch(void *switch_to, void **switched_from) { struct k_thread *new = switch_to; struct k_thread *old = CONTAINER_OF(switched_from, struct k_thread, switch_handle);
// save old context... *switched_from = old; // restore new context... }
Note that the kernel manages the switch_handle field for synchronization as described above. So it is not legal for architecture code to assume that it has any particular value at any other time. In particular it is not legal to read the field from the address passed in the second argument.
switch_to | Incoming thread's switch handle |
switched_from | Pointer to outgoing thread's switch handle storage location, which must be updated. |
void arch_switch_to_main_thread | ( | struct k_thread * | main_thread, |
char * | stack_ptr, | ||
k_thread_entry_t | _main | ||
) |
#include <kernel/include/kernel_arch_interface.h>
Custom logic for entering main thread context at early boot.
Used by architectures where the typical trick of setting up a dummy thread in early boot context to "switch out" of isn't workable.
main_thread | main thread object |
stack_ptr | Initial stack pointer |
_main | Entry point for application main function. |