Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC][PoC] Zephyr PreProcessor (ZPP) framework #82990

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 28 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ set(SYSCALL_LIST_H_TARGET syscall_list_h_target)
set(DRIVER_VALIDATION_H_TARGET driver_validation_h_target)
set(KOBJ_TYPES_H_TARGET kobj_types_h_target)
set(PARSE_SYSCALLS_TARGET parse_syscalls_target)
set(DEVICE_API_LD_TARGET device_api_ld_target)
set(ITERABLE_STRUCTS_LD_TARGET iterable_structs_ld_target)

define_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT BRIEF_DOCS " " FULL_DOCS " ")
set_property( GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-little${ARCH}) # BFD format
Expand Down Expand Up @@ -121,6 +121,7 @@ zephyr_include_directories(
${STDINCLUDE}
)

include(${ZEPHYR_BASE}/cmake/zpp.cmake)
include(${ZEPHYR_BASE}/cmake/linker_script/${ARCH}/linker.cmake OPTIONAL)

zephyr_include_directories(${SOC_FULL_DIR})
Expand All @@ -137,6 +138,7 @@ foreach(var AFLAGS CFLAGS CXXFLAGS CPPFLAGS LDFLAGS)
endforeach()

zephyr_compile_definitions(
ZPP
KERNEL
__ZEPHYR__=1
)
Expand Down Expand Up @@ -680,6 +682,7 @@ set(ZEPHYR_CURRENT_CMAKE_DIR)
get_property(LIBC_LINK_LIBRARIES TARGET zephyr_interface PROPERTY LIBC_LINK_LIBRARIES)
zephyr_link_libraries(${LIBC_LINK_LIBRARIES})

set(annotations_json ${CMAKE_BINARY_DIR}/zephyr/annotations.json)
set(syscall_list_h ${CMAKE_CURRENT_BINARY_DIR}/include/generated/zephyr/syscall_list.h)
set(edk_syscall_list_h ${CMAKE_CURRENT_BINARY_DIR}/edk/include/generated/zephyr/syscall_list.h)
set(syscalls_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls.json)
Expand Down Expand Up @@ -897,33 +900,43 @@ gen_kobj(KOBJ_INCLUDE_PATH)

# Generate sections for kernel device subsystems
set(
DEVICE_API_LD_SECTIONS
${CMAKE_CURRENT_BINARY_DIR}/include/generated/device-api-sections.ld
ITERABLE_STRUCTS_LD_RAM_SECTIONS
${CMAKE_CURRENT_BINARY_DIR}/include/generated/iterable-structs-ram-sections.ld
)
set(
ITERABLE_STRUCTS_LD_ROM_SECTIONS
${CMAKE_CURRENT_BINARY_DIR}/include/generated/iterable-structs-rom-sections.ld
)

set(DEVICE_API_LINKER_SECTIONS_CMAKE
${CMAKE_CURRENT_BINARY_DIR}/include/generated/device-api-sections.cmake
set(ITERABLE_STRUCTS_LINKER_SECTIONS_CMAKE
${CMAKE_CURRENT_BINARY_DIR}/include/generated/iterable-structs-sections.cmake
)

add_custom_command(
OUTPUT ${DEVICE_API_LD_SECTIONS} ${DEVICE_API_LINKER_SECTIONS_CMAKE}
OUTPUT
${ITERABLE_STRUCTS_LD_RAM_SECTIONS}
${ITERABLE_STRUCTS_LD_ROM_SECTIONS}
${ITERABLE_STRUCTS_LINKER_SECTIONS_CMAKE}
COMMAND
${PYTHON_EXECUTABLE}
${ZEPHYR_BASE}/scripts/build/gen_iter_sections.py
--alignment ${CONFIG_LINKER_ITERABLE_SUBALIGN}
--input ${struct_tags_json}
--tag __subsystem
--ld-output ${DEVICE_API_LD_SECTIONS}
--cmake-output ${DEVICE_API_LINKER_SECTIONS_CMAKE}
--input ${annotations_json}
$<$<BOOL:${CONFIG_XIP}>:--xip>
--ld-ram-output ${ITERABLE_STRUCTS_LD_RAM_SECTIONS}
--ld-rom-output ${ITERABLE_STRUCTS_LD_ROM_SECTIONS}
--cmake-output ${ITERABLE_STRUCTS_LINKER_SECTIONS_CMAKE}
--cmake-prefix "ITERABLE_STRUCTS"
DEPENDS
${ZEPHYR_BASE}/scripts/build/gen_iter_sections.py
${struct_tags_json}
${annotations_json}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

add_custom_target(${DEVICE_API_LD_TARGET}
DEPENDS ${DEVICE_API_LD_SECTIONS}
${DEVICE_API_LINKER_SECTIONS_CMAKE}
add_custom_target(${ITERABLE_STRUCTS_LD_TARGET}
DEPENDS ${ITERABLE_STRUCTS_LD_RAM_SECTIONS}
${ITERABLE_STRUCTS_LD_ROM_SECTIONS}
${ITERABLE_STRUCTS_LINKER_SECTIONS_CMAKE}
)

# Add a pseudo-target that is up-to-date when all generated headers
Expand Down Expand Up @@ -956,7 +969,7 @@ add_dependencies(zephyr_interface
${SYSCALL_LIST_H_TARGET}
${DRIVER_VALIDATION_H_TARGET}
${KOBJ_TYPES_H_TARGET}
${DEVICE_API_LD_TARGET}
${ITERABLE_STRUCTS_LD_TARGET}
)

add_custom_command(
Expand Down
4 changes: 2 additions & 2 deletions cmake/linker/armlink/target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ macro(configure_linker_script linker_script_gen linker_pass_define)
${STEERING_FILE}
${STEERING_C}
COMMAND ${CMAKE_COMMAND}
-C ${DEVICE_API_LINKER_SECTIONS_CMAKE}
-C ${ITERABLE_STRUCTS_LINKER_SECTIONS_CMAKE}
-C ${cmake_linker_script_settings}
-DPASS="${linker_pass_define}"
${STEERING_FILE_ARG}
${STEERING_C_ARG}
-DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen}
-P ${ZEPHYR_BASE}/cmake/linker/armlink/scatter_script.cmake
DEPENDS ${DEVICE_API_LD_TARGET}
DEPENDS ${ITERABLE_STRUCTS_LD_TARGET}
)

if("LINKER_ZEPHYR_FINAL" IN_LIST linker_pass_define_list)
Expand Down
4 changes: 2 additions & 2 deletions cmake/linker/ld/target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ macro(configure_linker_script linker_script_gen linker_pass_define)
add_custom_command(
OUTPUT ${linker_script_gen}
COMMAND ${CMAKE_COMMAND}
-C ${DEVICE_API_LINKER_SECTIONS_CMAKE}
-C ${ITERABLE_STRUCTS_LINKER_SECTIONS_CMAKE}
-C ${cmake_linker_script_settings}
-DPASS="${linker_pass_define}"
-DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen}
-P ${ZEPHYR_BASE}/cmake/linker/ld/ld_script.cmake
DEPENDS ${DEVICE_API_LD_TARGET}
DEPENDS ${ITERABLE_STRUCTS_LD_TARGET}
)
else()
set(template_script_defines ${linker_pass_define})
Expand Down
4 changes: 2 additions & 2 deletions cmake/linker/linker_script_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function(create_section)
set(INDEX 100)
set(settings_single "ALIGN;ANY;FIRST;KEEP;OFFSET;PRIO;SECTION;SORT")
set(settings_multi "FLAGS;INPUT;PASS;SYMBOLS")
foreach(settings ${SECTION_SETTINGS} ${DEVICE_API_SECTION_SETTINGS})
foreach(settings ${SECTION_SETTINGS} ${ITERABLE_STRUCTS_SECTION_SETTINGS})
if("${settings}" MATCHES "^{(.*)}$")
cmake_parse_arguments(SETTINGS "" "${settings_single}" "${settings_multi}" ${CMAKE_MATCH_1})

Expand Down Expand Up @@ -652,7 +652,7 @@ foreach(group ${GROUPS})
endif()
endforeach()

foreach(section ${SECTIONS} ${DEVICE_API_SECTIONS})
foreach(section ${SECTIONS} ${ITERABLE_STRUCTS_SECTIONS})
if("${section}" MATCHES "^{(.*)}$")
create_section(${CMAKE_MATCH_1} SYSTEM ${new_system})
endif()
Expand Down
25 changes: 0 additions & 25 deletions cmake/linker_script/common/common-rom.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,6 @@ zephyr_linker_section_configure(
KEEP SORT NAME
)

if(CONFIG_NET_SOCKETS)
zephyr_iterable_section(NAME net_socket_register KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
endif()


if(CONFIG_NET_L2_PPP)
zephyr_iterable_section(NAME ppp_protocol_handler KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
endif()

zephyr_iterable_section(NAME bt_l2cap_fixed_chan KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})

if(CONFIG_BT_CLASSIC)
Expand Down Expand Up @@ -161,10 +152,6 @@ if(CONFIG_EMUL)
zephyr_iterable_section(NAME emul KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
endif()

if(CONFIG_DNS_SD)
zephyr_iterable_section(NAME dns_sd_rec KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
endif()

if(CONFIG_PCIE)
zephyr_iterable_section(NAME irq_alloc KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
endif()
Expand Down Expand Up @@ -214,18 +201,6 @@ if (CONFIG_MULTI_LEVEL_INTERRUPTS)
zephyr_iterable_section(NAME intc_table KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
endif()

if (CONFIG_HTTP_SERVER)
zephyr_iterable_section(NAME http_service_desc KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
endif()

if (CONFIG_COAP_SERVER)
zephyr_iterable_section(NAME coap_service KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
endif()

if (CONFIG_NET_MGMT)
zephyr_iterable_section(NAME net_mgmt_event_static_handler KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
endif()

if(CONFIG_INPUT)
zephyr_iterable_section(NAME input_callback KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
endif()
Expand Down
27 changes: 27 additions & 0 deletions cmake/zpp.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright (c) 2024 Basalte bv
#
# SPDX-License-Identifier: Apache-2.0

# Generate compile_commands.json in the output directory
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE CACHE BOOL
"Export CMake compile commands. Used by zpp.py script"
FORCE
)
Comment on lines +5 to +9
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is already set in cmake/modules/kernel.cmake

Copy link
Collaborator Author

@pdgendt pdgendt Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied it from there, it should be merged somewhere indeed, but for the PoC it was easier to have it here with less chance of getting conflicts.


set(annotations_json "${CMAKE_BINARY_DIR}/zephyr/annotations.json")

add_custom_command(
OUTPUT ${annotations_json}
COMMAND
${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/zpp.py
-j ${CMAKE_BUILD_PARALLEL_LEVEL}
-o ${annotations_json}
-d ${annotations_json}.d
${CMAKE_BINARY_DIR}/compile_commands.json
DEPENDS
${ZEPHYR_BASE}/scripts/zpp.py
${CMAKE_BINARY_DIR}/compile_commands.json
DEPFILE ${annotations_json}.d
)

add_custom_target(zpp DEPENDS ${annotations_json})
2 changes: 2 additions & 0 deletions include/zephyr/linker/common-ram.ld
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,5 @@ ITERABLE_SECTION_RAM(scmi_protocol, Z_LINK_ITERABLE_SUBALIGN)
#ifdef CONFIG_USERSPACE
_static_kernel_objects_end = .;
#endif

#include <iterable-structs-ram-sections.ld>
2 changes: 0 additions & 2 deletions include/zephyr/linker/common-rom.ld
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

#include <zephyr/linker/common-rom/common-rom-init.ld>

#include <zephyr/linker/common-rom/common-rom-net.ld>

#include <zephyr/linker/common-rom/common-rom-bt.ld>

#include <zephyr/linker/common-rom/common-rom-logging.ld>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,4 @@
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
#endif /* !CONFIG_DEVICE_DEPS_DYNAMIC */

#include <device-api-sections.ld>
#include <iterable-structs-rom-sections.ld>
31 changes: 0 additions & 31 deletions include/zephyr/linker/common-rom/common-rom-net.ld

This file was deleted.

2 changes: 1 addition & 1 deletion include/zephyr/net/coap_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct coap_service_data {
struct coap_pending pending[CONFIG_COAP_SERVICE_PENDING_MESSAGES];
};

struct coap_service {
__iterable_section_rom struct coap_service {
const char *name;
const char *host;
uint16_t *port;
Expand Down
2 changes: 1 addition & 1 deletion include/zephyr/net/dns_sd.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ extern "C" {
*
* @see <a href="https://tools.ietf.org/html/rfc6763">RFC 6763</a>
*/
struct dns_sd_rec {
__iterable_section_rom struct dns_sd_rec {
/** "<Instance>" - e.g. "My HTTP Server" */
const char *instance;
/** Top half of the "<Service>" such as "_http" */
Expand Down
2 changes: 1 addition & 1 deletion include/zephyr/net/http/service.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct http_resource_desc {

/** @cond INTERNAL_HIDDEN */

struct http_service_desc {
__iterable_section_rom struct http_service_desc {
const char *host;
uint16_t *port;
int *fd;
Expand Down
2 changes: 1 addition & 1 deletion include/zephyr/net/net_mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ typedef void (*net_mgmt_event_static_handler_t)(uint32_t mgmt_event,
/** @cond INTERNAL_HIDDEN */

/* Structure for event handler registered at compile time */
struct net_mgmt_event_static_handler {
__iterable_section_rom struct net_mgmt_event_static_handler {
uint32_t event_mask;
net_mgmt_event_static_handler_t handler;
void *user_data;
Expand Down
2 changes: 1 addition & 1 deletion include/zephyr/net/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -1132,7 +1132,7 @@ struct in6_pktinfo {
/**
* @brief Registration information for a given BSD socket family.
*/
struct net_socket_register {
__iterable_section_rom struct net_socket_register {
int family;
bool is_offloaded;
bool (*is_supported)(int family, int type, int proto);
Expand Down
2 changes: 1 addition & 1 deletion include/zephyr/net/socket_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct net_socket_service_event {
* User should create needed sockets and then setup the poll struct and
* then register the sockets to be monitored at runtime.
*/
struct net_socket_service_desc {
__iterable_section_rom struct net_socket_service_desc {
#if CONFIG_NET_SOCKETS_LOG_LEVEL >= LOG_LEVEL_DBG
/**
* Owner name. This can be used in debugging to see who has
Expand Down
25 changes: 23 additions & 2 deletions include/zephyr/toolchain/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@
#define EXTERN_C extern
#endif

/*
* Use C23 attributes with our own prefix to make sure the C preprocessor
* has content for the annotations.
*/
#ifdef __ZPP__
#define __zpp(x) [[zephyr::x]]
#else
#define __zpp(...)
#endif

/* Use TASK_ENTRY_CPP to tag task entry points defined in C++ files. */

#ifdef __cplusplus
Expand Down Expand Up @@ -147,9 +157,14 @@
* not used).
*/
#ifndef ZTEST_UNITTEST
#ifndef __ZPP__
#define __syscall static inline
#define __syscall_always_inline static inline __attribute__((always_inline))
#else
#define __syscall __zpp(func("syscall", __FILE__, __LINE__))
#define __syscall_always_inline __zpp(func("syscall", __FILE__, __LINE__))
Comment on lines +160 to +165
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: both expand to the same?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The __syscall part hasn't been refactored yet, and this is mostly to demonstrate part of the output.

But I think the current syscall parsing also behaves the same, they end up different when compiling only.

#endif
#else
#define __syscall
#define __syscall_always_inline
#endif /* ZTEST_UNITTEST */
Expand All @@ -160,10 +175,16 @@
*/

/* Indicates this is a driver subsystem */
#define __subsystem
#define __subsystem __zpp(struct("__subsystem", "iterable", "ROM"))

/* Indicates this is a network socket object */
#define __net_socket
#define __net_socket __zpp(struct("__net_socket"))

/* Indicates a struct iterable section should be added in ROM */
#define __iterable_section_rom __zpp(struct("iterable", "ROM"))

/* Indicates a struct iterable section should be added in RAM */
#define __iterable_section_ram __zpp(struct("iterable", "RAM"))

#ifndef BUILD_ASSERT
/* Compile-time assertion that makes the build to fail.
Expand Down
Loading
Loading