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

andrewi/293 cangen refactor #315

Merged
merged 12 commits into from
Nov 12, 2024
2 changes: 1 addition & 1 deletion firmware/cmake/cangen.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cmake_language(GET_MESSAGE_LOG_LEVEL LOG_LEVEL)
# cangen is provided by racecar/scripts/cangen
add_custom_target(
generated_can
COMMAND "cangen" ${CMAKE_CURRENT_SOURCE_DIR} "--log-level=${LOG_LEVEL}"
COMMAND "cangen" ${CMAKE_CURRENT_SOURCE_DIR} "--cmake-log-level=${LOG_LEVEL}"
DEPENDS ${CAN_DEPENDENCIES}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT Generating CAN code from DBCs
Expand Down
61 changes: 19 additions & 42 deletions scripts/cangen/cangen/can_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import re
import shutil
import time
from typing import Dict, List, Tuple, Callable, Any
from typing import Dict, List, Tuple

import numpy as np
from cantools.database import Database, Message, Signal
Expand All @@ -22,13 +22,9 @@
EIGHT_BITS = 8
EIGHT_BYTES = 8
TOTAL_BITS = EIGHT_BITS * EIGHT_BYTES
MSG_REGISTRY_FILE_NAME = "_msg_registry.h"
CAN_MESSAGES_FILE_NAME = "_can_messages.h"

TEMPLATE_FILE_NAMES = ["can_messages.h.jinja2", "msg_registry.h.jinja2"]

PACKAGE_NAME = "cangen"


def _parse_dbc_files(dbc_file: str) -> Database:
logger.info(f"Parsing DBC files: {dbc_file}")
Expand Down Expand Up @@ -172,33 +168,12 @@ def _camel_to_snake(text):
return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower()


def _create_jninja_environment(
package_name: str, filters: dict[str, Callable[..., Any]]
):
env = Environment(
loader=PackageLoader(package_name), trim_blocks=True, lstrip_blocks=True
def _create_output_file_name(output_dir: str, bus_name: str, template_file_name: str) -> str:
return os.path.join(
output_dir, bus_name.lower() + "_" + template_file_name.removesuffix(".jninja2")
AndrewI26 marked this conversation as resolved.
Show resolved Hide resolved
)
for filter_name, filter_function in filters.items():
env.filters[filter_name] = filter_function

return env


def _create_output_file_name(output_dir: str, bus_name: str, template_file_name: str):
return os.path.join(output_dir, bus_name.lower() + "_" + template_file_name[:-7])


def _generate_jninja_template(template_file_name, output_path, context, env):
template = env.get_template(template_file_name)
rendered_code = template.render(**context)

output_file_name = output_path
with open(output_file_name, "w") as output_file:
output_file.write(rendered_code)
logger.info(f"Rendered code written to '{os.path.abspath(output_file_name)}'")


def _generate_code(bus: Bus, config: Config):
def _generate_code(bus: Bus, output_dir: str):
"""
Parses DBC files, extracts information, and generates code using Jinja2
templates.
Expand Down Expand Up @@ -227,20 +202,22 @@ def _generate_code(bus: Bus, config: Config):

logger.debug("Generating code for can messages and msg registry.")

env = _create_jninja_environment(
PACKAGE_NAME, {"camel_to_snake": _camel_to_snake, "decimal_to_hex": hex}
env = Environment(
loader=PackageLoader(__package__), trim_blocks=True, lstrip_blocks=True
)
env.filters["decimal_to_hex"] = hex
env.filters["camel_to_snake"] = _camel_to_snake

for template_file_name in TEMPLATE_FILE_NAMES:
_generate_jninja_template(
template_file_name,
_create_output_file_name(
config.output_dir, bus.bus_name, template_file_name
),
context,
env,
)
template = env.get_template(template_file_name)
rendered_code = template.render(**context)

output_file_name = _create_output_file_name(output_dir, bus.bus_name, template_file_name)
with open(output_file_name, "w") as output_file:
output_file.write(rendered_code)
logger.info(f"Rendered code written to '{os.path.abspath(output_file_name)}'")

logger.info("Code generation complete")
logger.info("Code generation complete")


def _prepare_output_directory(output_dir: str):
Expand All @@ -266,4 +243,4 @@ def generate_can_for_project(project_folder_name: str):
_prepare_output_directory(config.output_dir)

AndrewI26 marked this conversation as resolved.
Show resolved Hide resolved
for bus in config.busses:
_generate_code(bus, config)
_generate_code(bus, config.output_dir)
5 changes: 3 additions & 2 deletions scripts/cangen/cangen/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@
def parse():
parser = argparse.ArgumentParser(description="DBC to C code generator")
parser.add_argument("project", type=str, help="Name of the project")
parser.add_argument(
group = parser.add_mutually_exclusive_group()
group.add_argument(
"-v",
"--verbose",
dest="is_verbose",
action="store_true",
help="Enable verbose output",
)
parser.add_argument(
group.add_argument(
"--cmake-log-level",
AndrewI26 marked this conversation as resolved.
Show resolved Hide resolved
dest="level",
choices=["STATUS", "INFO", "VERBOSE", "DEBUG"],
Expand Down
Loading