scripts: gen_kobject_list: Generate enums and case statements
Adding a new kernel object type or driver subsystem requires changes in various different places. This patch makes it easier to create those devices by generating as much as possible in compile time. No behavior change. Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
This commit is contained in:
parent
c200367b68
commit
39dc7d03f7
|
@ -376,6 +376,8 @@ add_custom_command(
|
|||
)
|
||||
add_custom_target(driver_validation_h_target DEPENDS ${DRV_VALIDATION})
|
||||
|
||||
include($ENV{ZEPHYR_BASE}/cmake/kobj.cmake)
|
||||
gen_kobj(KOBJ_INCLUDE_PATH)
|
||||
|
||||
# Generate offsets.c.obj from offsets.c
|
||||
# Generate offsets.h from offsets.c.obj
|
||||
|
@ -390,6 +392,7 @@ add_dependencies( offsets
|
|||
syscall_list_h_target
|
||||
syscall_macros_h_target
|
||||
driver_validation_h_target
|
||||
kobj_types_h_target
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
|
|
27
cmake/kobj.cmake
Normal file
27
cmake/kobj.cmake
Normal file
|
@ -0,0 +1,27 @@
|
|||
function(gen_kobj gen_dir_out)
|
||||
if (PROJECT_BINARY_DIR)
|
||||
set(gen_dir ${PROJECT_BINARY_DIR}/include/generated)
|
||||
else ()
|
||||
set(gen_dir ${CMAKE_BINARY_DIR}/include/generated)
|
||||
endif ()
|
||||
|
||||
set(KOBJ_TYPES ${gen_dir}/kobj-types-enum.h)
|
||||
set(KOBJ_OTYPE ${gen_dir}/otype-to-str.h)
|
||||
|
||||
file(MAKE_DIRECTORY ${gen_dir})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${KOBJ_TYPES} ${KOBJ_OTYPE}
|
||||
COMMAND
|
||||
${PYTHON_EXECUTABLE}
|
||||
$ENV{ZEPHYR_BASE}/scripts/gen_kobject_list.py
|
||||
--kobj-types-output ${KOBJ_TYPES}
|
||||
--kobj-otype-output ${KOBJ_OTYPE}
|
||||
$<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose>
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
add_custom_target(kobj_types_h_target DEPENDS ${KOBJ_TYPES} ${KOBJ_OTYPE})
|
||||
|
||||
set(${gen_dir_out} ${gen_dir} PARENT_SCOPE)
|
||||
|
||||
endfunction ()
|
|
@ -211,13 +211,6 @@ Creating New Core Kernel Objects
|
|||
|
||||
* In ``scripts/gen_kobject_list.py``, add the name of the struct to the
|
||||
:py:data:`kobjects` list.
|
||||
* The name of the enumerated type is derived from the name of the struct.
|
||||
Take the name of the struct, remove the first two characters, convert to
|
||||
uppercase, and prepend ``K_OBJ_`` to it. Add the enum to
|
||||
:cpp:enum:`k_objects` in include/kernel.h. For example, ``struct k_foo``
|
||||
should be enumerated as ``K_OBJ_FOO``.
|
||||
* Add a string representation for the enum to the
|
||||
:c:func:`otype_to_str()` function in kernel/userspace.c
|
||||
|
||||
Instances of the new struct should now be tracked.
|
||||
|
||||
|
@ -229,13 +222,6 @@ what API struct they are set to.
|
|||
|
||||
* In ``scripts/gen_kobject_list.py``, add the name of the API struct for the
|
||||
new subsystem to the :py:data:`subsystems` list.
|
||||
* Take the name of the API struct, remove the trailing "_driver_api" from its
|
||||
name, convert to uppercase, and prepend ``K_OBJ_DRIVER_`` to it. This is
|
||||
the name of the enumerated type, which should be added to
|
||||
:cpp:enum:`k_objects` in include/kernel.h. For example, ``foo_driver_api``
|
||||
should be enumerated as ``K_OBJ_DRIVER_FOO``.
|
||||
* Add a string representation for the enum to the
|
||||
:c:func:`otype_to_str()` function in ``kernel/userspace.c``
|
||||
|
||||
Driver instances of the new subsystem should now be tracked.
|
||||
|
||||
|
|
|
@ -293,7 +293,11 @@ Several macros exist to validate arguments:
|
|||
fails. The latter should only be used for the most obvious of tests.
|
||||
|
||||
* :c:macro:`_SYSCALL_DRIVER_OP()` checks at runtime if a driver
|
||||
instance is capable of performing a particular operation.
|
||||
instance is capable of performing a particular operation. While this
|
||||
macro can be used by itself, it's mostly a building block for macros
|
||||
that are automatically generated for every driver subsytem. For
|
||||
instance, to validate the GPIO driver, one could use the
|
||||
:c:macro:`_SYSCALL_DRIVER_GPIO()` macro.
|
||||
|
||||
If any check fails, a kernel oops will be triggered which will kill the
|
||||
calling thread. This is done instead of returning some error condition to
|
||||
|
|
|
@ -28,61 +28,10 @@ const char *otype_to_str(enum k_objects otype)
|
|||
*/
|
||||
#ifdef CONFIG_PRINTK
|
||||
switch (otype) {
|
||||
/* Core kernel objects */
|
||||
case K_OBJ_ALERT:
|
||||
return "k_alert";
|
||||
case K_OBJ_MSGQ:
|
||||
return "k_msgq";
|
||||
case K_OBJ_MUTEX:
|
||||
return "k_mutex";
|
||||
case K_OBJ_PIPE:
|
||||
return "k_pipe";
|
||||
case K_OBJ_SEM:
|
||||
return "k_sem";
|
||||
case K_OBJ_STACK:
|
||||
return "k_stack";
|
||||
case K_OBJ_THREAD:
|
||||
return "k_thread";
|
||||
case K_OBJ_TIMER:
|
||||
return "k_timer";
|
||||
case K_OBJ__THREAD_STACK_ELEMENT:
|
||||
return "k_thread_stack_t";
|
||||
|
||||
/* Driver subsystems */
|
||||
case K_OBJ_DRIVER_ADC:
|
||||
return "adc driver";
|
||||
case K_OBJ_DRIVER_AIO_CMP:
|
||||
return "aio comparator driver";
|
||||
case K_OBJ_DRIVER_COUNTER:
|
||||
return "counter driver";
|
||||
case K_OBJ_DRIVER_CRYPTO:
|
||||
return "crypto driver";
|
||||
case K_OBJ_DRIVER_DMA:
|
||||
return "dma driver";
|
||||
case K_OBJ_DRIVER_FLASH:
|
||||
return "flash driver";
|
||||
case K_OBJ_DRIVER_GPIO:
|
||||
return "gpio driver";
|
||||
case K_OBJ_DRIVER_I2C:
|
||||
return "i2c driver";
|
||||
case K_OBJ_DRIVER_I2S:
|
||||
return "i2s driver";
|
||||
case K_OBJ_DRIVER_IPM:
|
||||
return "ipm driver";
|
||||
case K_OBJ_DRIVER_PINMUX:
|
||||
return "pinmux driver";
|
||||
case K_OBJ_DRIVER_PWM:
|
||||
return "pwm driver";
|
||||
case K_OBJ_DRIVER_ENTROPY:
|
||||
return "entropy driver";
|
||||
case K_OBJ_DRIVER_RTC:
|
||||
return "realtime clock driver";
|
||||
case K_OBJ_DRIVER_SENSOR:
|
||||
return "sensor driver";
|
||||
case K_OBJ_DRIVER_SPI:
|
||||
return "spi driver";
|
||||
case K_OBJ_DRIVER_UART:
|
||||
return "uart driver";
|
||||
/* otype-to-str.h is generated automatically during build by
|
||||
* gen_kobject_list.py
|
||||
*/
|
||||
#include <otype-to-str.h>
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
|
|
|
@ -141,6 +141,51 @@ def write_validation_output(fp):
|
|||
|
||||
fp.write("#endif /* __DRIVER_VALIDATION_GEN_H__ */\n")
|
||||
|
||||
|
||||
def write_kobj_types_output(fp):
|
||||
fp.write("/* Core kernel objects */\n")
|
||||
for kobj in kobjects:
|
||||
if kobj == "device":
|
||||
continue
|
||||
|
||||
if kobj.startswith("k_"):
|
||||
kobj = kobj[2:]
|
||||
elif kobj.startswith("_k_"):
|
||||
kobj = kobj[2:]
|
||||
|
||||
fp.write("K_OBJ_%s,\n" % kobj.upper())
|
||||
|
||||
fp.write("/* Driver subsystems */\n")
|
||||
for subsystem in subsystems:
|
||||
subsystem = subsystem.replace("_driver_api", "").upper()
|
||||
fp.write("K_OBJ_DRIVER_%s,\n" % subsystem)
|
||||
|
||||
|
||||
def write_kobj_otype_output(fp):
|
||||
fp.write("/* Core kernel objects */\n")
|
||||
for kobj in kobjects:
|
||||
if kobj == "device":
|
||||
continue
|
||||
|
||||
if kobj.startswith("k_"):
|
||||
kobj = kobj[2:]
|
||||
elif kobj.startswith("_k_"):
|
||||
kobj = kobj[2:]
|
||||
|
||||
fp.write('case K_OBJ_%s: return "%s";\n' % (
|
||||
kobj.upper(),
|
||||
kobj
|
||||
))
|
||||
|
||||
fp.write("/* Driver subsystems */\n")
|
||||
for subsystem in subsystems:
|
||||
subsystem = subsystem.replace("_driver_api", "")
|
||||
fp.write('case K_OBJ_DRIVER_%s: return "%s driver";\n' % (
|
||||
subsystem.upper(),
|
||||
subsystem
|
||||
))
|
||||
|
||||
|
||||
def parse_args():
|
||||
global args
|
||||
|
||||
|
@ -156,6 +201,12 @@ def parse_args():
|
|||
parser.add_argument(
|
||||
"-V", "--validation-output", required=False,
|
||||
help="Output driver validation macros")
|
||||
parser.add_argument(
|
||||
"-K", "--kobj-types-output", required=False,
|
||||
help="Output k_object enum values")
|
||||
parser.add_argument(
|
||||
"-S", "--kobj-otype-output", required=False,
|
||||
help="Output case statements for otype_to_str()")
|
||||
parser.add_argument("-v", "--verbose", action="store_true",
|
||||
help="Print extra debugging information")
|
||||
args = parser.parse_args()
|
||||
|
@ -187,6 +238,13 @@ def main():
|
|||
with open(args.validation_output, "w") as fp:
|
||||
write_validation_output(fp)
|
||||
|
||||
if args.kobj_types_output:
|
||||
with open(args.kobj_types_output, "w") as fp:
|
||||
write_kobj_types_output(fp)
|
||||
|
||||
if args.kobj_otype_output:
|
||||
with open(args.kobj_otype_output, "w") as fp:
|
||||
write_kobj_otype_output(fp)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
include($ENV{ZEPHYR_BASE}/tests/unit/unittest.cmake)
|
||||
project(none)
|
||||
include($ENV{ZEPHYR_BASE}/tests/unit/unittest.cmake)
|
||||
|
||||
|
|
|
@ -18,17 +18,22 @@ if(NOT SOURCES)
|
|||
set(SOURCES main.c)
|
||||
endif()
|
||||
|
||||
add_executable(testbinary ${SOURCES})
|
||||
|
||||
include($ENV{ZEPHYR_BASE}/cmake/kobj.cmake)
|
||||
add_dependencies(testbinary kobj_types_h_target)
|
||||
gen_kobj(KOBJ_GEN_DIR)
|
||||
|
||||
list(APPEND INCLUDE
|
||||
tests/ztest/include
|
||||
tests/include
|
||||
include
|
||||
.
|
||||
)
|
||||
|
||||
add_executable(testbinary ${SOURCES})
|
||||
)
|
||||
|
||||
target_compile_options(testbinary PRIVATE
|
||||
-Wall
|
||||
-I ${KOBJ_GEN_DIR}
|
||||
${EXTRA_CPPFLAGS_AS_LIST}
|
||||
${EXTRA_CFLAGS_AS_LIST}
|
||||
$<$<COMPILE_LANGUAGE:CXX>:${EXTRA_CXXFLAGS_AS_LIST}>
|
||||
|
|
Loading…
Reference in a new issue