device: Add device subsystem enumeration script
The device enumeration feature requires all devices to place their API implementation in linker sections by api type. This commit adds a script which uses the tag __subsystem to identify all existing driver API types and generate iterable sections for them. The script is invoked from the top CMakeLists.txt Signed-off-by: Bjarki Arge Andreasen <baa@trackunit.com> Co-authored-by: Pieter De Gendt <pieter.degendt@basalte.be> Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
This commit is contained in:
parent
efc2cfe326
commit
ece79c3767
3 changed files with 74 additions and 0 deletions
|
@ -88,6 +88,7 @@ set(SYSCALL_LIST_H_TARGET syscall_list_h_target)
|
||||||
set(DRIVER_VALIDATION_H_TARGET driver_validation_h_target)
|
set(DRIVER_VALIDATION_H_TARGET driver_validation_h_target)
|
||||||
set(KOBJ_TYPES_H_TARGET kobj_types_h_target)
|
set(KOBJ_TYPES_H_TARGET kobj_types_h_target)
|
||||||
set(PARSE_SYSCALLS_TARGET parse_syscalls_target)
|
set(PARSE_SYSCALLS_TARGET parse_syscalls_target)
|
||||||
|
set(DEVICE_API_LD_TARGET device_api_ld_target)
|
||||||
|
|
||||||
define_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT BRIEF_DOCS " " FULL_DOCS " ")
|
define_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT BRIEF_DOCS " " FULL_DOCS " ")
|
||||||
set_property( GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-little${ARCH}) # BFD format
|
set_property( GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-little${ARCH}) # BFD format
|
||||||
|
@ -882,6 +883,28 @@ add_custom_target(${DRIVER_VALIDATION_H_TARGET} DEPENDS ${DRV_VALIDATION})
|
||||||
include(${ZEPHYR_BASE}/cmake/kobj.cmake)
|
include(${ZEPHYR_BASE}/cmake/kobj.cmake)
|
||||||
gen_kobj(KOBJ_INCLUDE_PATH)
|
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
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${DEVICE_API_LD_SECTIONS}
|
||||||
|
COMMAND
|
||||||
|
${PYTHON_EXECUTABLE}
|
||||||
|
${ZEPHYR_BASE}/scripts/build/gen_iter_sections.py
|
||||||
|
--input ${struct_tags_json}
|
||||||
|
--tag __subsystem
|
||||||
|
--ld-output ${DEVICE_API_LD_SECTIONS}
|
||||||
|
DEPENDS
|
||||||
|
${ZEPHYR_BASE}/scripts/build/gen_iter_sections.py
|
||||||
|
${struct_tags_json}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(${DEVICE_API_LD_TARGET} DEPENDS ${DEVICE_API_LD_SECTIONS})
|
||||||
|
|
||||||
# Add a pseudo-target that is up-to-date when all generated headers
|
# Add a pseudo-target that is up-to-date when all generated headers
|
||||||
# are up-to-date.
|
# are up-to-date.
|
||||||
|
|
||||||
|
@ -912,6 +935,7 @@ add_dependencies(zephyr_interface
|
||||||
${SYSCALL_LIST_H_TARGET}
|
${SYSCALL_LIST_H_TARGET}
|
||||||
${DRIVER_VALIDATION_H_TARGET}
|
${DRIVER_VALIDATION_H_TARGET}
|
||||||
${KOBJ_TYPES_H_TARGET}
|
${KOBJ_TYPES_H_TARGET}
|
||||||
|
${DEVICE_API_LD_TARGET}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
|
|
@ -102,3 +102,5 @@
|
||||||
#include <zephyr/linker/device-deps.ld>
|
#include <zephyr/linker/device-deps.ld>
|
||||||
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||||
#endif /* !CONFIG_DEVICE_DEPS_DYNAMIC */
|
#endif /* !CONFIG_DEVICE_DEPS_DYNAMIC */
|
||||||
|
|
||||||
|
#include <device-api-sections.ld>
|
||||||
|
|
48
scripts/build/gen_iter_sections.py
Normal file
48
scripts/build/gen_iter_sections.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 Bjarki Arge Andreasen
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
"""
|
||||||
|
Script to generate iterable sections from JSON encoded dictionary containing lists of items.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def get_tagged_items(filepath: str, tag: str) -> list:
|
||||||
|
with open(filepath) as fp:
|
||||||
|
return json.load(fp)[tag]
|
||||||
|
|
||||||
|
|
||||||
|
def gen_ld(filepath: str, items: list):
|
||||||
|
with open(filepath, "w") as fp:
|
||||||
|
for item in items:
|
||||||
|
fp.write(f"ITERABLE_SECTION_ROM({item}, Z_LINK_ITERABLE_SUBALIGN)\n")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args() -> argparse.Namespace:
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description=__doc__,
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
allow_abbrev=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument("-i", "--input", required=True, help="Path to input list of tags")
|
||||||
|
parser.add_argument("-t", "--tag", required=True, help="Tag to generate iterable sections for")
|
||||||
|
parser.add_argument("-l", "--ld-output", required=True, help="Path to output linker file")
|
||||||
|
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_args()
|
||||||
|
|
||||||
|
items = get_tagged_items(args.input, args.tag)
|
||||||
|
|
||||||
|
gen_ld(args.ld_output, items)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Add table
Add a link
Reference in a new issue