670 lines
23 KiB
C
670 lines
23 KiB
C
/*
|
|
* Copyright (c) 2020 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
*
|
|
* @brief Macros for declaring thread stacks
|
|
*/
|
|
|
|
/**
|
|
* @brief Thread Stack APIs
|
|
* @ingroup kernel_apis
|
|
* @defgroup thread_stack_api Thread Stack APIs
|
|
* @{
|
|
* @}
|
|
*/
|
|
|
|
#ifndef ZEPHYR_INCLUDE_SYS_THREAD_STACK_H
|
|
#define ZEPHYR_INCLUDE_SYS_THREAD_STACK_H
|
|
|
|
#if !defined(_ASMLANGUAGE)
|
|
#include <arch/cpu.h>
|
|
#include <sys/util.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Using typedef deliberately here, this is quite intended to be an opaque
|
|
* type.
|
|
*
|
|
* The purpose of this data type is to clearly distinguish between the
|
|
* declared symbol for a stack (of type k_thread_stack_t) and the underlying
|
|
* buffer which composes the stack data actually used by the underlying
|
|
* thread; they cannot be used interchangeably as some arches precede the
|
|
* stack buffer region with guard areas that trigger a MPU or MMU fault
|
|
* if written to.
|
|
*
|
|
* APIs that want to work with the buffer inside should continue to use
|
|
* char *.
|
|
*
|
|
* Stacks should always be created with K_THREAD_STACK_DEFINE().
|
|
*/
|
|
struct __packed z_thread_stack_element {
|
|
char data;
|
|
};
|
|
|
|
/**
|
|
* @typedef k_thread_stack_t
|
|
* @brief Typedef of struct z_thread_stack_element
|
|
*
|
|
* @see z_thread_stack_element
|
|
*/
|
|
|
|
|
|
/**
|
|
* @brief Properly align a CPU stack pointer value
|
|
*
|
|
* Take the provided value and round it down such that the value is aligned
|
|
* to the CPU and ABI requirements. This is not used for any memory protection
|
|
* hardware requirements.
|
|
*
|
|
* @param ptr Proposed stack pointer address
|
|
* @return Properly aligned stack pointer address
|
|
*/
|
|
static inline char *z_stack_ptr_align(char *ptr)
|
|
{
|
|
return (char *)ROUND_DOWN(ptr, ARCH_STACK_PTR_ALIGN);
|
|
}
|
|
#define Z_STACK_PTR_ALIGN(ptr) ((uintptr_t)z_stack_ptr_align((char *)(ptr)))
|
|
|
|
/**
|
|
* @brief Helper macro for getting a stack frame struct
|
|
*
|
|
* It is very common for architectures to define a struct which contains
|
|
* all the data members that are pre-populated in arch_new_thread().
|
|
*
|
|
* Given a type and an initial stack pointer, return a properly cast
|
|
* pointer to the frame struct.
|
|
*
|
|
* @param type Type of the initial stack frame struct
|
|
* @param ptr Initial aligned stack pointer value
|
|
* @return Pointer to stack frame struct within the stack buffer
|
|
*/
|
|
#define Z_STACK_PTR_TO_FRAME(type, ptr) \
|
|
(type *)((ptr) - sizeof(type))
|
|
|
|
#ifdef ARCH_KERNEL_STACK_RESERVED
|
|
#define K_KERNEL_STACK_RESERVED ((size_t)ARCH_KERNEL_STACK_RESERVED)
|
|
#else
|
|
#define K_KERNEL_STACK_RESERVED ((size_t)0)
|
|
#endif
|
|
|
|
#define Z_KERNEL_STACK_SIZE_ADJUST(size) (ROUND_UP(size, \
|
|
ARCH_STACK_PTR_ALIGN) + \
|
|
K_KERNEL_STACK_RESERVED)
|
|
|
|
#ifdef ARCH_KERNEL_STACK_OBJ_ALIGN
|
|
#define Z_KERNEL_STACK_OBJ_ALIGN ARCH_KERNEL_STACK_OBJ_ALIGN
|
|
#else
|
|
#define Z_KERNEL_STACK_OBJ_ALIGN ARCH_STACK_PTR_ALIGN
|
|
#endif
|
|
|
|
#define Z_KERNEL_STACK_LEN(size) \
|
|
ROUND_UP(Z_KERNEL_STACK_SIZE_ADJUST(size), Z_KERNEL_STACK_OBJ_ALIGN)
|
|
|
|
/**
|
|
* @brief Obtain an extern reference to a stack
|
|
*
|
|
* This macro properly brings the symbol of a thread stack declared
|
|
* elsewhere into scope.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
*/
|
|
#define K_KERNEL_STACK_EXTERN(sym) extern k_thread_stack_t sym[]
|
|
|
|
/**
|
|
* @addtogroup thread_stack_api
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @def K_KERNEL_STACK_ARRAY_EXTERN
|
|
* @brief Obtain an extern reference to a stack array
|
|
*
|
|
* This macro properly brings the symbol of a stack array declared
|
|
* elsewhere into scope.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param nmemb Number of stacks to declare
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define K_KERNEL_STACK_ARRAY_EXTERN(sym, nmemb, size) \
|
|
extern struct z_thread_stack_element \
|
|
sym[nmemb][Z_KERNEL_STACK_LEN(size)]
|
|
|
|
/**
|
|
* @def K_KERNEL_PINNED_STACK_ARRAY_EXTERN
|
|
* @brief Obtain an extern reference to a pinned stack array
|
|
*
|
|
* This macro properly brings the symbol of a pinned stack array
|
|
* declared elsewhere into scope.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param nmemb Number of stacks to declare
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define K_KERNEL_PINNED_STACK_ARRAY_EXTERN(sym, nmemb, size) \
|
|
extern struct z_thread_stack_element \
|
|
sym[nmemb][Z_KERNEL_STACK_LEN(size)]
|
|
|
|
/**
|
|
* @def Z_KERNEL_STACK_DEFINE_IN
|
|
* @brief Define a toplevel kernel stack memory region in specified section
|
|
*
|
|
* This declares a region of memory for use as a thread stack in
|
|
* the specified linker section.
|
|
*
|
|
* It is legal to precede this definition with the 'static' keyword.
|
|
*
|
|
* It is NOT legal to take the sizeof(sym) and pass that to the stackSize
|
|
* parameter of k_thread_create(), it may not be the same as the
|
|
* 'size' parameter. Use K_KERNEL_STACK_SIZEOF() instead.
|
|
*
|
|
* The total amount of memory allocated may be increased to accommodate
|
|
* fixed-size stack overflow guards.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param size Size of the stack memory region
|
|
* @param lsect Linker section for this stack
|
|
*/
|
|
#define Z_KERNEL_STACK_DEFINE_IN(sym, size, lsect) \
|
|
struct z_thread_stack_element lsect \
|
|
__aligned(Z_KERNEL_STACK_OBJ_ALIGN) \
|
|
sym[Z_KERNEL_STACK_SIZE_ADJUST(size)]
|
|
|
|
/**
|
|
* @def Z_KERNEL_STACK_ARRAY_DEFINE_IN
|
|
* @brief Define a toplevel array of kernel stack memory regions in specified section
|
|
*
|
|
* @param sym Kernel stack array symbol name
|
|
* @param nmemb Number of stacks to declare
|
|
* @param size Size of the stack memory region
|
|
* @param lsect Linker section for this array of stacks
|
|
*/
|
|
#define Z_KERNEL_STACK_ARRAY_DEFINE_IN(sym, nmemb, size, lsect) \
|
|
struct z_thread_stack_element lsect \
|
|
__aligned(Z_KERNEL_STACK_OBJ_ALIGN) \
|
|
sym[nmemb][Z_KERNEL_STACK_LEN(size)]
|
|
|
|
/**
|
|
* @def K_KERNEL_STACK_DEFINE
|
|
* @brief Define a toplevel kernel stack memory region
|
|
*
|
|
* This declares a region of memory for use as a thread stack, for threads
|
|
* that exclusively run in supervisor mode. This is also suitable for
|
|
* declaring special stacks for interrupt or exception handling.
|
|
*
|
|
* Stacks declared with this macro may not host user mode threads.
|
|
*
|
|
* It is legal to precede this definition with the 'static' keyword.
|
|
*
|
|
* It is NOT legal to take the sizeof(sym) and pass that to the stackSize
|
|
* parameter of k_thread_create(), it may not be the same as the
|
|
* 'size' parameter. Use K_KERNEL_STACK_SIZEOF() instead.
|
|
*
|
|
* The total amount of memory allocated may be increased to accommodate
|
|
* fixed-size stack overflow guards.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define K_KERNEL_STACK_DEFINE(sym, size) \
|
|
Z_KERNEL_STACK_DEFINE_IN(sym, size, __kstackmem)
|
|
|
|
/**
|
|
* @def K_KERNEL_PINNED_STACK_DEFINE
|
|
* @brief Define a toplevel kernel stack memory region in pinned section
|
|
*
|
|
* See K_KERNEL_STACK_DEFINE() for more information and constraints.
|
|
*
|
|
* This puts the stack into the pinned noinit linker section if
|
|
* CONFIG_LINKER_USE_PINNED_SECTION is enabled, or else it would
|
|
* put the stack into the same section as K_KERNEL_STACK_DEFINE().
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#if defined(CONFIG_LINKER_USE_PINNED_SECTION)
|
|
#define K_KERNEL_PINNED_STACK_DEFINE(sym, size) \
|
|
Z_KERNEL_STACK_DEFINE_IN(sym, size, __pinned_noinit)
|
|
#else
|
|
#define K_KERNEL_PINNED_STACK_DEFINE(sym, size) \
|
|
Z_KERNEL_STACK_DEFINE_IN(sym, size, __kstackmem)
|
|
#endif
|
|
|
|
/**
|
|
* @def K_KERNEL_STACK_ARRAY_DEFINE
|
|
* @brief Define a toplevel array of kernel stack memory regions
|
|
*
|
|
* Stacks declared with this macro may not host user mode threads.
|
|
*
|
|
* @param sym Kernel stack array symbol name
|
|
* @param nmemb Number of stacks to declare
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define K_KERNEL_STACK_ARRAY_DEFINE(sym, nmemb, size) \
|
|
Z_KERNEL_STACK_ARRAY_DEFINE_IN(sym, nmemb, size, __kstackmem)
|
|
|
|
/**
|
|
* @def K_KERNEL_PINNED_STACK_ARRAY_DEFINE
|
|
* @brief Define a toplevel array of kernel stack memory regions in pinned section
|
|
*
|
|
* See K_KERNEL_STACK_ARRAY_DEFINE() for more information and constraints.
|
|
*
|
|
* This puts the stack into the pinned noinit linker section if
|
|
* CONFIG_LINKER_USE_PINNED_SECTION is enabled, or else it would
|
|
* put the stack into the same section as K_KERNEL_STACK_ARRAY_DEFINE().
|
|
*
|
|
* @param sym Kernel stack array symbol name
|
|
* @param nmemb Number of stacks to declare
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#if defined(CONFIG_LINKER_USE_PINNED_SECTION)
|
|
#define K_KERNEL_PINNED_STACK_ARRAY_DEFINE(sym, nmemb, size) \
|
|
Z_KERNEL_STACK_ARRAY_DEFINE_IN(sym, nmemb, size, __pinned_noinit)
|
|
#else
|
|
#define K_KERNEL_PINNED_STACK_ARRAY_DEFINE(sym, nmemb, size) \
|
|
Z_KERNEL_STACK_ARRAY_DEFINE_IN(sym, nmemb, size, __kstackmem)
|
|
#endif
|
|
|
|
/**
|
|
* @def K_KERNEL_STACK_MEMBER
|
|
* @brief Declare an embedded stack memory region
|
|
*
|
|
* Used for kernel stacks embedded within other data structures.
|
|
*
|
|
* Stacks declared with this macro may not host user mode threads.
|
|
* @param sym Thread stack symbol name
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define K_KERNEL_STACK_MEMBER(sym, size) \
|
|
Z_KERNEL_STACK_DEFINE_IN(sym, size,)
|
|
|
|
#define K_KERNEL_STACK_SIZEOF(sym) (sizeof(sym) - K_KERNEL_STACK_RESERVED)
|
|
|
|
/** @} */
|
|
|
|
static inline char *Z_KERNEL_STACK_BUFFER(k_thread_stack_t *sym)
|
|
{
|
|
return (char *)sym + K_KERNEL_STACK_RESERVED;
|
|
}
|
|
#ifndef CONFIG_USERSPACE
|
|
#define K_THREAD_STACK_RESERVED K_KERNEL_STACK_RESERVED
|
|
#define K_THREAD_STACK_SIZEOF K_KERNEL_STACK_SIZEOF
|
|
#define K_THREAD_STACK_LEN Z_KERNEL_STACK_LEN
|
|
#define K_THREAD_STACK_DEFINE K_KERNEL_STACK_DEFINE
|
|
#define K_THREAD_STACK_ARRAY_DEFINE K_KERNEL_STACK_ARRAY_DEFINE
|
|
#define K_THREAD_STACK_MEMBER K_KERNEL_STACK_MEMBER
|
|
#define Z_THREAD_STACK_BUFFER Z_KERNEL_STACK_BUFFER
|
|
#define K_THREAD_STACK_EXTERN K_KERNEL_STACK_EXTERN
|
|
#define K_THREAD_STACK_ARRAY_EXTERN K_KERNEL_STACK_ARRAY_EXTERN
|
|
#define K_THREAD_PINNED_STACK_DEFINE K_KERNEL_PINNED_STACK_DEFINE
|
|
#define K_THREAD_PINNED_STACK_ARRAY_DEFINE \
|
|
K_KERNEL_PINNED_STACK_ARRAY_DEFINE
|
|
#else
|
|
/**
|
|
* @def K_THREAD_STACK_RESERVED
|
|
* @brief Indicate how much additional memory is reserved for stack objects
|
|
*
|
|
* Any given stack declaration may have additional memory in it for guard
|
|
* areas, supervisor mode stacks, or platform-specific data. This macro
|
|
* indicates how much space is reserved for this.
|
|
*
|
|
* This value only indicates memory that is permanently reserved in the stack
|
|
* object. Memory that is "borrowed" from the thread's stack buffer is never
|
|
* accounted for here.
|
|
*
|
|
* Reserved memory is at the beginning of the stack object. The reserved area
|
|
* must be appropriately sized such that the stack buffer immediately following
|
|
* it is correctly aligned.
|
|
*/
|
|
#ifdef ARCH_THREAD_STACK_RESERVED
|
|
#define K_THREAD_STACK_RESERVED ((size_t)(ARCH_THREAD_STACK_RESERVED))
|
|
#else
|
|
#define K_THREAD_STACK_RESERVED ((size_t)0U)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Properly align the lowest address of a stack object
|
|
*
|
|
* Return an alignment value for the lowest address of a stack object, taking
|
|
* into consideration all alignment constraints imposed by the CPU, ABI, and
|
|
* any memory management policies, including any alignment required by
|
|
* reserved platform data within the stack object. This will always be at least
|
|
* ARCH_STACK_PTR_ALIGN or an even multiple thereof.
|
|
*
|
|
* Depending on hardware, this is either a fixed value or a function of the
|
|
* provided size. The requested size is significant only if
|
|
* CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT is enabled.
|
|
*
|
|
* If CONFIG_USERSPACE is enabled, this determines the alignment of stacks
|
|
* which may be used by user mode threads, or threads running in supervisor
|
|
* mode which may later drop privileges to user mode.
|
|
*
|
|
* Arches define this with ARCH_THREAD_STACK_OBJ_ALIGN().
|
|
*
|
|
* If ARCH_THREAD_STACK_OBJ_ALIGN is not defined assume ARCH_STACK_PTR_ALIGN
|
|
* is appropriate.
|
|
*
|
|
* @param size Requested size of the stack buffer (which could be ignored)
|
|
* @return Alignment of the stack object
|
|
*/
|
|
#if defined(ARCH_THREAD_STACK_OBJ_ALIGN)
|
|
#define Z_THREAD_STACK_OBJ_ALIGN(size) ARCH_THREAD_STACK_OBJ_ALIGN(size)
|
|
#else
|
|
#define Z_THREAD_STACK_OBJ_ALIGN(size) ARCH_STACK_PTR_ALIGN
|
|
#endif /* ARCH_THREAD_STACK_OBJ_ALIGN */
|
|
|
|
/**
|
|
* @def Z_THREAD_STACK_SIZE_ADJUST
|
|
* @brief Round up a requested stack size to satisfy constraints
|
|
*
|
|
* Given a requested stack buffer size, return an adjusted size value for
|
|
* the entire stack object which takes into consideration:
|
|
*
|
|
* - Reserved memory for platform data
|
|
* - Alignment of stack buffer bounds to CPU/ABI constraints
|
|
* - Alignment of stack buffer bounds to satisfy memory management hardware
|
|
* constraints such that a protection region can cover the stack buffer area
|
|
*
|
|
* If CONFIG_USERSPACE is enabled, this determines the size of stack objects
|
|
* which may be used by user mode threads, or threads running in supervisor
|
|
* mode which may later drop privileges to user mode.
|
|
*
|
|
* Arches define this with ARCH_THREAD_STACK_SIZE_ADJUST().
|
|
*
|
|
* If ARCH_THREAD_STACK_SIZE_ADJUST is not defined, assume rounding up to
|
|
* ARCH_STACK_PTR_ALIGN is appropriate.
|
|
*
|
|
* Any memory reserved for platform data is also included in the total
|
|
* returned.
|
|
*
|
|
* @param size Requested size of the stack buffer
|
|
* @return Adjusted size of the stack object
|
|
*/
|
|
#if defined(ARCH_THREAD_STACK_SIZE_ADJUST)
|
|
#define Z_THREAD_STACK_SIZE_ADJUST(size) \
|
|
(ARCH_THREAD_STACK_SIZE_ADJUST(size) + K_THREAD_STACK_RESERVED)
|
|
#else
|
|
#define Z_THREAD_STACK_SIZE_ADJUST(size) \
|
|
(ROUND_UP((size), ARCH_STACK_PTR_ALIGN) + K_THREAD_STACK_RESERVED)
|
|
#endif /* ARCH_THREAD_STACK_SIZE_ADJUST */
|
|
|
|
/**
|
|
* @brief Obtain an extern reference to a stack
|
|
*
|
|
* This macro properly brings the symbol of a thread stack declared
|
|
* elsewhere into scope.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
*/
|
|
#define K_THREAD_STACK_EXTERN(sym) extern k_thread_stack_t sym[]
|
|
|
|
/**
|
|
* @brief Obtain an extern reference to a thread stack array
|
|
*
|
|
* This macro properly brings the symbol of a stack array declared
|
|
* elsewhere into scope.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param nmemb Number of stacks to declare
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define K_THREAD_STACK_ARRAY_EXTERN(sym, nmemb, size) \
|
|
extern struct z_thread_stack_element \
|
|
sym[nmemb][K_THREAD_STACK_LEN(size)]
|
|
|
|
/**
|
|
* @addtogroup thread_stack_api
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief Return the size in bytes of a stack memory region
|
|
*
|
|
* Convenience macro for passing the desired stack size to k_thread_create()
|
|
* since the underlying implementation may actually create something larger
|
|
* (for instance a guard area).
|
|
*
|
|
* The value returned here is not guaranteed to match the 'size' parameter
|
|
* passed to K_THREAD_STACK_DEFINE and may be larger, but is always safe to
|
|
* pass to k_thread_create() for the associated stack object.
|
|
*
|
|
* @param sym Stack memory symbol
|
|
* @return Size of the stack buffer
|
|
*/
|
|
#define K_THREAD_STACK_SIZEOF(sym) (sizeof(sym) - K_THREAD_STACK_RESERVED)
|
|
|
|
/**
|
|
* @brief Declare a toplevel thread stack memory region in specified region
|
|
*
|
|
* This declares a region of memory suitable for use as a thread's stack
|
|
* in specified region.
|
|
*
|
|
* This is the generic, historical definition. Align to Z_THREAD_STACK_OBJ_ALIGN
|
|
* and put in 'noinit' section so that it isn't zeroed at boot
|
|
*
|
|
* The declared symbol will always be a k_thread_stack_t which can be passed to
|
|
* k_thread_create(), but should otherwise not be manipulated. If the buffer
|
|
* inside needs to be examined, examine thread->stack_info for the associated
|
|
* thread object to obtain the boundaries.
|
|
*
|
|
* It is legal to precede this definition with the 'static' keyword.
|
|
*
|
|
* It is NOT legal to take the sizeof(sym) and pass that to the stackSize
|
|
* parameter of k_thread_create(), it may not be the same as the
|
|
* 'size' parameter. Use K_THREAD_STACK_SIZEOF() instead.
|
|
*
|
|
* Some arches may round the size of the usable stack region up to satisfy
|
|
* alignment constraints. K_THREAD_STACK_SIZEOF() will return the aligned
|
|
* size.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param size Size of the stack memory region
|
|
* @param lsect Linker section for this stack
|
|
*/
|
|
#define Z_THREAD_STACK_DEFINE_IN(sym, size, lsect) \
|
|
struct z_thread_stack_element lsect \
|
|
__aligned(Z_THREAD_STACK_OBJ_ALIGN(size)) \
|
|
sym[Z_THREAD_STACK_SIZE_ADJUST(size)]
|
|
|
|
/**
|
|
* @brief Declare a toplevel array of thread stack memory regions in specified region
|
|
*
|
|
* Create an array of equally sized stacks. See Z_THREAD_STACK_DEFINE_IN
|
|
* definition for additional details and constraints.
|
|
*
|
|
* This is the generic, historical definition. Align to Z_THREAD_STACK_OBJ_ALIGN
|
|
* and put in specified section so that it isn't zeroed at boot
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param nmemb Number of stacks to declare
|
|
* @param size Size of the stack memory region
|
|
* @param lsect Linker section for this stack
|
|
*/
|
|
#define Z_THREAD_STACK_ARRAY_DEFINE_IN(sym, nmemb, size, lsect) \
|
|
struct z_thread_stack_element lsect \
|
|
__aligned(Z_THREAD_STACK_OBJ_ALIGN(size)) \
|
|
sym[nmemb][K_THREAD_STACK_LEN(size)]
|
|
|
|
/**
|
|
* @brief Declare a toplevel thread stack memory region
|
|
*
|
|
* This declares a region of memory suitable for use as a thread's stack.
|
|
*
|
|
* This is the generic, historical definition. Align to Z_THREAD_STACK_OBJ_ALIGN
|
|
* and put in 'noinit' section so that it isn't zeroed at boot
|
|
*
|
|
* The declared symbol will always be a k_thread_stack_t which can be passed to
|
|
* k_thread_create(), but should otherwise not be manipulated. If the buffer
|
|
* inside needs to be examined, examine thread->stack_info for the associated
|
|
* thread object to obtain the boundaries.
|
|
*
|
|
* It is legal to precede this definition with the 'static' keyword.
|
|
*
|
|
* It is NOT legal to take the sizeof(sym) and pass that to the stackSize
|
|
* parameter of k_thread_create(), it may not be the same as the
|
|
* 'size' parameter. Use K_THREAD_STACK_SIZEOF() instead.
|
|
*
|
|
* Some arches may round the size of the usable stack region up to satisfy
|
|
* alignment constraints. K_THREAD_STACK_SIZEOF() will return the aligned
|
|
* size.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define K_THREAD_STACK_DEFINE(sym, size) \
|
|
Z_THREAD_STACK_DEFINE_IN(sym, size, __stackmem)
|
|
|
|
/**
|
|
* @brief Define a toplevel thread stack memory region in pinned section
|
|
*
|
|
* This declares a region of memory suitable for use as a thread's stack.
|
|
*
|
|
* This is the generic, historical definition. Align to Z_THREAD_STACK_OBJ_ALIGN
|
|
* and put in 'noinit' section so that it isn't zeroed at boot
|
|
*
|
|
* The declared symbol will always be a k_thread_stack_t which can be passed to
|
|
* k_thread_create(), but should otherwise not be manipulated. If the buffer
|
|
* inside needs to be examined, examine thread->stack_info for the associated
|
|
* thread object to obtain the boundaries.
|
|
*
|
|
* It is legal to precede this definition with the 'static' keyword.
|
|
*
|
|
* It is NOT legal to take the sizeof(sym) and pass that to the stackSize
|
|
* parameter of k_thread_create(), it may not be the same as the
|
|
* 'size' parameter. Use K_THREAD_STACK_SIZEOF() instead.
|
|
*
|
|
* Some arches may round the size of the usable stack region up to satisfy
|
|
* alignment constraints. K_THREAD_STACK_SIZEOF() will return the aligned
|
|
* size.
|
|
*
|
|
* This puts the stack into the pinned noinit linker section if
|
|
* CONFIG_LINKER_USE_PINNED_SECTION is enabled, or else it would
|
|
* put the stack into the same section as K_THREAD_STACK_DEFINE().
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#if defined(CONFIG_LINKER_USE_PINNED_SECTION)
|
|
#define K_THREAD_PINNED_STACK_DEFINE(sym, size) \
|
|
Z_THREAD_STACK_DEFINE_IN(sym, size, __pinned_noinit)
|
|
#else
|
|
#define K_THREAD_PINNED_STACK_DEFINE(sym, size) \
|
|
K_THREAD_STACK_DEFINE(sym, size)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Calculate size of stacks to be allocated in a stack array
|
|
*
|
|
* This macro calculates the size to be allocated for the stacks
|
|
* inside a stack array. It accepts the indicated "size" as a parameter
|
|
* and if required, pads some extra bytes (e.g. for MPU scenarios). Refer
|
|
* K_THREAD_STACK_ARRAY_DEFINE definition to see how this is used.
|
|
* The returned size ensures each array member will be aligned to the
|
|
* required stack base alignment.
|
|
*
|
|
* @param size Size of the stack memory region
|
|
* @return Appropriate size for an array member
|
|
*/
|
|
#define K_THREAD_STACK_LEN(size) \
|
|
ROUND_UP(Z_THREAD_STACK_SIZE_ADJUST(size), \
|
|
Z_THREAD_STACK_OBJ_ALIGN(Z_THREAD_STACK_SIZE_ADJUST(size)))
|
|
|
|
/**
|
|
* @brief Declare a toplevel array of thread stack memory regions
|
|
*
|
|
* Create an array of equally sized stacks. See K_THREAD_STACK_DEFINE
|
|
* definition for additional details and constraints.
|
|
*
|
|
* This is the generic, historical definition. Align to Z_THREAD_STACK_OBJ_ALIGN
|
|
* and put in 'noinit' section so that it isn't zeroed at boot
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param nmemb Number of stacks to declare
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define K_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \
|
|
Z_THREAD_STACK_ARRAY_DEFINE_IN(sym, nmemb, size, __stackmem)
|
|
|
|
/**
|
|
* @brief Declare a toplevel array of thread stack memory regions in pinned section
|
|
*
|
|
* Create an array of equally sized stacks. See K_THREAD_STACK_DEFINE
|
|
* definition for additional details and constraints.
|
|
*
|
|
* This is the generic, historical definition. Align to Z_THREAD_STACK_OBJ_ALIGN
|
|
* and put in 'noinit' section so that it isn't zeroed at boot
|
|
*
|
|
* This puts the stack into the pinned noinit linker section if
|
|
* CONFIG_LINKER_USE_PINNED_SECTION is enabled, or else it would
|
|
* put the stack into the same section as K_THREAD_STACK_DEFINE().
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param nmemb Number of stacks to declare
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#if defined(CONFIG_LINKER_USE_PINNED_SECTION)
|
|
#define K_THREAD_PINNED_STACK_ARRAY_DEFINE(sym, nmemb, size) \
|
|
Z_THREAD_PINNED_STACK_DEFINE_IN(sym, nmemb, size, __pinned_noinit)
|
|
#else
|
|
#define K_THREAD_PINNED_STACK_ARRAY_DEFINE(sym, nmemb, size) \
|
|
K_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Declare an embedded stack memory region
|
|
*
|
|
* Used for stacks embedded within other data structures. Use is highly
|
|
* discouraged but in some cases necessary. For memory protection scenarios,
|
|
* it is very important that any RAM preceding this member not be writable
|
|
* by threads else a stack overflow will lead to silent corruption. In other
|
|
* words, the containing data structure should live in RAM owned by the kernel.
|
|
*
|
|
* A user thread can only be started with a stack defined in this way if
|
|
* the thread starting it is in supervisor mode.
|
|
*
|
|
* This is now deprecated, as stacks defined in this way are not usable from
|
|
* user mode. Use K_KERNEL_STACK_MEMBER.
|
|
*
|
|
* @param sym Thread stack symbol name
|
|
* @param size Size of the stack memory region
|
|
*/
|
|
#define K_THREAD_STACK_MEMBER(sym, size) \
|
|
Z_THREAD_STACK_DEFINE_IN(sym, size,)
|
|
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief Get a pointer to the physical stack buffer
|
|
*
|
|
* Obtain a pointer to the non-reserved area of a stack object.
|
|
* This is not guaranteed to be the beginning of the thread-writable region;
|
|
* this does not account for any memory carved-out for MPU stack overflow
|
|
* guards.
|
|
*
|
|
* Use with care. The true bounds of the stack buffer are available in the
|
|
* stack_info member of its associated thread.
|
|
*
|
|
* @param sym Declared stack symbol name
|
|
* @return The buffer itself, a char *
|
|
*/
|
|
static inline char *Z_THREAD_STACK_BUFFER(k_thread_stack_t *sym)
|
|
{
|
|
return (char *)sym + K_THREAD_STACK_RESERVED;
|
|
}
|
|
|
|
#endif /* CONFIG_USERSPACE */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _ASMLANGUAGE */
|
|
#endif /* ZEPHYR_INCLUDE_SYS_THREAD_STACK_H */
|