Skip to content
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

[RFC] Template prototype using jinja2 templating engine #10957

Conversation

evenl
Copy link
Collaborator

@evenl evenl commented Oct 31, 2018

Sorry for this, my bad, I had to create a new pull request:
This is an continuation of #10873

Goal

To propose the jinja2 template engine as an alternative to the COG
based solution proposed for code generation.

Rationale

The version of COG proposed to be used in Zephyr is a highly modified
version of the original COG implementation. Which means that we can
not leverage future improvements made to COG or contribute our own
modifications back to COG.

This commit evenl@d8c986c
shows what code can be removed by using a jinja instead of a COG base solution

The Jinja2 engine however can be used as a pip package dependency
without modifications.

COG is more or less straight forward python which means that a generator
must more or less be written for each case. Which means that even the
simplest things will need a lot of boiler code just to output something.

Example:

Data in is “dev_name”

Cog:

/**
 * @code{.codegen}
 *
 *     codegen.outl(“#ifndef {}_INCLUDE_H”.format(dev_name))
 *     codegen.outl(“#define {}_INCLUDE_H”.format(dev_name))
 *
 * @endcode{.codegen}
 */

Jinja2:

    #ifndef {{ dev_name }}_INCLUDE_H
    #define {{ dev_name }}_INCLUDE_H

TODO:

The Jinja2 implementation is on par with what is currently implemented using the COG
solution. But because the COG solution give the user the ability to directly write
python code directly in the template there may be a need to develop some custom filters/
helper functions for the jinja2 solution.

This code is based on this code https://github.com/galak/zephyr/tree/EDTS which is not
yet in master.

Other advantages:

    * Big active community
    * Standardized and documented (http://jinja.pocoo.org)
    * Has been in development for a long time with multiple stable releases
    * Extensive enough to be a one-stop-shop for all code generation in the Zephyr project

@evenl evenl added area: Devicetree RFC Request For Comments: want input from the community DNM This PR should not be merged (Do Not Merge) labels Oct 31, 2018
@codecov-io
Copy link

codecov-io commented Oct 31, 2018

Codecov Report

Merging #10957 into topic-EDTS will increase coverage by 0.01%.
The diff coverage is n/a.

Impacted file tree graph

@@              Coverage Diff               @@
##           topic-EDTS   #10957      +/-   ##
==============================================
+ Coverage        53.3%   53.32%   +0.01%     
==============================================
  Files             215      215              
  Lines           25908    25908              
  Branches         5711     5711              
==============================================
+ Hits            13810    13815       +5     
+ Misses           9777     9772       -5     
  Partials         2321     2321
Impacted Files Coverage Δ
subsys/logging/log_core.c 78.4% <0%> (+2.34%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8ab7823...d4c8c5b. Read the comment docs.

@galak galak changed the base branch from master to topic-EDTS October 31, 2018 09:15
erwango and others added 14 commits October 31, 2018 04:25
Add new 'type' field in dts yaml bindings. It is meant to
provide zephyr generic device type (i2c, spi, ...).
This information could be used for various operations that
require to have information on the generic type of a device
or a compatible (CI triage, board documentation, ...)

Signed-off-by: Erwan Gouriou <[email protected]>
Introduce python class for extended device tree database generation
and extraction.
Extended device tree database is a json formatted database.
It contains python like dict representation of device tree information
amended with zephyr yaml bindings.

Signed-off-by: Bobby Noelte <[email protected]>
Signed-off-by: Erwan Gouriou <[email protected]>
Create extended DTS database to be used by codegen and others.

Signed-off-by: Bobby Noelte <[email protected]>
Get compatible info available by EDTS.
This way the compatible info of all activated devices can be used in
drivers.

Signed-off-by: Erwan Gouriou <[email protected]>
Signed-off-by: Kumar Gala <[email protected]>
Added get_device_ids_by_compatible to EDTSConsumerMixin

Signed-off-by: Kumar Gala <[email protected]>
Extend reg directive handling to fill the EDTS datanbase.

Signed-off-by: Bobby Noelte <[email protected]>
Signed-off-by: Kumar Gala <[email protected]>
Extend interrupts directive handling to fill the EDTS database.

Signed-off-by: Bobby Noelte <[email protected]>
Signed-off-by: Kumar Gala <[email protected]>
Extend default directive handling to fill the EDTS database.

Signed-off-by: Bobby Noelte <[email protected]>
Added get_device_id_by_label to EDTSConsumerMixin

Signed-off-by: Kumar Gala <[email protected]>
Extend clocks directive handling to fill the EDTS database.

Signed-off-by: Bobby Noelte <[email protected]>
Extend directive handling to use heuristics to fill the EDTS database.

heuristics was called when treating 'compatible' property
on the assumption it is mandatory.
Actually some nodes (children) don't have 'compatible', so
move heuristics out or properties parsing and process them
just before node properties treatment.

Signed-off-by: Bobby Noelte <[email protected]>
Signed-off-by: Erwan Gouriou <[email protected]>
Extract gpio property for injection in EDTS.
Cleanup no more needed function from extract_dts_includes script

Signed-off-by: Erwan Gouriou <[email protected]>
Signed-off-by: Kumar Gala <[email protected]>
Added get_compatibles to EDTSConsumerMixin

Signed-off-by: Kumar Gala <[email protected]>
Add an 'aliases' dict within generated edts.json and
fill in alias information when required in device-struct.

Signed-off-by: Erwan Gouriou <[email protected]>
evenl and others added 5 commits November 5, 2018 09:14
* Can now set and get parameters instead of direcly
  populating a dictionary
* IRQ_CONNECT and irq_enable is now autogenerated
* Removed the need for setting CODEGEN_OUTPUT if only the
  last extention of the template filename should be removed

Signed-off-by: Even Falch-Larsen [email protected]
(cherry picked from commit 414e447)
Exposing EDTSDatabase and EDTSDevice API for templates
through the edts_api data object

Signed-off-by: Even Falch-Larsen [email protected]
Moved generation parameters into a dictonary in the main
template to removed the need for set/get_param macros

Signed-off-by: Even Falch-Larsen [email protected]
Removed the need for the metafile for injecting metadata,
everything is handled in one template now

Signed-off-by: Even Falch-Larsen [email protected]
Renamed the tool to JinjaGen to diversify it from codegen

Signed-off-by: Even Falch-Larsen [email protected]
@evenl evenl force-pushed the template_prototype_with_updated_edts branch from 18afe36 to d4c8c5b Compare November 5, 2018 08:15
Copy link
Member

@erwango erwango left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the changes, starting to looks nice.
2 remaining points

drivers/i2c/CMakeLists.txt Show resolved Hide resolved
drivers/spi/CMakeLists.txt Show resolved Hide resolved
'init_function' : 'i2c_stm32_init',
'config_struct_body' : config_struct_body} %}

{{ i2c_stm32.device(data, ['st,stm32-i2c-v1', 'st,stm32-i2c-v2'], params) }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question on particular multi compatible support.

As you could see this file is compatible with 2 STM32 I2C IP versions. Particularly, both versions use the same code for devices.
Then, what if they used slightly different code for devices V1 and devices V2.
For instance: V1 and V2 uses same data_struct_body but have different config_struct_body

How would you support that if I still want to have device instantiation all in once place? (Assumption is only one compatible would be used for a specific board, either V1 or V2, but for all types of boards, I want to use this same file.)
This is doable with codegen since we provide 'compatible' in API, so we only have to define data_struct_body, config_struct_body_v1 and config_struct_body_v2, then calling API twice:
-first with devicedeclare('compat_v1', 'config_struct_body_v1', 'data_struct_body'),
-then with devicedeclare('compat_v2', 'config_struct_body_v2', 'data_struct_body')

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is doable with codegen since we provide 'compatible' in API, so we only have to define data_struct_body,
config_struct_body_v1 and config_struct_body_v2, then calling API twice:
-first with devicedeclare('compat_v1', 'config_struct_body_v1', 'data_struct_body'),
-then with devicedeclare('compat_v2', 'config_struct_body_v2', 'data_struct_body')

That is not entirely true, there is a lot more parameters.

devicedeclare.device_declare( \
 *     ['st,stm32-exti', ],
 *     'CONFIG_KERNEL_INIT_PRIORITY_DEVICE',
 *     'PRE_KERNEL_1',
 *     None,
 *     'stm32_exti_init',
 *     None,
 *     device_data,
 *     None)

So what I did in my jinja2 solution is to move the parameters out of the function call and into an object, I know it's personal taste, but I think it is cleaner. But your use-case is totally supported, it's just a matter of creating another parameter object, that points to the other config_struct_body for the second device, and then do two calls as in the codegen solution.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not entirely true, there is a lot more parameters.

Indeed, my goal was not to oversimplify codegen solution. I should have used following syntax:
devicedeclare('compat_v1', 'config_struct_body_v1', 'data_struct_body', ....)

But your use-case is totally supported

Ok, great removing my NACK. But tbh I'd prefer to have things available (even as a prototype) rather than doable and will be done if RFC is approved (even if I do trust you).

Copy link
Collaborator

@superna9999 superna9999 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok for the i2c and spi stm32 drivers changes

@galak
Copy link
Collaborator

galak commented Nov 7, 2018

@evenl I updated the topic-EDTS branch, can you rebase on it.

@SebastianBoe
Copy link
Collaborator

@galak : IMHO, syncing the prototype with EDTS should not be done until the RFC is approved.

If the RFC is declined there is no value in syncing it with the latest EDTS changes. If the RFC is
accepted we can sync with EDTS in the PR.

Copy link
Contributor

@dbkinder dbkinder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for docs

@carlescufi carlescufi mentioned this pull request Nov 13, 2018
6 tasks
@evenl
Copy link
Collaborator Author

evenl commented Nov 26, 2018

I was wondering if there is any progress regarding this topic? I think all questions/change requests has been addressed.

@SebastianBoe
Copy link
Collaborator

@erwango : Hi, I see you are registered as a NACK. Can you re-asses your review?

@SebastianBoe
Copy link
Collaborator

Hi, @galak if you could approve this RFC we can consider the RFC to be approved. We will then remove the RFC tag and rebase it onto the topic-EDTS branch as a PR.

@SebastianBoe
Copy link
Collaborator

Hi, since there have been several approvals I am going to consider this RFC approved.

@evenl : You may now remove the RFC tag and begin preparing this so that it can be reviewed again as a PR and then merged.

@erwango
Copy link
Member

erwango commented Dec 18, 2018

@SebastianBoe

.. and then merged.

Is that decided we're using jinja2 instead of codegen or other ? Have I missed something?

@SebastianBoe
Copy link
Collaborator

Is that decided we're using jinja2 instead of codegen or other ? Have I missed something?

Yes, that is what this RFC is for and what you have approved.
The implementation is still up for review.

@erwango
Copy link
Member

erwango commented Dec 19, 2018

@SebastianBoe

Yes, that is what this RFC is for and what you have approved.

Is tit really ? @carlescufi are you aligned on this?
My understanding was not this one. I've approved because I considered this proposal was matching all my requirements. This was not about "yeah lets' go with jinja2". I have not seen any github API aims as selecting a proposal over a another one.
I think this is a decision that should be taken by another process (and I'm totally open to have that discussion by any other way).
Meanwhile, if this is the current understanding, let me reconsider my review.

I would have preferred we could have the following process:
Review both RFC equally to get the best and equivalent implementations of both RFC. Once both provide satisfactions regarding reviews, a public selection can happen, which should involve the most zephyr users.

Copy link
Member

@erwango erwango left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting to withdraw my approval, since approval equals "vote for" according to @SebastianBoe .

Copy link
Member

@erwango erwango left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to remove approval, or dismiss review..

@SebastianBoe
Copy link
Collaborator

SebastianBoe commented Dec 19, 2018

The RFC is no longer considered to be approved due to a misunderstanding.

Further review will be required ...

@carlescufi
Copy link
Member

Is it really ? @carlescufi are you aligned on this?

Unfortunately the final decision on what templating system to use has been deferred to after the LTS release in order to get everything ready for the upcoming release.
Let's wait until then in order to settle the discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Devicetree DNM This PR should not be merged (Do Not Merge) RFC Request For Comments: want input from the community
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants