-
Notifications
You must be signed in to change notification settings - Fork 7k
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
Generated driver instantiation prototype #8561
Generated driver instantiation prototype #8561
Conversation
Codecov Report
@@ Coverage Diff @@
## topic-EDTS #8561 +/- ##
===========================================
Coverage 53.11% 53.11%
===========================================
Files 218 218
Lines 26871 26871
Branches 5952 5952
===========================================
Hits 14273 14273
Misses 10163 10163
Partials 2435 2435 Continue to review full report at Codecov.
|
33d5c20
to
106cce5
Compare
CONTRIBUTING.rst
Outdated
@@ -329,8 +329,11 @@ On Linux systems, you can install uncrustify with | |||
For Windows installation instructions see the `sourceforge listing for | |||
uncrustify <https://sourceforge.net/projects/uncrustify>`_. | |||
|
|||
Best coding practises |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
practices
CONTRIBUTING.rst
Outdated
|
||
Keep the code as simple as possible. | ||
|
||
Zephyr allows to generate code by tools. Keep this to a minimum and use the tool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about this:
Code-generation preprocessing tools provide a convenient way to
simplify some repetitive or parameterized coding tasks. While Zephyr
development allows use of such tools, we recommend keeping this
use to a minimum and when it provides an appropriate and simple
coding solution that follows these rules:
doc/subsystems/codegen/codegen.rst
Outdated
tailored and tuned to a specific project configuration. | ||
|
||
The Zephyr project supports a code generating tool that processes embedded | ||
Python "snippets" inlined in your source files. It can be used, for example, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should you mention Python2 or Python3 here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No not relevant here and Zephyr anyway is restricted to Python 3 only.
doc/subsystems/codegen/codegen.rst
Outdated
Python scripts. All Python snippets in a source file and all Python snippets of | ||
included template files are treated as a python script with a common set of | ||
global Python variables. Global data created in one snippet can be used in | ||
another snippet that is processed later on. This feature is e.g. used to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to:
This feature could be used, for example, to customize included template files.
doc/subsystems/codegen/codegen.rst
Outdated
An inlined Python snippet can always access the codegen module. The codegen | ||
module encapsulates and provides all the functions to retrieve information | ||
(options, device tree properties, CMake variables, config properties) and to | ||
put out the generated code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change put out
to output
doc/subsystems/codegen/codegen.rst
Outdated
|
||
.. function:: codegen.if_device_tree_controller_compatible(device_type_name, compatible) | ||
|
||
Stop code generation if there is no activated device that is compatible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "stop" mean here? Just that no output for that chunk is generated or the whole code generation processing stops?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whole code processing stops
doc/subsystems/codegen/codegen.rst
Outdated
The codegen.error function. | ||
|
||
Instead of raising standard python errors, codegen generators can use | ||
this function. It will display the error without a scary Python |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I'd avoid using "scary Python traceback", so just write this as:
Instead of raising standard Python errors, codegen generators can use
this function to write the error message to the log.
doc/subsystems/codegen/codegen.rst
Outdated
Logging | ||
------- | ||
|
||
.. function:: codegen.log(message [, message_type=None] [, end="\n"] [, logonly=True]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're missing descriptions and parameter descriptions for these functions.
Where does logging output get written?
doc/subsystems/codegen/codegen.rst
Outdated
Code generation in the build process | ||
************************************ | ||
|
||
Code generation has to be invoked as part of the build process. Zephyr uses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming then that the doc generating (doxygen) processing won't see the codegen output. I suspect this is OK but I'm curious how the API documentation will be affected
doc/subsystems/codegen/codegen.rst
Outdated
|
||
.. function:: codegen.prerr(s [, end="\n"]) | ||
|
||
Code generation in the build process |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reading all these codegen function definitions, it would be great to have some practical examples of their use included in the document to better show why we're provide this codegen capability.
scripts/codegen/cogapp/cogapp.py
Outdated
@@ -0,0 +1,781 @@ | |||
# coding: utf8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is present on PyPi: https://pypi.org/project/cogapp/. Do we really need to include it here or could we add it to requirements.txt
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cogapp.py is the orginal import from PyPi. It was not changed and is treated as an external source. Does not make sense to include it to requirements.txt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you mean @b0661? Why do you need to import it from PyPi and make a local copy of it? if you put cogapp
in requirements.txt
the module will be installed automatically when the user sets up the development environment and the Zephyr scripts will always have access to the latest version. I don't understand why we wouldn't do the same thing we do with all other Python modules we require, which is to install them via PyPi. Having local copies is always a maintenance burden.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The local copy of the sources of cogapp is reduced to the bare minimum. Major parts are already re-written, only very litlle is used anymore. The rest will be replaced over time. There is no extra burden as there is no benefit for codegen to follow cogapp. It is vice versa; it would be an extra burden to follow cogapp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, that was not what I understood originally when you said "cogapp.py is the original import from PyPi. It was not changed...". Fine then, if we want to avoid following upstream to do our own thing I'm OK with that.
@erwango one of the outstanding points that hasn't been listed yet is the obvious "should we mix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a lot of review comments that target codegen. Please make clear what part of the code is just used by your solution (such as codegen from #6762) and what are the additions/ changes you are doing.
I will try to solve all comments that are related to the original codegen sources in #6762 providing an updated version to be used here. Some of the comments are already solved in the current version of #6762, your copy is outdated - please rebase your code or cherry-pick from #6762. You should pick at least:
- scripts: prepare Zephyr inline code generation
- scripts: add Zephyr inline code generation
- doc: subsystems: add inline code generation documentation
Comments on the API:
device_data = ( ['spi_stm32_data',
{'string': ['SPI_CONTEXT_INIT_LOCK(st_stm32_spi_fifo_', 'index', '_data, ctx)']},
{'string': ['SPI_CONTEXT_INIT_SYNC(st_stm32_spi_fifo_', 'index', '_data, ctx)']}]
)
device_config = ( ['spi_stm32_config',
{'field': '.spi', 'value': '@reg/0', 'cast': '(SPI_TypeDef *)'},
{'field': '.pclken.bus', 'value': '@clock/bus'},
{'field': '.pclken.enr', 'value': '@clock/bits'},
{'string': ['.irq_config = st_stm32_spi_fifo_', 'index', '_config_irq'], 'flag': 'CONFIG_SPI_STM32_INTERRUPT'}]
)
You are specifying data strings in Python that a C programmer can easily specify in C syntax. Python provides a string template class that I used in my solution and that should be used instead. By this the programmer does not have to learn a new syntax. She has only to remember some macro names. The macros are replaced by the appropriate values for the driver instances.
See https://github.com/b0661/zephyr/blob/1e68884e8b1505cb236b5af595a91fc55712f337/drivers/spi/spi_stm32.c as an example:
/**
* @code{.codegen}
* ...
* device_data = ('struct spi_stm32_data',
* """
* SPI_CONTEXT_INIT_LOCK(${DEVICE_DATA}, ctx),
* SPI_CONTEXT_INIT_SYNC(${DEVICE_DATA}, ctx),
* """)
* device_config_info = ('struct spi_stm32_config',
* """
* .spi = (SPI_TypeDef *)$BASE_ADDRESS,
* .pclken.bus = $CLOCK_0_BUS,
* .pclken.enr = $CLOCK_0_BITS,
* #if CONFIG_SPI_STM32_INTERRUPT
* .config_irq = ${DEVICE_CONFIG_IRQ},
* #endif
* """)
* device_config_irq = (
* """
* #if CONFIG_SPI_STM32_INTERRUPT
* DEVICE_DECLARE(${DEVICE_NAME});
* static void ${DEVICE_CONFIG_IRQ}(struct device *dev)
* {
* IRQ_CONNECT(${IRQ_0}, ${IRQ_0_PRIORITY}, spi_stm32_isr, \\
* DEVICE_GET(${DEVICE_NAME}), 0);
* irq_enable(${IRQ_0});
* }
* #endif
* """)
* codegen.out_include('templates/drivers/simple_tmpl.c')
* @endcode{.codegen}
*/
/** @code{.codeins}@endcode */
/** @} device_driver_spi_stm32 */
"""
from .include import IncludeMixin | ||
from .log import LogMixin | ||
|
||
class CodeGenerator(OptionsMixin, GenericMixin, ConfigMixin, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doc/subsystems/codegen/codegen.rst
Outdated
tailored and tuned to a specific project configuration. | ||
|
||
The Zephyr project supports a code generating tool that processes embedded | ||
Python "snippets" inlined in your source files. It can be used, for example, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No not relevant here and Zephyr anyway is restricted to Python 3 only.
doc/subsystems/codegen/codegen.rst
Outdated
put out the generated code. | ||
|
||
Codegen transforms files in a very simple way: it finds chunks of Python code | ||
embedded in them, executes the Python code, and inserts its output back into |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, hello will be put in your code if you use codegen.out("hello"). Print is another story, it will usually go to stdout.
doc/subsystems/codegen/codegen.rst
Outdated
.. function:: codegen.error(msg) | ||
|
||
Raises an exception with msg as the text. No traceback is included, so | ||
that non-Python programmers using your code generators won’t be scared. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong anyway - will delete.
scripts/codegen/cogapp/cogapp.py
Outdated
@@ -0,0 +1,781 @@ | |||
# coding: utf8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cogapp.py is the orginal import from PyPi. It was not changed and is treated as an external source. Does not make sense to include it to requirements.txt.
@b0661 The issue with :
is that you are forcing devs to follow a certain way of naming their private data variable. And that you cannot do it. Up to code generation to provide enough flexibility to adapt to any kind of naming a dev would like to follow, not the other way round. Maybe there is another way, mixing both ideas in one: we could have a definition of the base name of the data variable, and the rest would be about the same as yours:
2nd parameter would be the one dictating the base name of the private data name. It's always a string so no need to precise the type, and it's just an array of string/@dts_generated_vars. @erwango what do you think? We of course would apply the same to device_config(). Personally I like the fact dev does not have to manager #ifdefs by himself and use the 'flag' introduced in this PR used as a condition to generate code. Thouhg I don't know of to merge it in above proposal. Another one is the macro names your are talking about: these are totally unrelated to DTS. $BASE_ADDRESS, $CLOCK_0_BITS, ... These are hard to relate to DTS db, and that's something we would like to avoid. Idea is that the relationship with DTS and code generation should be straight. It's not visible yet in this PR because it requires quite some work again, but things like @reg/0 will disappear to @base_address for instance (DTS db will provide nicer names/aliases). In clock area it's already quite nice because it reuses the flag names from the yaml file for instance. For the rest, we have to stick with device_declare(), fully hiding all the DEVICE_* macros, the irq config function stuff etc... We really want that to disappear. |
@erwango and you should really come up with the goals you wan´t to achieve. Simplicity and ease of use was the goal @erwango postulated. To be simple some restrictions must be there - otherwise you always can use pure inline python and not a template. By the way you copied it wrong. The parameter is about the data type and not the name of the data instantiation. "cannot do" - Yes, I can do. The dev provides the data type "struct whatever_dev_needs". The template decides on the name and provides the name as a macro parameter ${DEVICE_DATA}. Both get what they need in a simple and easy way. Your suggestion needs a lot more parameters that are not necessary. The template always replaces the macro parameters by the actual values of the specific driver instantiation - no need for any index.
Thats a matter of naming and not of the principle. In Python string templates you provide a mapping from macro names to values. You can use whatever macro name you like. So best you first decide on how you want to name the properties from the device tree. In my solution I already created an alias for ${BASE_ADDRESS} - you can use ${reg0} instead. You can for shure also add ${base_address} as another alias.
I don´t know why you are regarding driver developers to be so dumb to not know what to put here. Anyway if you wan´t to hide such things you really have to put more restrictions on that. In the end the driver developer has to learn the syntax to fill all the template parameters which in my view is in no way easier than to just use plain C with some macros. I think copy and paste from one driver to another will anyway happen - so no need to invent a new syntax for something that is already documented and available for C. Code generation should be restricted to the parts that can not easiliy be done in C (one of the coding rules).
Depends on what defines you are talking. Defines that are related to the device tree can be resolved by the template (e.g. 'CONFIG_SPI_0'). Defines that reflect application/user decisions (e.g. "SPI_USE_INT") have to be handled in the driver code anyway - there is no benefit to hide these defines only in the driver instantiation when you have to use them in the rest of the code. |
106cce5
to
72b4953
Compare
You are misunderstanding the point here. We want to hide how device instances are actually generated because that will change to address other issues (unrelated to code generation, sure). And you don't want to change that in every drivers (changing or removing DEVICE_* macros etc etc...). In any case: what's generic and found in every driver (as generated code that is) should just disappear from there and put in the device_declare (or else) directly. |
@b0661 @dbkinder, I've just rebased with the following changes:
I didn't had time to update the solution vs the new cogen version so integration is somewhat worst than previously even if still working. |
Provide the parameters the new device instantiation needs. Without that we are spinning wheels forever. |
One of the goal we'd like to achieve is to avoid hardcoded references to device tree property, solution should be flexible enough to get these as inputs of whatever API will be used. And parameters encoding should be close enough to device tree syntax to make its use instinctive. Then, I have one specific comment to recent #6762, that I will do in #6762 to avoid mixing topics (we discuss "what" here and "how" in #6762) |
cmake/dts.cmake
Outdated
@@ -108,6 +109,7 @@ if(CONFIG_HAS_DTS) | |||
${DTS_FIXUPS} | |||
--keyvalue ${GENERATED_DTS_BOARD_CONF} | |||
--include ${GENERATED_DTS_BOARD_H} | |||
--structs ${GENERATED_DTS_STRUCTS} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get rid of structs as a name. I know this has historical reasons but now it is about to generate a database and not of structs only. So what about GENERATED_DTS_BOARD. This is also the name of the generated file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok to remove structs, though I'd like we can identify this is a('the") database.
What about GENERATED_DTS_BOARD_EBD?
scripts/codegen/declare.py
Outdated
import pprint | ||
import json | ||
|
||
class DeclareMixin(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shall become a template. There might be several ways how to instantiate a driver in the future. The core of codegen should not be affected by this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cf, my comment here (#6762 (comment)).
I agree to find a solution to isolate these modules from core of codegen. Though, I don't think we should use templates for python code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now codegen modules are available. Please make this a module.
scripts/codegen/devicetree.py
Outdated
import pprint | ||
import json | ||
|
||
class DeviceTreeMixin(object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please reduce this class to the bare minimum to access the json file and get device tree properties. Move the rest to a template. Same reason as above to keep the core of codegen stable and provide the ability for different solutions by templates.
cmake/extensions.cmake
Outdated
-D "CMAKE_COMPILER_IS_GNUCXX=${CMAKE_COMPILER_IS_GNUCXX}" | ||
-D "GENERATED_DTS_BOARD_H=${GENERATED_DTS_BOARD_H}" | ||
-D "GENERATED_DTS_BOARD_CONF=${GENERATED_DTS_BOARD_CONF}" | ||
-D "GENERATED_DTS_STRUCTS=${GENERATED_DTS_STRUCTS}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GENERATE_DTS_BOARD
drivers/spi/spi_ll_stm32.c
Outdated
* @code{.codegen} | ||
* codegen.device_tree_set_compatible('st,stm32-spi') | ||
* | ||
* # static struct spi_stm32_data st_stm32_spi_<node_idx>_data = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not necessary to let the dev define the name of the data instantiation (here "st_stm32_spi_<node_idx>_data"). Data can and shall always be referenced by the device structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, comment is actually misleading here as this code will indeed be generated from compat + 'data'
drivers/spi/spi_ll_stm32.c
Outdated
* # }; | ||
* | ||
* device_data = ( ['spi_stm32_data', | ||
* {'string': ['SPI_CONTEXT_INIT_LOCK(st_stm32_spi_', 'index', '_data, ctx)']}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as @tbursztyka does not provide info on the planned new device instantiation I regard this interface as too complex and be easily replaced by a template string with macros.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as @tbursztyka does not provide info on the planned new device instantiation
Even in a new instantiation solution, devices will be provided by sepcific _data and _config structures, so see these structs as an immutable in the API. User should be able to provide his own custom structs with 'free text' and access to device tree edb.
I regard this interface as too complex and be easily replaced by a template string with macros.
'Too complex', I agree.
'Easily replaced', this is where the codegen solution provided is maybe not as easy to understand as you might think. I might be slow learner, but I'm having hard time to see how it should be used and (what I see as) abusive use of templates does not help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might be slow learner, but I'm having hard time to see how it should be used and (what I see as) abusive use of templates does not help.
My ideal world is a C code string with placeholders where a template script replaces the placeholders by the values from device tree, autoconf, ... for a device driver. The template script repeats that for all instantiations of a device driver.
Only thing to know for a dev are the placeholder names that relate to device tree, autoconf, ... and the C syntax to write the data definitions and the interrupt initialisation.
The ideal world has to be augmented by some control data to know about the CONFIG vairables of the device driver, the api struct, ...
Your aim is different; you wan´t something where the code generator is in control how the data definition and the interrupt initialisation will be coded. Only by this you can make it independent of the device initialisation principle. In my view this independence is not worth the effort and the additional complexity. The initialisation principle will not be changed very often. If it is changed you may even use sematic patching to apply the change.
You always have to state the device tree property you want to use. How the value for this property is found can be decided by a template. There is nothing hardcoded here. Using Python template strings the mapping between names and values is completely controlled by the snippet code. The value can e.g. be retrieved by device_tree_node_property(). The important thing is to define a scheme for the names of properties that can easily used by the devs. |
drivers/spi/spi_ll_stm32.c
Outdated
* codegen.if_device_tree_node_compatible('st,stm32-spi') | ||
* @endcode{.codegen} | ||
*/ | ||
/** @code{.codeins}@endcode */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned earlier, this is not ok.
See the original PR for the reasoning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
codegen.if_device_tree_node_compatible() stops code generation if there is no compatible device activated. This was regarded not acceptable as the file is generated but it does have no content. The solution was to make the decision what file to generate in CMakeList.txt using a config var.
This is a copy of old stuff that needs to be adpated by @erwango. See https://github.com/b0661/zephyr/blob/1e68884e8b1505cb236b5af595a91fc55712f337/drivers/spi/spi_stm32.c in #5799 for a version that does not use codegen.if_device_tree_node_compatible().
This PR has copied code from other PR's without addressing the review comments in the original PR's. How do we deal with that? Repeat ourselves? Add links to original PR? Block this PR on the original PR's? |
Replace device instances code by codegen solution. Since there are 2 compatibles for STM32 SPI, declare both compatibles in device_declare API. Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
Replace device instances code by codegen solution. Since there are 2 compatibles for STM32 i2c, specify 2 different compatibles are supported by the driver Change the isr name, with isr name as postfix (instead being in the middle of the function name) in order to make it easier to be generated. Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
To align with requirement about split of responsibility between Kconfig and device tree, don't condition instance code generation on matching CONFIG flag value. Codegen should generate the code configured in device tree. Kconfig is responible for its final compilation. This way codegen is independant from Kconfig and could be executed before it. Reported misconfiguration should not be possible if a 'compatible' check is done beforehand. Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
Depending on the caller, edtsdatabase should import EDTSDevice class from edtsdevice or dts.edtsdevice. Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
In codegen devicedeclare module, use EDTSDevice API to access EDTS data. To simplify things, 'device-name' derivates (device-data, device-config-info and device-config-irq) are reworked to use unique_id field. Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This change is only to demonstrate how we could declare common template for a driver compatible with 2 compatible variants. Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
13026b2
to
867bd1c
Compare
* | ||
* device_config_spi = ('lsm6dsl_config', | ||
* """ | ||
* .comm_master_dev_name = ${get_property('bus/master')}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need an EDTSDevice api to get bus/master name
* device_config_spi = ('lsm6dsl_config', | ||
* """ | ||
* .comm_master_dev_name = ${get_property('bus/master')}, | ||
* .irq_gpio_port = ${get_property('irq-gpios/0/controller')}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need an EDTSDevice api to get controller name
* .comm_master_dev_name = ${get_property('bus/master')}, | ||
* .irq_gpio_port = ${get_property('irq-gpios/0/controller')}, | ||
* .irq_gpio_pin = ${get_property('irq-gpios/0/pin')}, | ||
* .cs_gpio_port = ${get_property('cs-gpios-controller/0/controller')}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need an EDTSDevice api to get controller name
* | ||
* device_config_i2c = ('lsm6dsl_config', | ||
* """ | ||
* .comm_master_dev_name = ${get_property('bus/master')}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
867bd1c
to
fcde762
Compare
Update devicedecmare to work with parents and controllers. Since they now can be returned thanks to EDTSDevice methods returning EDTSDevice Object, remove the additional code to do this treatment inside devicedeclare. Add support for '.' inside pattern _DeviceCustomTemplate to enable treatment of such partens: get_controller('irq-gpios/0').get_property('label') Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
fcde762
to
f9e720c
Compare
-Add example of sensor device generation with get_parent and get_controller methods returning EDTSDevice object |
b4cc89f
to
2733355
Compare
2733355
to
6f6c34e
Compare
Needs error checking, and handling of different 'types' (interrupt, gpio, etc). Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Add get_controller that return controller EDTSDevice Object Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
Update driver to support code generation. Note that this driver change is not functional but done to provide example on how to demonstrate several possibilities of device_declare api: -access bus-master information (implicit in device tree, build thanks to yaml) -access irq/cs gpios and pin information -For a single driver specify 2 types of config struct and build them depending on the compatible present in the board Remove from build_all test to pass CI Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
Do Not Merge: Add LSM6DSL I2C sensor Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
6f6c34e
to
043c929
Compare
Goal
Aim of this work is to demonstrate a prototype of driver instantiation leveraging codegen library provided by @b0661.
Concept
Oustanding points
Database
Differentiation point compared to initial proposal (#6762 and #5799) is to introduce an intermediate generated json database result of device tree treatment along with yaml bindings. This database exposes a flatten list of device nodes enabled in device tree, grouped by compatible. Each device node contains device tree properties augmented thanks to yaml bindings.
This database aims at providing a unique source of information on the target and could be reused for other purposes than code generation, such as CI, Kconfig generation, ...
Database structure could be refined after acceptance of this prototype, specially to add specific node information for advanced post-treatment.
json format was chosen over pickle alternative due to the text format.
Device declaration API
A special effort has been made to provide and easy to use code generation interface.
A
device_declare
function is provided which should be filled by driver developer once. It will then be processed before compilation and generate code for all device nodes instances matching the driver compatible and not disabled. If no node matching compatible, driver is not compiled.device_declare
will drive the whole device instances code generation (generic to all/most drivers) withdevice_data
anddevice_config
will help writing dedicated_data
and_config
structs that can depend on each driver.Here is and example of
device_declare
usage applied to STM32 SPI driver.Generated code looks as follows (for instance 'SPI_1'):
device_data
anddevice_config
should be filled with help specific tags:Even if working fine with current example, this work could be further improved by:
EDIT:
Since there are 2 compatibles for STM32 spi, duplicate drivers files to have one file per compatible.
Only file matching compatible will be compiled.
For drivers offering quite small differences between 2 different 'compatible', this could be improved in a second step to enable the ability for a driver file to be compatible with 2 dts 'compatibles'
EDIT (06/29):
declare.py
intocodegen/modules
.declare_template.py
module and used indrivers/spi/spi_ll_stm32.c
EDIT (07/03):
EDIT (07/04):
EDIT (07/06)
EDIT (08/01)
Next steps
Based on current propotype reception, following points should be refined: