blob: 41c4c5e4ebfb8c1e9163589a925f950168c160e3 [file] [log] [blame]
/*
* 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 <zephyr/arch/cpu.h>
#include <zephyr/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)
/**
* @addtogroup thread_stack_api
* @{
*/
/**
* @brief Declare a reference to a thread stack
*
* This macro declares the symbol of a thread stack defined elsewhere in the
* current scope.
*
* @param sym Thread stack symbol name
* @param size Size of the stack memory region
*/
#define K_KERNEL_STACK_DECLARE(sym, size) \
extern struct z_thread_stack_element \
sym[Z_KERNEL_STACK_SIZE_ADJUST(size)]
/**
* @brief Declare a reference to a thread stack array
*
* This macro declares the symbol of a thread stack array defined elsewhere in
* the current scope.
*
* @param sym Thread stack symbol name
* @param nmemb Number of stacks defined
* @param size Size of the stack memory region
*/
#define K_KERNEL_STACK_ARRAY_DECLARE(sym, nmemb, size) \
extern struct z_thread_stack_element \
sym[nmemb][Z_KERNEL_STACK_LEN(size)]
/**
* @brief Declare a reference to a pinned thread stack array
*
* This macro declares the symbol of a pinned thread stack array defined
* elsewhere in the current scope.
*
* @param sym Thread stack symbol name
* @param nmemb Number of stacks defined
* @param size Size of the stack memory region
*/
#define K_KERNEL_PINNED_STACK_ARRAY_DECLARE(sym, nmemb, size) \
extern struct z_thread_stack_element \
sym[nmemb][Z_KERNEL_STACK_LEN(size)]
/**
* @brief Obtain an extern reference to a stack
*
* This macro properly brings the symbol of a thread stack defined
* elsewhere into scope.
*
* @deprecated Use @c K_KERNEL_STACK_DECLARE() instead.
*
* @param sym Thread stack symbol name
*/
#define K_KERNEL_STACK_EXTERN(sym) __DEPRECATED_MACRO \
extern k_thread_stack_t sym[]
/**
* @brief Obtain an extern reference to a stack array
*
* This macro properly brings the symbol of a stack array defined
* elsewhere into scope.
*
* @deprecated Use @c K_KERNEL_STACK_ARRAY_DECLARE() instead.
*
* @param sym Thread stack symbol name
* @param nmemb Number of stacks defined
* @param size Size of the stack memory region
*/
#define K_KERNEL_STACK_ARRAY_EXTERN(sym, nmemb, size) __DEPRECATED_MACRO \
extern struct z_thread_stack_element \
sym[nmemb][Z_KERNEL_STACK_LEN(size)]
/**
* @brief Obtain an extern reference to a pinned stack array
*
* This macro properly brings the symbol of a pinned stack array
* defined elsewhere into scope.
*
* @deprecated Use @c K_KERNEL_PINNED_STACK_ARRAY_DECLARE() instead.
*
* @param sym Thread stack symbol name
* @param nmemb Number of stacks defined
* @param size Size of the stack memory region
*/
#define K_KERNEL_PINNED_STACK_ARRAY_EXTERN(sym, nmemb, size) __DEPRECATED_MACRO \
extern struct z_thread_stack_element \
sym[nmemb][Z_KERNEL_STACK_LEN(size)]
/**
* @brief Define a toplevel kernel stack memory region in specified section
*
* This defines 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)]
/**
* @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 define
* @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)]
/**
* @brief Define a toplevel kernel stack memory region
*
* This defines 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 defined 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)
/**
* @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
/**
* @brief Define a toplevel array of kernel stack memory regions
*
* Stacks defined with this macro may not host user mode threads.
*
* @param sym Kernel stack array symbol name
* @param nmemb Number of stacks to define
* @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)
/**
* @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 define
* @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
/**
* @brief Define an embedded stack memory region
*
* Used for kernel stacks embedded within other data structures.
*
* Stacks defined 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_DECLARE K_KERNEL_STACK_DECLARE
#define K_THREAD_STACK_ARRAY_DECLARE K_KERNEL_STACK_ARRAY_DECLARE
#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
/**
* @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(Z_THREAD_STACK_SIZE_ADJUST(size))
#else
#define Z_THREAD_STACK_OBJ_ALIGN(size) ARCH_STACK_PTR_ALIGN
#endif /* ARCH_THREAD_STACK_OBJ_ALIGN */
/**
* @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 */
/**
* @addtogroup thread_stack_api
* @{
*/
/**
* @brief Declare a reference to a thread stack
*
* This macro declares the symbol of a thread stack defined elsewhere in the
* current scope.
*
* @param sym Thread stack symbol name
* @param size Size of the stack memory region
*/
#define K_THREAD_STACK_DECLARE(sym, size) \
extern struct z_thread_stack_element \
sym[Z_THREAD_STACK_SIZE_ADJUST(size)]
/**
* @brief Declare a reference to a thread stack array
*
* This macro declares the symbol of a thread stack array defined elsewhere in
* the current scope.
*
* @param sym Thread stack symbol name
* @param nmemb Number of stacks defined
* @param size Size of the stack memory region
*/
#define K_THREAD_STACK_ARRAY_DECLARE(sym, nmemb, size) \
extern struct z_thread_stack_element \
sym[nmemb][K_THREAD_STACK_LEN(size)]
/**
* @brief Obtain an extern reference to a stack
*
* This macro properly brings the symbol of a thread stack defined
* elsewhere into scope.
*
* @deprecated Use @c K_THREAD_STACK_DECLARE() instead.
*
* @param sym Thread stack symbol name
*/
#define K_THREAD_STACK_EXTERN(sym) __DEPRECATED_MACRO \
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 defined
* elsewhere into scope.
*
* @deprecated Use @c K_THREAD_STACK_ARRAY_DECLARE() instead.
*
* @param sym Thread stack symbol name
* @param nmemb Number of stacks defined
* @param size Size of the stack memory region
*/
#define K_THREAD_STACK_ARRAY_EXTERN(sym, nmemb, size) __DEPRECATED_MACRO \
extern struct z_thread_stack_element \
sym[nmemb][K_THREAD_STACK_LEN(size)]
/**
* @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 Define a toplevel thread stack memory region in specified region
*
* This defines 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 defined 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 Define 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 define
* @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 Define a toplevel thread stack memory region
*
* This defines 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 defined 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 defines 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 defined 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(size))
/**
* @brief Define 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 define
* @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 Define 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 define
* @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 Define 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 defined 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 */