-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The history of the multi API / MFD discussions 2022 July - Sep #50621
Comments
Proposed ideal solution 1Proposed solutionUsing the api_device structs model, placing the api / device type information in the bindings files, generating macros using gen_defines.py / edtlib.py. Supporting remarks
Requirements
Further argumentsThe api: key in the bindings files is nearly identical to the Linux device_type: property, we could even call it device_type, but it is not as clear as api:. So there is precedent for having that information in the devicetree bindings files. There is even a The update of DEVICE_DEFINEs can be done gradually, and only require changing the api_ptr argument, which allows for an easy transition to this model. The PM device subsystem is already remarked as being flawed and will be updated in the future in any case. For single API devices, the PM subsystem works as expected, it also works with multi API devices, but it is awkward. ExampleBindings file
Device driver single API
Device driver multi API
Application
|
It is used e.g. by STM32 timers (specific functions of the timer are represented as child nodes:
The main problem I see in Zephyr really is that we use DT node identifiers (node labels, paths, aliases, etc.) to obtain
They could also be seen as hardware blocks of the modem (some definitely are, like GPIO), but it's true that some cases may be at the edge. But as I said above, we don't use Devicetree as Linux does, and I think we need to be pragmatic in the end. Is it worth breaking the whole device model? Or is it better to allow for certain exceptions in the case of MFDs (allow for Zephyrisms)? I solved the GD32 RCU case this way: zephyr/dts/arm/gigadevice/gd32f4xx/gd32f4xx.dtsi Lines 39 to 55 in e348fe4
RCU is a HW block that has both reset and clock control registers. I could just describe the RCU in DT (as ST does on Linux with RCC, same/similar IP). But to my understanding, it's not inaccurate to add a couple of sub-nodes to represent the reset and clock control blocks.
I get the point, but I think we need to be careful on breaking the device model for what it seems to be an edge case that has, in my view, a viable solution with the existing model. |
FYI; there is a "Convert to discussion" action for issues. |
Ha, of course there is :) |
Intruduction
This issue will go through the entire MFD / multi API device model discussions starting in with the modem driver design issue. Please note that this is summarizing multiple PRs and issues with about 100 comments across them, some details will be left out.
The issue with modem driver design July 2022
Modems often contain multiple functions, which are not common between all modems. The BG96 contains a cellular modem, GNSS modem and GPIO controller. Each of these modules support multiple features. A simple graph of features is shown below:
This is the basis for the need for multiple APIs since the BG96 contains multiple functions, which may contain multiple APIs each.
This issue was brought up at the architecture meeting, and no solution to the problem was suggested at that time.
The MFD devicetree parent/child solution July 2022 #47655
This solution to the problem is simple, just add every function or feature which requires its own API, be it an actual device or just a device struct being used as a handle, to the devicetree. Then instanciate a single driver for the top parent node which instanciates device instances for all features (child devices).
The issue proposed design rules and some macros which would help to keep the design and implementations of MFDs consistent.
The summed up opposing opinions to this solution at the time was:
The last opposing opinion sparked the research into multiple APIs pr device node.
The runtime API lookup solution Aug 9 2022 #48817
This solution pulled out the API pointer from the struct device, and placed it in an iterable section based on API type along
with a pointer to the device struct it belongs to.
Device instantiation before:
Device instantiation after:
The iterable sections would contain arrays of the following:
and the API wrappers would be rewritten to look through the section containing all devices
which support the specific API, comparing the provided struct device with the one in the
iterable section, to invoke the correct API implementation for the device.
The opposing responses to this solution at the time:
The multi API device model solution take 1 Aug 2022 #48817
This solution creates a single device struct and names it according to its api type, moving away from the generic
DEVICE_DT_DEFINE(node_id, ..., api_ptr)
toDEVICE_DT_API_DEFINE(node_id, ..., api_type, api_ptr)
andDEVICE_DT_GET(node_id)
toDEVICE_DT_API_GET(node_id, api_type)
.This allows for multiple device instances
pr device node, since a device instance is accessed using both the node and the api_type.
Note this solution doesn't work well with the PM subsystem as all devices which belong to the same node share the the same PM sub context.
pm_action(i2c_dev, ...);
is equal to
pm_action(i3c_dev, ...);
All instantiated devices would also be placed in iterable section by api type with this solution.
There where no relevant opposing responses to this solution at the time, just some notes:
The multi API device model solution take 2 Aug 22 2022 #49374
This solution is identical to the first take, however, this was the full implementation of it. It is split into multiple smaller issues
which we will go through now.
Where to declare API support and generate macros take 1 Aug 2022 #49374
The first solution was to use create a new top-level key in the bindings files in dts/bindings named api:. The required macros for the multi API device model where then generated by edtlib.py.
This solution also identified that it was not necessary to place devices in iterable sections at compile time (presuming all devices where declared in the devicetree) since we could generate foreach macros instead, greatlyr reducing complexity and allowing for compile time checks for if a device supports a specific API, or if any device supports a specific API, which could be used to auto exclude shells and subsystems which only work if those devices exists, and selecting the appropriate API when there are multiple potential APIs supported for a device, fx sensors often support both I2C and SPI, the macros could be used in place of the bus: property.
The opposing responses to this solution at the time:
Where to declare API support and generate macros take 2 Aug 2022 #49374
The properties files where invented, YAML files that extend the properties which can be defined for a device using the device
compatible to link the properties in it with the devicetree nodes and bindings files.
The supporting responses to this solution
The opposing responses to this solution
At this point, the properties files are pulled out into their own PR.
Back to the multi API device model Sep 2022 #49374
The multi API device model using the properties files is discussed at this point. This section will look past the properties files, which have their own section later. As a response to this PR, the following solutions where presented / discussed:
The runtime API lookup solution with added flag for multi API devices
The solution treats single and multiple API devices differently, by using the api pointer inside the struct device if only one API
is supported, and using the API lookup if more than one API is supported for said device. This differs from the first runtime lookup solution as this would aim to remove the api ptr from the struct device, which means every device would be treated equally.
This solution solves
This solution requires
Issues with this solution
Using device_api structs instead of device struct clones
The seconds solution was to use the multi API device model proposed in the PR, but changing device instance struct to the following:
This would save ROM because only two extra pointers are added for each API (and one removed from inside the struct device), including the "primary" one, instead of the entire struct device.
This solution solves
This solution requires
Issues with this solution
Using the originally proposed MFD solution
The original solution was brought up again as a possible solution. Issues and requirements for solution will be repeated here.
This solution solves
This solution requires
Issues with this solution
Using the multi functional device model in the PR
This solution solves
This solution requires
Issues with this solution
Properties files PR Sep 2022 #50441
The supporting responses to the properties files on their own:
The opposing responses to the properties files on their own are:
The text was updated successfully, but these errors were encountered: