diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index dc8f1fb130d..614b2eab1b9 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -5456,6 +5456,41 @@ struct k_mem_slab { * @{ */ +/** + * @brief Statically define and initialize a memory slab in a user-provided memory section with + * public (non-static) scope. + * + * The memory slab's buffer contains @a slab_num_blocks memory blocks + * that are @a slab_block_size bytes long. The buffer is aligned to a + * @a slab_align -byte boundary. To ensure that each memory block is similarly + * aligned to this boundary, @a slab_block_size must also be a multiple of + * @a slab_align. + * + * The memory slab can be accessed outside the module where it is defined + * using: + * + * @code extern struct k_mem_slab ; @endcode + * + * @note This macro cannot be used together with a static keyword. + * If such a use-case is desired, use @ref K_MEM_SLAB_DEFINE_IN_SECT_STATIC + * instead. + * + * @param name Name of the memory slab. + * @param in_section Section attribute specifier such as Z_GENERIC_SECTION. + * @param slab_block_size Size of each memory block (in bytes). + * @param slab_num_blocks Number memory blocks. + * @param slab_align Alignment of the memory slab's buffer (power of 2). + */ +#define K_MEM_SLAB_DEFINE_IN_SECT(name, in_section, slab_block_size, slab_num_blocks, slab_align) \ + BUILD_ASSERT(((slab_block_size) % (slab_align)) == 0, \ + "slab_block_size must be a multiple of slab_align"); \ + BUILD_ASSERT((((slab_align) & ((slab_align) - 1)) == 0), \ + "slab_align must be a power of 2"); \ + char in_section __aligned(WB_UP( \ + slab_align)) _k_mem_slab_buf_##name[(slab_num_blocks) * WB_UP(slab_block_size)]; \ + STRUCT_SECTION_ITERABLE(k_mem_slab, name) = Z_MEM_SLAB_INITIALIZER( \ + name, _k_mem_slab_buf_##name, WB_UP(slab_block_size), slab_num_blocks) + /** * @brief Statically define and initialize a memory slab in a public (non-static) scope. * @@ -5479,13 +5514,36 @@ struct k_mem_slab { * @param slab_num_blocks Number memory blocks. * @param slab_align Alignment of the memory slab's buffer (power of 2). */ -#define K_MEM_SLAB_DEFINE(name, slab_block_size, slab_num_blocks, slab_align) \ - char __noinit_named(k_mem_slab_buf_##name) \ - __aligned(WB_UP(slab_align)) \ - _k_mem_slab_buf_##name[(slab_num_blocks) * WB_UP(slab_block_size)]; \ - STRUCT_SECTION_ITERABLE(k_mem_slab, name) = \ - Z_MEM_SLAB_INITIALIZER(name, _k_mem_slab_buf_##name, \ - WB_UP(slab_block_size), slab_num_blocks) +#define K_MEM_SLAB_DEFINE(name, slab_block_size, slab_num_blocks, slab_align) \ + K_MEM_SLAB_DEFINE_IN_SECT(name, __noinit_named(k_mem_slab_buf_##name), slab_block_size, \ + slab_num_blocks, slab_align) + +/** + * @brief Statically define and initialize a memory slab in a user-provided memory section with + * private (static) scope. + * + * The memory slab's buffer contains @a slab_num_blocks memory blocks + * that are @a slab_block_size bytes long. The buffer is aligned to a + * @a slab_align -byte boundary. To ensure that each memory block is similarly + * aligned to this boundary, @a slab_block_size must also be a multiple of + * @a slab_align. + * + * @param name Name of the memory slab. + * @param in_section Section attribute specifier such as Z_GENERIC_SECTION. + * @param slab_block_size Size of each memory block (in bytes). + * @param slab_num_blocks Number memory blocks. + * @param slab_align Alignment of the memory slab's buffer (power of 2). + */ +#define K_MEM_SLAB_DEFINE_IN_SECT_STATIC(name, in_section, slab_block_size, slab_num_blocks, \ + slab_align) \ + BUILD_ASSERT(((slab_block_size) % (slab_align)) == 0, \ + "slab_block_size must be a multiple of slab_align"); \ + BUILD_ASSERT((((slab_align) & ((slab_align) - 1)) == 0), \ + "slab_align must be a power of 2"); \ + static char in_section __aligned(WB_UP( \ + slab_align)) _k_mem_slab_buf_##name[(slab_num_blocks) * WB_UP(slab_block_size)]; \ + static STRUCT_SECTION_ITERABLE(k_mem_slab, name) = Z_MEM_SLAB_INITIALIZER( \ + name, _k_mem_slab_buf_##name, WB_UP(slab_block_size), slab_num_blocks) /** * @brief Statically define and initialize a memory slab in a private (static) scope. @@ -5501,13 +5559,9 @@ struct k_mem_slab { * @param slab_num_blocks Number memory blocks. * @param slab_align Alignment of the memory slab's buffer (power of 2). */ -#define K_MEM_SLAB_DEFINE_STATIC(name, slab_block_size, slab_num_blocks, slab_align) \ - static char __noinit_named(k_mem_slab_buf_##name) \ - __aligned(WB_UP(slab_align)) \ - _k_mem_slab_buf_##name[(slab_num_blocks) * WB_UP(slab_block_size)]; \ - static STRUCT_SECTION_ITERABLE(k_mem_slab, name) = \ - Z_MEM_SLAB_INITIALIZER(name, _k_mem_slab_buf_##name, \ - WB_UP(slab_block_size), slab_num_blocks) +#define K_MEM_SLAB_DEFINE_STATIC(name, slab_block_size, slab_num_blocks, slab_align) \ + K_MEM_SLAB_DEFINE_IN_SECT_STATIC(name, __noinit_named(k_mem_slab_buf_##name), \ + slab_block_size, slab_num_blocks, slab_align) /** * @brief Initialize a memory slab. @@ -5806,7 +5860,7 @@ void k_heap_free(struct k_heap *h, void *mem) __attribute_nonnull(1); * * @param name Symbol name for the struct k_heap object * @param bytes Size of memory region, in bytes - * @param in_section __attribute__((section(name)) + * @param in_section Section attribute specifier such as Z_GENERIC_SECTION. */ #define Z_HEAP_DEFINE_IN_SECT(name, bytes, in_section) \ char in_section \