scripts/Kconfig: add dt_node_array_prop Kconfig functions

The motivation is to allow accessing array elements from device tree
properties in Kconfig.
* Add dt_node_array_prop and _node_array_prop functions to extract the
array elements from properties.
* Add 'dt_node_array_prop_int' and 'dt_node_array_prop_hex' keys to use
in Kconfig.

Signed-off-by: Eivind Jølsgard <eivind.jolsgard@nordicsemi.no>
This commit is contained in:
Eivind Jølsgard 2022-03-18 10:50:00 +01:00 committed by Carles Cufí
commit 3865e08c96
7 changed files with 129 additions and 0 deletions

View file

@ -211,6 +211,32 @@ def _node_int_prop(node, prop, unit=None):
return node.props[prop].val >> _dt_units_to_scale(unit) return node.props[prop].val >> _dt_units_to_scale(unit)
def _node_array_prop(node, prop, index=0, unit=None):
"""
This function takes a 'node' and will look to see if that 'node' has a
property called 'prop' and if that 'prop' is an array type will return
the value of the property 'prop' at the given 'index' as either a string int
or string hex value. If the property 'prop' is not found or the given 'index'
is out of range it will return 0.
The function will divide the value based on 'unit':
None No division
'k' or 'K' divide by 1024 (1 << 10)
'm' or 'M' divide by 1,048,576 (1 << 20)
'g' or 'G' divide by 1,073,741,824 (1 << 30)
"""
if not node:
return 0
if prop not in node.props:
return 0
if node.props[prop].type != "array":
return 0
if int(index) >= len(node.props[prop].val):
return 0
return node.props[prop].val[int(index)] >> _dt_units_to_scale(unit)
def _dt_chosen_reg_addr(kconf, chosen, index=0, unit=None): def _dt_chosen_reg_addr(kconf, chosen, index=0, unit=None):
""" """
This function takes a 'chosen' property and treats that property as a path This function takes a 'chosen' property and treats that property as a path
@ -448,6 +474,34 @@ def dt_node_int_prop(kconf, name, path, prop, unit=None):
if name == "dt_node_int_prop_hex": if name == "dt_node_int_prop_hex":
return hex(_node_int_prop(node, prop, unit)) return hex(_node_int_prop(node, prop, unit))
def dt_node_array_prop(kconf, name, path, prop, index, unit=None):
"""
This function takes a 'path', property name ('prop') and index ('index')
and looks for an EDT node at that path. If it finds an EDT node, it will
look to see if that node has a property called 'prop' and if that 'prop'
is an array type will return the value of the property 'prop' at the given
'index' as either a string int or string hex value. If not found we return 0.
The function will divide the value based on 'unit':
None No division
'k' or 'K' divide by 1024 (1 << 10)
'm' or 'M' divide by 1,048,576 (1 << 20)
'g' or 'G' divide by 1,073,741,824 (1 << 30)
"""
if doc_mode or edt is None:
return "0"
try:
node = edt.get_node(path)
except edtlib.EDTError:
return "0"
if name == "dt_node_array_prop_int":
return str(_node_array_prop(node, prop, index, unit))
if name == "dt_node_array_prop_hex":
return hex(_node_array_prop(node, prop, index, unit))
def dt_node_str_prop_equals(kconf, _, path, prop, val): def dt_node_str_prop_equals(kconf, _, path, prop, val):
""" """
This function takes a 'path' and property name ('prop') looks for an EDT This function takes a 'path' and property name ('prop') looks for an EDT
@ -611,6 +665,8 @@ functions = {
"dt_nodelabel_has_prop": (dt_nodelabel_has_prop, 2, 2), "dt_nodelabel_has_prop": (dt_nodelabel_has_prop, 2, 2),
"dt_node_int_prop_int": (dt_node_int_prop, 2, 3), "dt_node_int_prop_int": (dt_node_int_prop, 2, 3),
"dt_node_int_prop_hex": (dt_node_int_prop, 2, 3), "dt_node_int_prop_hex": (dt_node_int_prop, 2, 3),
"dt_node_array_prop_int": (dt_node_array_prop, 3, 4),
"dt_node_array_prop_hex": (dt_node_array_prop, 3, 4),
"dt_node_str_prop_equals": (dt_node_str_prop_equals, 3, 3), "dt_node_str_prop_equals": (dt_node_str_prop_equals, 3, 3),
"dt_nodelabel_has_compat": (dt_nodelabel_has_compat, 2, 2), "dt_nodelabel_has_compat": (dt_nodelabel_has_compat, 2, 2),
"dt_nodelabel_path": (dt_nodelabel_path, 1, 1), "dt_nodelabel_path": (dt_nodelabel_path, 1, 1),

View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(kconfigoptions)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

View file

@ -0,0 +1,19 @@
# Copyright (c) 2022 Nordic Semiconductor
#
# SPDX-License-Identifier: Apache-2.0
#
DT_FLASH_CONTROLLER := $(dt_nodelabel_path,flashcontroller0)
config FLASH_CONTROLLER_ADDRESS
int
default $(dt_node_array_prop_int,$(DT_FLASH_CONTROLLER),reg,0)
config FLASH_CONTROLLER_SIZE
int
default $(dt_node_array_prop_int,$(DT_FLASH_CONTROLLER),reg,1)
menu "Zephyr Kernel"
source "Kconfig.zephyr"
endmenu

View file

@ -0,0 +1,9 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
&flashcontroller0 {
reg = <0x00000001 4194304>;
};

View file

@ -0,0 +1 @@
CONFIG_ZTEST=y

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
/**
* @brief Test .
*
*/
void test_kconfigoptions_array_hex(void)
{
zassert_equal(0x1, CONFIG_FLASH_CONTROLLER_ADDRESS,
"Unexpected flash controller address (%d)", CONFIG_FLASH_CONTROLLER_ADDRESS);
}
void test_kconfigoptions_array_int(void)
{
zassert_equal(4194304, CONFIG_FLASH_CONTROLLER_SIZE,
"Unexpected flash controller size (%d)", CONFIG_FLASH_CONTROLLER_SIZE);
}
void test_main(void)
{
ztest_test_suite(kconfigoptions,
ztest_unit_test(test_kconfigoptions_array_hex),
ztest_unit_test(test_kconfigoptions_array_int)
);
ztest_run_test_suite(kconfigoptions);
}

View file

@ -0,0 +1,4 @@
tests:
misc.kconfigoptions:
tags: kconfigoptions
platform_allow: native_posix