Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
8f04a01
scripts/dts/extract: reg.py: Flatten reg instead of props
erwango Nov 9, 2018
d41bf05
scripts/dts: provide edts sanity check scripts
erwango Oct 18, 2018
21fe1cf
scripts: codegen: add inline code generation
b0661 Feb 28, 2018
6ec24a9
doc: codegen: add inline code generation documentation
b0661 Mar 10, 2018
81dca4e
scripts: codegen: add generic module
b0661 Jun 1, 2018
bad906a
doc: codegen: add modules and templates doc
b0661 Jun 1, 2018
5fa50b4
cmake: extensions.cmake: Update codegen sequence
erwango Oct 25, 2018
3fab258
drivers/spi: stm32: use codegen driver instantiation
erwango Aug 1, 2018
362c376
drivers/i2c: stm32: use codegen driver instantiation
erwango Aug 1, 2018
2c16942
scripts/codegen: Remove CONFIG flag check from device generation
erwango Sep 4, 2018
d617e19
scripts/dts: edtsdatabase.py: provide alternate path for edtsdevice
erwango Oct 25, 2018
f3c94b6
scripts/codegen: devicedeclare: use EDTSDevice API to access EDTS
erwango Nov 8, 2018
55c15fb
drivers/i2c: stm32: Split v1 and v2 compatibles templates
erwango Nov 9, 2018
d876318
scripts/dts/codegen: devicedeclare: fix for parents and controllers
erwango Nov 12, 2018
4fb3dd8
scripts/dts: add initial cut at get_parent()
galak Nov 9, 2018
91e81be
scripts/dts: edtsdevice: Method to get controller EDTSDevice object
erwango Nov 12, 2018
64617de
drivers/sensors: lsm6dsl: Generate driver instantiation [DNM]
erwango Jul 4, 2018
043c929
boards: 96b_argonkey: Add LSM6DSL I2C sensor for codegen demo [DNM]
erwango Nov 20, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,13 @@ add_subdirectory(subsys)
add_subdirectory(drivers)
add_subdirectory(tests)

# Add all generated zephyr sources in the same context as the zephyr library
# is created. Assure all sub directories that might invoke code generation
# are processed before.
get_property(zephyr_generated_sources GLOBAL PROPERTY zephyr_generated_sources_property)
set_source_files_properties(${zephyr_generated_sources} PROPERTIES GENERATED 1)
target_sources(zephyr PRIVATE ${zephyr_generated_sources})

set(syscall_macros_h ${ZEPHYR_BINARY_DIR}/include/generated/syscall_macros.h)

add_custom_target(syscall_macros_h_target DEPENDS ${syscall_macros_h})
Expand Down
8 changes: 8 additions & 0 deletions boards/arm/96b_argonkey/96b_argonkey.dts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
compatible = "st,lsm6dsl-spi";
reg = <1>;
spi-max-frequency = <1000000>;
cs-gpios = <&gpioc 2 0>;
irq-gpios = <&gpiob 1 0>;
label = "LSM6DSL_SPI";
};
Expand All @@ -75,6 +76,13 @@
&i2c1 {
status = "ok";
clock-frequency = <I2C_BITRATE_FAST>;

/* ST Microelectronics LSM6DSL accel/gyro sensor */
lsm6dsl@1 {
compatible = "st,lsm6dsl";
reg = <1>;
label = "LSM6DSL_I2C";
};
};

&i2c2 {
Expand Down
192 changes: 192 additions & 0 deletions cmake/extensions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,191 @@ macro(get_property_and_add_prefix result target property prefix)
endforeach()
endmacro()

# 1.3 generate_inc_*

# These functions are useful if there is a need to generate a file
# that can be included into the application at build time. The file
# can also be compressed automatically when embedding it.
#
# See tests/application_development/gen_inc_file for an example of
# usage.
function(generate_inc_file
source_file # The source file to be converted to hex
generated_file # The generated file
)
add_custom_command(
OUTPUT ${generated_file}
COMMAND
${PYTHON_EXECUTABLE}
${ZEPHYR_BASE}/scripts/file2hex.py
${ARGN} # Extra arguments are passed to file2hex.py
--file ${source_file}
> ${generated_file} # Does pipe redirection work on Windows?
DEPENDS ${source_file}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endfunction()

function(generate_inc_file_for_gen_target
target # The cmake target that depends on the generated file
source_file # The source file to be converted to hex
generated_file # The generated file
gen_target # The generated file target we depend on
# Any additional arguments are passed on to file2hex.py
)
generate_inc_file(${source_file} ${generated_file} ${ARGN})

# Ensure 'generated_file' is generated before 'target' by creating a
# dependency between the two targets

add_dependencies(${target} ${gen_target})
endfunction()

function(get_unique_generated_target_name
generated_file # The generated file
generated_target_name # the unique name
)
string(RANDOM LENGTH 8 random_chars)
get_filename_component(basename ${generated_file} NAME)
string(REPLACE "." "_" basename ${basename})
string(REPLACE "@" "_" basename ${basename})
set(generated_target_name "gen_${basename}_${random_chars}" PARENT_SCOPE)
endfunction()

function(generate_inc_file_for_target
target # The cmake target that depends on the generated file
source_file # The source file to be converted to hex
generated_file # The generated file
# Any additional arguments are passed on to file2hex.py
)
# Ensure 'generated_file' is generated before 'target' by creating a
# 'custom_target' for it and setting up a dependency between the two
# targets
get_unique_generated_target_name(${generated_file} generated_target_name)
add_custom_target(${generated_target_name} DEPENDS ${generated_file})
generate_inc_file_for_gen_target(${target} ${source_file} ${generated_file}
${generated_target_name} ${ARGN})
endfunction()

function(target_sources_codegen
target # The cmake target that depends on the generated file
)
set(options)
set(oneValueArgs)
set(multiValueArgs CODEGEN_DEFINES DEPENDS)
cmake_parse_arguments(CODEGEN "${options}" "${oneValueArgs}"
"${multiValueArgs}" ${ARGN})
# prepend -D to all defines
string(REGEX REPLACE "([^;]+)" "-D;\\1"
CODEGEN_CODEGEN_DEFINES "${CODEGEN_CODEGEN_DEFINES}")
# Get all the files that make up codegen for dependency
file(GLOB CODEGEN_SOURCES
${ZEPHYR_BASE}/scripts/dts/edtsdevice.py
${ZEPHYR_BASE}/scripts/dts/edtsdatabase.py
${ZEPHYR_BASE}/scripts/codegen/modules/*.py
${ZEPHYR_BASE}/scripts/codegen/templates/drivers/*.py
${ZEPHYR_BASE}/scripts/codegen/*.py
${ZEPHYR_BASE}/scripts/gen_code.py)

message(STATUS "Will generate for target ${target}")
# Generated file must be generated to the current binary directory.
# Otherwise this would trigger CMake issue #14633:
# https://gitlab.kitware.com/cmake/cmake/issues/14633
foreach(arg ${CODEGEN_UNPARSED_ARGUMENTS})
get_filename_component(generated_file_name ${arg} NAME_WE)
if(IS_ABSOLUTE ${arg})
set(template_file ${arg})
set(generated_file ${CMAKE_CURRENT_BINARY_DIR}/${generated_file_name}_devices.c)
else()
set(template_file ${CMAKE_CURRENT_SOURCE_DIR}/${generated_file_name}_devices.c.in)
set(generated_file ${CMAKE_CURRENT_BINARY_DIR}/${generated_file_name}_devices.c)
endif()
get_filename_component(template_dir ${template_file} DIRECTORY)
get_filename_component(generated_dir ${generated_file} DIRECTORY)

if(IS_DIRECTORY ${template_file})
message(FATAL_ERROR "target_sources_codegen() was called on a directory")
endif()

# Generate file from template
message(STATUS " from '${template_file}'")
message(STATUS " to '${generated_file}'")
execute_process(
COMMAND
${PYTHON_EXECUTABLE}
${ZEPHYR_BASE}/scripts/gen_code.py
${CODEGEN_CODEGEN_DEFINES}
-D "PROJECT_NAME=${PROJECT_NAME}"
-D "PROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}"
-D "PROJECT_BINARY_DIR=${PROJECT_BINARY_DIR}"
-D "CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}"
-D "CMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}"
-D "CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}"
-D "CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}"
-D "CMAKE_CURRENT_LIST_DIR=${CMAKE_CURRENT_LIST_DIR}"
-D "CMAKE_FILES_DIRECTORY=${CMAKE_FILES_DIRECTORY}"
-D "CMAKE_PROJECT_NAME=${CMAKE_PROJECT_NAME}"
-D "CMAKE_SYSTEM=${CMAKE_SYSTEM}"
-D "CMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}"
-D "CMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION}"
-D "CMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}"
-D "CMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
-D "CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
-D "CMAKE_COMPILER_IS_GNUCC=${CMAKE_COMPILER_IS_GNUCC}"
-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_EDTS=${GENERATED_EDTS}"
--input "${template_file}"
--output "${generated_file}"
--log "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CodeGen.log"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
if("${target}" STREQUAL "zephyr")
# zephyr is special
get_unique_generated_target_name(${generated_file} generated_target_name)
add_custom_target(${generated_target_name} DEPENDS ${generated_file})
add_dependencies(zephyr ${generated_target_name})
# Remember all the files that are generated for zephyr.
# target_sources(zephyr PRIVATE ${zephyr_generated_sources})
# is executed in the top level CMakeFile.txt context.
get_property(zephyr_generated_sources GLOBAL PROPERTY zephyr_generated_sources_property)
list(APPEND zephyr_generated_sources ${generated_file})
set_property(GLOBAL PROPERTY zephyr_generated_sources_property "${zephyr_generated_sources}")
# Add template directory to include path to allow includes with
# relative path in generated file to work
zephyr_include_directories(${template_dir})
else()
zephyr_include_directories(${generated_dir})
target_sources(${target} PRIVATE ${arg})

# Add template directory to include path to allow includes with
# relative path in generated file to work
target_include_directories(${target} PRIVATE ${template_dir})
endif()
endforeach()
endfunction()

function(zephyr_sources_codegen)
target_sources_codegen(zephyr ${ARGN})
endfunction()

function(zephyr_sources_codegen_ifdef feature_toggle)
if(${${feature_toggle}})
zephyr_sources_codegen(${ARGN})
endif()
endfunction()

function(zephyr_library_sources_codegen)
target_sources_codegen(${ZEPHYR_CURRENT_LIBRARY} ${ARGN})
endfunction()

function(zephyr_library_sources_codegen_ifdef feature_toggle)
if(${${feature_toggle}})
zephyr_library_sources_codegen(${ARGN})
endif()
endfunction()

# 1.2 zephyr_library_*
#
# Zephyr libraries use CMake's library concept and a set of
Expand Down Expand Up @@ -357,6 +542,13 @@ macro(zephyr_library_named name)
# This is a macro because we need add_library() to be executed
# within the scope of the caller.
set(ZEPHYR_CURRENT_LIBRARY ${name})

if("${name}" STREQUAL "zephyr")
# We have to mark all the generated files "GENERATED" in this context
get_property(zephyr_generated_files GLOBAL PROPERTY zephyr_generated_files_property)
set_source_files_properties(${zephyr_generated_files} PROPERTIES GENERATED 1)
endif()

add_library(${name} STATIC "")

zephyr_append_cmake_library(${name})
Expand Down
24 changes: 23 additions & 1 deletion doc/contribute/contribute_guidelines.rst
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,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
*********************

Coding Style
************
============

Use these coding guidelines to ensure that your development complies with the
project's style and naming conventions.
Expand Down Expand Up @@ -363,6 +366,25 @@ it to contain:
set -e exec
exec git diff --cached | ${ZEPHYR_BASE}/scripts/checkpatch.pl -

Keep the code simple
====================

Keep the code as simple as possible.

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:

* Use code generation - by preprocessor, :ref:`codegen`, or other - only for
problems that cannot be solved in the source language.
* Limit code generation to declarative data. Avoid generating control logic
whenever possible.
* Use the preprocessor for code generation as the primary tool.
* Use :ref:`codegen` only if the preprocessor can not provide a simple solution.
* Use CMake only if :ref:`codegen` can not be used.

.. _Contribution workflow:

Contribution Workflow
Expand Down
29 changes: 29 additions & 0 deletions doc/subsystems/codegen/build.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
..
Copyright (c) 2018 Bobby Noelte
SPDX-License-Identifier: Apache-2.0

.. _codegen_build:

Code Generation in the Build Process
####################################

Code generation has to be invoked as part of the build process. Zephyr uses
`CMake <https://cmake.org/>`_ as the tool to manage building the project.

A file that contains inline code generation has to be added to the project
by one of the following commands in a :file:`CMakeList.txt` file.

.. function:: zephyr_sources_codegen(codegen_file.c [CODEGEN_DEFINES defines..] [DEPENDS target.. file..])

.. function:: zephyr_sources_codegen_ifdef(ifguard codegen_file.c [CODEGEN_DEFINES defines..] [DEPENDS target.. file..])

.. function:: zephyr_library_sources_codegen(codegen_file.c [CODEGEN_DEFINES defines..] [DEPENDS target.. file..])

.. function:: zephyr_library_sources_codegen_ifdef(ifguard codegen_file.c [CODEGEN_DEFINES defines..] [DEPENDS target.. file..])

The arguments given by the ``CODEGEN_DEFINES`` keyword have to be of the form
``define_name=define_value``. The arguments become globals in the python
snippets and can be accessed by ``define_name``.

Dependencies given by the ``DEPENDS`` key word are added to the dependencies
of the generated file.
Loading