Skip to content

Commit b493b66

Browse files
Bjarki Arge Andreasenpdgendt
andcommitted
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 <[email protected]> Co-authored-by: Pieter De Gendt <[email protected]> Signed-off-by: Pieter De Gendt <[email protected]>
1 parent 0d66091 commit b493b66

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ set(SYSCALL_LIST_H_TARGET syscall_list_h_target)
8888
set(DRIVER_VALIDATION_H_TARGET driver_validation_h_target)
8989
set(KOBJ_TYPES_H_TARGET kobj_types_h_target)
9090
set(PARSE_SYSCALLS_TARGET parse_syscalls_target)
91+
set(DEVICE_API_LD_TARGET device_api_ld_target)
9192

9293
define_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT BRIEF_DOCS " " FULL_DOCS " ")
9394
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})
882883
include(${ZEPHYR_BASE}/cmake/kobj.cmake)
883884
gen_kobj(KOBJ_INCLUDE_PATH)
884885

886+
# Generate sections for kernel device subsystems
887+
set(
888+
DEVICE_API_LD_SECTIONS
889+
${CMAKE_CURRENT_BINARY_DIR}/include/generated/device-api-sections.ld
890+
)
891+
892+
add_custom_command(
893+
OUTPUT ${DEVICE_API_LD_SECTIONS}
894+
COMMAND
895+
${PYTHON_EXECUTABLE}
896+
${ZEPHYR_BASE}/scripts/build/gen_iter_sections.py
897+
--input ${struct_tags_json}
898+
--tag __subsystem
899+
--ld-output ${DEVICE_API_LD_SECTIONS}
900+
DEPENDS
901+
${ZEPHYR_BASE}/scripts/build/gen_iter_sections.py
902+
${struct_tags_json}
903+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
904+
)
905+
906+
add_custom_target(${DEVICE_API_LD_TARGET} DEPENDS ${DEVICE_API_LD_SECTIONS})
907+
885908
# Add a pseudo-target that is up-to-date when all generated headers
886909
# are up-to-date.
887910

@@ -912,6 +935,7 @@ add_dependencies(zephyr_interface
912935
${SYSCALL_LIST_H_TARGET}
913936
${DRIVER_VALIDATION_H_TARGET}
914937
${KOBJ_TYPES_H_TARGET}
938+
${DEVICE_API_LD_TARGET}
915939
)
916940

917941
add_custom_command(

include/zephyr/linker/common-rom/common-rom-kernel-devices.ld

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,5 @@
102102
#include <zephyr/linker/device-deps.ld>
103103
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
104104
#endif /* !CONFIG_DEVICE_DEPS_DYNAMIC */
105+
106+
#include <device-api-sections.ld>

scripts/build/gen_iter_sections.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2023 Bjarki Arge Andreasen
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
"""
7+
Script to generate iterable sections from JSON encoded dictionary containing lists of items.
8+
"""
9+
10+
import argparse
11+
import json
12+
13+
14+
def get_tagged_items(filepath: str, tag: str) -> list:
15+
with open(filepath) as fp:
16+
return json.load(fp)[tag]
17+
18+
19+
def gen_ld(filepath: str, items: list):
20+
with open(filepath, "w") as fp:
21+
for item in items:
22+
fp.write(f"ITERABLE_SECTION_ROM({item}, Z_LINK_ITERABLE_SUBALIGN)\n")
23+
24+
25+
def parse_args() -> argparse.Namespace:
26+
parser = argparse.ArgumentParser(
27+
description=__doc__,
28+
formatter_class=argparse.RawDescriptionHelpFormatter,
29+
allow_abbrev=False,
30+
)
31+
32+
parser.add_argument("-i", "--input", required=True, help="Path to input list of tags")
33+
parser.add_argument("-t", "--tag", required=True, help="Tag to generate iterable sections for")
34+
parser.add_argument("-l", "--ld-output", required=True, help="Path to output linker file")
35+
36+
return parser.parse_args()
37+
38+
39+
def main():
40+
args = parse_args()
41+
42+
items = get_tagged_items(args.input, args.tag)
43+
44+
gen_ld(args.ld_output, items)
45+
46+
47+
if __name__ == "__main__":
48+
main()

0 commit comments

Comments
 (0)