mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
core: Introduce cross file arrays (XFA)
Co-Authored-By: Joakim Nohlgård <joakim.nohlgard@eistec.se>
This commit is contained in:
parent
09df6a4549
commit
66092f5506
@ -357,6 +357,11 @@ endif
|
||||
# Add standard include directories
|
||||
INCLUDES += -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/sys/include
|
||||
|
||||
# Augmentation ldscript for cross file arrays (XFA)
|
||||
# this argument must come before any other -T options on the command line,
|
||||
# otherwise we get an error message ".text not found for insert"
|
||||
LINKFLAGS += -Txfa.ld
|
||||
|
||||
# process provided features
|
||||
include $(RIOTBASE)/Makefile.features
|
||||
|
||||
@ -416,6 +421,10 @@ TOOLCHAINS_SUPPORTED ?= gnu
|
||||
# Import all toolchain settings
|
||||
include $(RIOTMAKE)/toolchain/$(TOOLCHAIN).inc.mk
|
||||
|
||||
# Append ldscript path after importing CPU and board makefiles to allow
|
||||
# overriding the core ldscripts
|
||||
LINKFLAGS += -L$(RIOTBASE)/core/ldscripts
|
||||
|
||||
# Tell ccache to pass the original file to the compiler, instead of passing the
|
||||
# preprocessed code. Without this setting, the compilation will fail with
|
||||
# -Wimplicit-fallthrough warnings even when the fall through case is properly
|
||||
|
153
core/include/xfa.h
Normal file
153
core/include/xfa.h
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup core_util
|
||||
* @brief Cross File Arrays
|
||||
* @{
|
||||
*
|
||||
* This macro, in combination with an entry in the linker scripts, allows the
|
||||
* definition of constant arrays to be spread over multiple C compilation
|
||||
* units. These arrays are called "cross-file arrays" or short xfa.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @file
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#ifndef XFA_H
|
||||
#define XFA_H
|
||||
|
||||
/**
|
||||
* @brief helper macro for other XFA_* macros
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
#define _XFA(name, prio) __attribute__((used, section(".xfa." #name "." #prio)))
|
||||
|
||||
/**
|
||||
* @brief helper macro for other XFA_* macros
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
#define _XFA_CONST(name, prio) __attribute__((used, section(".roxfa." #name "." #prio))) const
|
||||
|
||||
/**
|
||||
* @brief Define a read-only cross-file array
|
||||
*
|
||||
* This macro defines the symbols necessary to use XFA_START() and XFA_END().
|
||||
* It needs to be part of one single compilation unit.
|
||||
*
|
||||
* @param[in] type name of the cross-file array
|
||||
* @param[in] name name of the cross-file array
|
||||
*/
|
||||
#define XFA_INIT_CONST(type, name) \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wpedantic\"") \
|
||||
_XFA_CONST(name, 0_) const type name [0] = {}; \
|
||||
_XFA_CONST(name, 9_) const type name ## _end [0] = {}; \
|
||||
_Pragma("GCC diagnostic pop") \
|
||||
extern const unsigned __xfa_dummy
|
||||
|
||||
/**
|
||||
* @brief Define a writable cross-file array
|
||||
*
|
||||
* This macro defines the symbols necessary to use XFA_START() and XFA_END().
|
||||
* It needs to be part of one single compilation unit.
|
||||
*
|
||||
* @param[in] type name of the cross-file array
|
||||
* @param[in] name name of the cross-file array
|
||||
*/
|
||||
#define XFA_INIT(type, name) \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wpedantic\"") \
|
||||
_XFA(name, 0_) type name [0] = {}; \
|
||||
_XFA(name, 9_) type name ## _end [0] = {}; \
|
||||
_Pragma("GCC diagnostic pop") \
|
||||
extern const unsigned __xfa_dummy
|
||||
|
||||
/**
|
||||
* @brief Declare an external read-only cross-file array
|
||||
*
|
||||
* This macro defines the symbols necessary to use XFA_START() and XFA_END().
|
||||
* Think of this as XFA_INIT() but with "extern" keyword.
|
||||
* It is supposed to be used in compilation units where the cross file array is
|
||||
* being accessed, but not defined using XFA_INIT.
|
||||
*
|
||||
* @param[in] type name of the cross-file array
|
||||
* @param[in] name name of the cross-file array
|
||||
*/
|
||||
#define XFA_USE_CONST(type, name) \
|
||||
extern const type name []; \
|
||||
extern const type name ## _end []
|
||||
|
||||
/**
|
||||
* @brief Declare an external writable cross-file array
|
||||
*
|
||||
* This macro defines the symbols necessary to use XFA_START() and XFA_END().
|
||||
* Think of this as XFA_INIT() but with "extern" keyword.
|
||||
* It is supposed to be used in compilation units where the cross file array is
|
||||
* being accessed, but not defined using XFA_INIT.
|
||||
*
|
||||
* @param[in] type name of the cross-file array
|
||||
* @param[in] name name of the cross-file array
|
||||
*/
|
||||
#define XFA_USE(type, name) \
|
||||
extern type name []; \
|
||||
extern type name ## _end []
|
||||
|
||||
/**
|
||||
* @brief Define variable in writable cross-file array
|
||||
*
|
||||
* Variables will end up sorted by prio.
|
||||
*
|
||||
* Add this to the type in a variable definition, e.g.:
|
||||
*
|
||||
* XFA(driver_params, 0) driver_params_t _onboard = { .pin=42 };
|
||||
*
|
||||
* @param[in] name name of the xfa
|
||||
* @param[in] prio priority within the xfa
|
||||
*/
|
||||
#define XFA(xfa_name, prio) _XFA(xfa_name, 5_ ##prio)
|
||||
|
||||
/**
|
||||
* @brief Define variable in read-only cross-file array
|
||||
*
|
||||
* Variables will end up sorted by prio.
|
||||
*
|
||||
* Add this to the type in a variable definition, e.g.:
|
||||
*
|
||||
* XFA(driver_params, 0) driver_params_t _onboard = { .pin=42 };
|
||||
*
|
||||
* @param[in] name name of the xfa
|
||||
* @param[in] prio priority within the xfa
|
||||
*/
|
||||
#define XFA_CONST(xfa_name, prio) _XFA_CONST(xfa_name, 5_ ##prio)
|
||||
|
||||
/**
|
||||
* @brief Add a pointer to cross-file array
|
||||
*
|
||||
* Pointers will end up sorted by prio.
|
||||
*
|
||||
* @param[in] xfa_name name of the xfa
|
||||
* @param[in] prio priority within the xfa
|
||||
* @param[in] name symbol name
|
||||
* @param[in] entry pointer variable to add to xfa
|
||||
*/
|
||||
#define XFA_ADD_PTR(xfa_name, prio, name, entry) \
|
||||
_XFA_CONST(xfa_name, 5_ ##prio) \
|
||||
const typeof(entry) xfa_name ## _ ## prio ## _ ## name = entry
|
||||
|
||||
/**
|
||||
* @brief Calculate number of entries in cross-file array
|
||||
*/
|
||||
#define XFA_LEN(type, name) (((const char*)name ## _end - (const char*)name) / sizeof(type))
|
||||
|
||||
/** @} */
|
||||
#endif /* XFA_H */
|
23
core/ldscripts/xfa.ld
Normal file
23
core/ldscripts/xfa.ld
Normal file
@ -0,0 +1,23 @@
|
||||
SECTIONS
|
||||
{
|
||||
.data :
|
||||
{
|
||||
KEEP (*(SORT(.xfa.*)))
|
||||
}
|
||||
__data_start = ADDR(.data);
|
||||
__data_load_start = LOADADDR(.data);
|
||||
__data_end = (__data_start + SIZEOF(.data));
|
||||
__data_load_end = (__data_load_start + SIZEOF(.data));
|
||||
}
|
||||
|
||||
INSERT AFTER .text;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.rodata :
|
||||
{
|
||||
KEEP (*(SORT(.roxfa.*)))
|
||||
}
|
||||
}
|
||||
|
||||
INSERT AFTER .text;
|
Loading…
Reference in New Issue
Block a user