Commit 3c47f91b authored by Victor Brzeski's avatar Victor Brzeski Committed by Daniel DeGrasse
Browse files

include: kernel: add macros to enable allocation from specific sections



This change adds two macros that allow the user to specify the section
the memslab buffer should be allocated from. This is useful for systems
where memory must reside in DMA-able memory like USB.

Signed-off-by: default avatarVictor Brzeski <vbrzeski@gmail.com>
parent 5ac9cd11
Loading
Loading
Loading
Loading
+69 −15
Original line number Diff line number Diff line
@@ -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 <name>; @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.
 *
@@ -5480,12 +5515,35 @@ struct k_mem_slab {
 * @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)
	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.
@@ -5502,12 +5560,8 @@ struct k_mem_slab {
 * @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)
	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						\