device: fix potential truncation of DT-derived device names
While using the encoded path to a device tree node guarantees a unique identifier for the corresponding device there is a limit on the number of characters of that name that can be captured when looking up a device by name from user mode, and the path can exceed that limit. Synthesize a unique name from the node dependency ordinal instead, and update the gen_defines script to record the name associated with the full path in the extern declaration. Add a build-time check that no device is created with a name that violates the user mode requirement. Also update the network device DTS helper functions to use the same inference for dev_name and label that the real one does, since they bypass the real one. Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
parent
0782f9c4a6
commit
f91e9fba51
4 changed files with 25 additions and 9 deletions
|
@ -99,7 +99,8 @@ extern "C" {
|
|||
* since the API is not specified;
|
||||
*
|
||||
* @param dev_name Device name. This must be less than Z_DEVICE_MAX_NAME_LEN
|
||||
* characters in order to be looked up from user mode with device_get_binding().
|
||||
* characters (including terminating NUL) in order to be looked up from user
|
||||
* mode with device_get_binding().
|
||||
*
|
||||
* @param drv_name The name this instance of the driver exposes to
|
||||
* the system.
|
||||
|
@ -168,7 +169,7 @@ extern "C" {
|
|||
*/
|
||||
#define DEVICE_DT_DEFINE(node_id, init_fn, pm_control_fn, \
|
||||
data_ptr, cfg_ptr, level, prio, api_ptr) \
|
||||
Z_DEVICE_DEFINE(node_id, node_id, \
|
||||
Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
|
||||
DT_PROP_OR(node_id, label, NULL), init_fn, \
|
||||
pm_control_fn, \
|
||||
data_ptr, cfg_ptr, level, prio, api_ptr)
|
||||
|
@ -202,7 +203,7 @@ extern "C" {
|
|||
* @return The expanded name of the device object created by
|
||||
* DEVICE_DT_DEFINE()
|
||||
*/
|
||||
#define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(node_id)
|
||||
#define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_NAME(node_id))
|
||||
|
||||
/**
|
||||
* @def DEVICE_DT_GET
|
||||
|
@ -688,10 +689,20 @@ static inline int device_pm_put_sync(const struct device *dev) { return -ENOTSUP
|
|||
* @}
|
||||
*/
|
||||
|
||||
/* Node paths can exceed the maximum size supported by device_get_binding() in user mode,
|
||||
* so synthesize a unique dev_name from the devicetree node.
|
||||
*
|
||||
* The ordinal used in this name can be mapped to the path by
|
||||
* examining zephyr/include/generated/device_extern.h header. If the
|
||||
* format of this conversion changes, gen_defines should be updated to
|
||||
* match it.
|
||||
*/
|
||||
#define Z_DEVICE_DT_DEV_NAME(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
|
||||
|
||||
#define Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, pm_control_fn, \
|
||||
data_ptr, cfg_ptr, level, prio, api_ptr) \
|
||||
Z_DEVICE_DEFINE_PM(dev_name) \
|
||||
COND_CODE_1(DT_NODE_EXISTS(dev_name), (), (static)) \
|
||||
COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
|
||||
const Z_DECL_ALIGN(struct device) \
|
||||
DEVICE_NAME_GET(dev_name) __used \
|
||||
__attribute__((__section__(".device_" #level STRINGIFY(prio)))) = { \
|
||||
|
@ -701,8 +712,10 @@ static inline int device_pm_put_sync(const struct device *dev) { return -ENOTSUP
|
|||
.data = (data_ptr), \
|
||||
Z_DEVICE_DEFINE_PM_INIT(dev_name, pm_control_fn) \
|
||||
}; \
|
||||
Z_INIT_ENTRY_DEFINE(_CONCAT(__device_, dev_name), init_fn, \
|
||||
(&_CONCAT(__device_, dev_name)), level, prio)
|
||||
BUILD_ASSERT(sizeof(Z_STRINGIFY(drv_name)) <= Z_DEVICE_MAX_NAME_LEN, \
|
||||
Z_STRINGIFY(DEVICE_GET_NAME(drv_name)) " too long"); \
|
||||
Z_INIT_ENTRY_DEFINE(DEVICE_NAME_GET(dev_name), init_fn, \
|
||||
(&DEVICE_NAME_GET(dev_name)), level, prio)
|
||||
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
#define Z_DEVICE_DEFINE_PM(dev_name) \
|
||||
|
|
|
@ -711,7 +711,8 @@ static inline bool net_eth_get_vlan_status(struct net_if *iface)
|
|||
*/
|
||||
#define ETH_NET_DEVICE_DT_DEFINE(node_id, init_fn, pm_control_fn, data, \
|
||||
cfg, prio, api, mtu) \
|
||||
Z_ETH_NET_DEVICE_INIT(node_id, node_id, DT_LABEL(node_id), \
|
||||
Z_ETH_NET_DEVICE_INIT(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
|
||||
DT_PROP_OR(node_id, label, NULL), \
|
||||
init_fn, pm_control_fn, data, cfg, prio, \
|
||||
api, mtu)
|
||||
|
||||
|
|
|
@ -2268,7 +2268,8 @@ struct net_if_api {
|
|||
*/
|
||||
#define NET_DEVICE_DT_DEFINE(node_id, init_fn, pm_control_fn, data, cfg, \
|
||||
prio, api, l2, l2_ctx_type, mtu) \
|
||||
Z_NET_DEVICE_INIT(node_id, node_id, DT_LABEL(node_id), init_fn, \
|
||||
Z_NET_DEVICE_INIT(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
|
||||
DT_PROP_OR(node_id, label, NULL), init_fn, \
|
||||
pm_control_fn, data, cfg, prio, api, l2, \
|
||||
l2_ctx_type, mtu)
|
||||
|
||||
|
|
|
@ -132,7 +132,8 @@ def write_device_extern_header(device_header_out, edt):
|
|||
print("", file=dev_header_file)
|
||||
|
||||
for node in sorted(edt.nodes, key=lambda node: node.dep_ordinal):
|
||||
print(f"extern const struct device DEVICE_DT_NAME_GET(DT_{node.z_path_id});", file=dev_header_file)
|
||||
print(f"extern const struct device DEVICE_DT_NAME_GET(DT_{node.z_path_id}); /* dts_ord_{node.dep_ordinal} */",
|
||||
file=dev_header_file)
|
||||
|
||||
print("", file=dev_header_file)
|
||||
print("#ifdef __cplusplus", file=dev_header_file)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue