Commit f398be2a authored by Federico Vaga's avatar Federico Vaga

sw:tools: add project creator tool

This tool will help users to start the development of a new project
based on Mock Turtle. It creates a skeleton for development.
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 4bcff9d0
# Change Log
## [0.0.0] - {{date}}
This start the project {{name}} from the Mock Turtle template.
It includes basic files for hdl and software development
This is the README file for the {{name}} project.
\ No newline at end of file
GIT_VERSION = $(shell cd $(src); git describe --dirty --long --tags)
all: doxygen
doxygen:
GIT_VERSION=$(GIT_VERSION) EXCLUDE_FILES=$(EXCLUDE_FILES) BRIEF=$(BRIEF) \
doxygen ./doxygen-${short_name}-config
.PHONY: all doxygen
PROJECT_NAME = "${name}"
PROJECT_NUMBER = $(GIT_VERSION)
PROJECT_BRIEF =
PROJECT_LOGO =
OUTPUT_DIRECTORY = doxygen-${short_name}
CREATE_SUBDIRS = YES
TAB_SIZE = 8
OPTIMIZE_OUTPUT_FOR_C = YES
EXTRACT_STATIC = YES
CASE_SENSE_NAMES = YES
WARN_NO_PARAMDOC = YES
INPUT = ../lib
RECURSIVE = YES
EXCLUDE =
GENERATE_HTML = YES
GENERATE_LATEX = YES
-include Makefile.specific
# If needed add here images conversion
*.so
*.a
*.mod.c
*.o
*.ko
*.o.cmd
*~
\#*\#
*TAGS
Module.symvers
modules.order
Makefile.specific
*.S
*.bin
*.elf
*.gdb
GPATH
*.log
*.aux
-include Makefile.specific
DIRS := lib
DIRS += tools
DIRS += firmware
all clean modules install modules_install: $(DIRS)
clean: TARGET = clean
modules: TARGET = modules
install: TARGET = install
modules_install: TARGET = modules_install
$(DIRS):
$(MAKE) -C $@ $(TARGET)
.PHONY: all clean modules install modules_install
.PHONY: $(DIRS)
-include Makefile.specific
DIRS := fw-01
all clean modules install modules_install: $(DIRS)
clean: TARGET = $@
modules: TARGET = $@
install: TARGET = $@
modules_install: TARGET = $@
$(DIRS):
$(MAKE) -C $@ $(TARGET)
.PHONY: all clean modules install modules_install
.PHONY: $(DIRS)
/*
* Copyright (C)
* Author:
* License:
*/
#ifndef __FW_{{short_name_capital}}_COMMON_H__
#define __FW_{{short_name_capital}}_COMMON_H__
#include <mockturtle-rt-smem.h>
#include <{{short_name}}-common.h>
#endif
OBJS = fw-{{short_name}}.o
OBJS += # add other object files that you need
OUTPUT = fw-{{short_name}}
TRTL ?= ../../mockturtle
TRTL_SW = $(TRTL)/software
EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -I../common
EXTRA_CFLAGS += -DFPGA_APPLICATION_ID=----
EXTRA_CFLAGS += -DRT_APPLICATION_ID=----
MOCKTURTLE_PRINTF_ENABLE := 0
# Firmware Libray configuration
LIBMOCKTURTLE_ENABLE := 1
LIBMOCKTURTLE_VARIABLE_ENABLE := 0
LIBMOCKTURTLE_STRUCT_ENABLE := 0
LIBMOCKTURTLE_DEBUG_ENABLE := 0
LIBMOCKTURTLE_32BIT_ALIGN := 1
include $(TRTL_SW)/rt/Makefile
/*
* Copyright (C)
* Author:
* License:
*/
#include <string.h>
#include <libmockturtle-rt.h>
#include <fw-{{short_name}}-common.h>
enum rt_slot_name {
{{short_name_capital}}_CMD_IN = 0,
{{short_name_capital}}_CMD_OUT,
};
static struct rt_mq mq[] = {
[{{short_name_capital}}_CMD_IN] = {
.index = 0,
.flags = RT_MQ_FLAGS_LOCAL | RT_MQ_FLAGS_INPUT,
},
[{{short_name_capital}}_CMD_OUT] = {
.index = 0,
.flags = RT_MQ_FLAGS_LOCAL | RT_MQ_FLAGS_OUTPUT,
},
};
static struct rt_variable variables[] = {
/* put here variables that you want to share */
};
static struct rt_structure structures[] = {
/* put here data structures that you want to share */
};
static action_t *actions[] = {
[RT_ACTION_RECV_PING] = rt_recv_ping,
[RT_ACTION_RECV_VERSION] = rt_version_getter,
[RT_ACTION_RECV_FIELD_SET] = rt_variable_setter,
[RT_ACTION_RECV_FIELD_GET] = rt_variable_getter,
[RT_ACTION_RECV_STRUCT_SET] = rt_structure_setter,
[RT_ACTION_RECV_STRUCT_GET] = rt_structure_getter,
/* Add your actions here */
};
struct rt_application app = {
.name = "{{short_name}}",
.version = {
.fpga_id = FPGA_APPLICATION_ID,
.rt_id = RT_APPLICATION_ID,
.rt_version = RT_VERSION(0, 1),
.git_version = GIT_VERSION
},
.mq = mq,
.n_mq = ARRAY_SIZE(mq),
.structures = structures,
.n_structures = ARRAY_SIZE(structures),
.variables = variables,
.n_variables = ARRAY_SIZE(variables),
.actions = actions,
.n_actions = ARRAY_SIZE(actions),
};
/**
* Well, the main :)
*/
int main()
{
rt_init(&app);
while (1) {
/*
* Handle all messages incoming from slot
* {{short_name_capital}}_CMD_IN
* as actions
*/
rt_mq_action_dispatch({{short_name_capital}}_CMD_IN);
}
return 0;
}
/*
* Copyright (C)
* Author:
* License:
*
* Define the symbols which are shared between the user-space and
* the firmware application
*/
#ifndef __{{short_name_capital}}_COMMON_H
#define __{{short_name_capital}}_COMMON_H
#include <mockturtle-common.h>
#endif
# If it exists includes Makefile.specific. In this Makefile, you should put
# specific Makefile code that you want to run before this. For example,
# build a particular environment.
-include Makefile.specific
TRTL ?= ../mockturtle
TRTL_SW = $(TRTL)/software
LIB = lib{{short_name}}.a
LOBJ := lib{{short_name}}.o
CFLAGS += -Wall -ggdb -O2
CFLAGS += -I. -I../include
CFLAGS += -I$(TRTL_SW)/include -I$(TRTL_SW)/lib -I$(TRTL_SW)/kernel
CFLAGS += $(EXTRACFLAGS)
LDFLAGS += -L.
LDLIBS += -l{{short_name}}
modules all: $(LIB)
%: %.c $(LIB) $(LIBRT)
$(CC) $(CFLAGS) $(LDFLAGS) $*.c $(LDLIBS) -o $@
$(LIB): $(LOBJ)
ar r $@ $^
clean:
rm -f $(LIB) .depend *.o *~
.depend: Makefile $(wildcard *.c *.h)
$(CC) $(CFLAGS) -M $(LOBJ:.o=.c) -o $@
install modules_install:
-include .depend
/*
* Copyright (C)
* Author:
* License:
*
* Define here the internal API
*/
#ifndef __LIB{{short_name_capital}}_INTERNAL__H__
#define __LIB{{short_name_capital}}_INTERNAL__H__
#include <stdlib.h>
#include <lib{{short_name}}.h>
/**
* Description of a {{name}} device
*/
struct {{short_name}}_desc {
struct trtl_dev *trtl; /**< WRNC device associated */
uint32_t dev_id; /**< device id */
};
#endif
/*
* Copyright (C)
* Author:
* License:
*/
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <libmockturtle.h>
#include <lib{{short_name}}-internal.h>
/**
* List of error messages corresponding to the error codes.
*/
static const char *{{short_name}}_errors[] = {
};
/**
* It returns a string messages corresponding to a given error code. If
* it is not a libwrtd error code, it will run trtl_strerror()
* @param[in] err error code
* @return a message error
*/
const char *{{short_name}}_strerror(unsigned int err)
{
if (err < __E{{short_name_capital}}_MIN_ERROR_NUMBER ||
err >= __E{{short_name_capital}}_MAX_ERROR_NUMBER)
return trtl_strerror(err);
return {{short_name}}_errors[err - __E{{short_name_capital}}_MIN_ERROR_NUMBER];
}
/**
* It initializes the {{name}} library. It must be called before doing
* anything else.
* This library is based on the libmockturtle, so internally, this function also
* run trtl_init() in order to initialize the Mock Turtle library.
* @return 0 on success, otherwise -1 and errno is appropriately set
*/
int {{short_name}}_init()
{
int err;
err = trtl_init();
if (err)
return err;
return 0;
}
/**
* It releases the resources allocated by {{short_name}}_init(). It must be called when
* you stop to use this library. Then, you cannot use functions from this
* library.
*/
void {{short_name}}_exit()
{
trtl_exit();
}
/**
* Open a {{name}} node device using the Mock Turtle ID
* @param[in] device_id Mock Turtle device identificator
* @return It returns an anonymous {{short_name}}_node structure on success.
* On error, NULL is returned, and errno is set appropriately.
*/
struct {{short_name}}_node *{{short_name}}_open_by_id(uint32_t device_id)
{
struct {{short_name}}_desc *{{short_name}};
{{short_name}} = malloc(sizeof(struct {{short_name}}_desc));
if (!{{short_name}})
return NULL;
{{short_name}}->trtl = trtl_open_by_id(device_id);
if (!{{short_name}}->trtl)
goto out;
{{short_name}}->dev_id = device_id;
return (struct {{short_name}}_node *){{short_name}};
out:
free({{short_name}});
return NULL;
}
/**
* It closes a {{name}} device opened with one of the following function:
* {{short_name}}_open_by_id()
* @param[in] dev device token
*/
void {{short_name}}_close(struct {{short_name}}_node *dev)
{
struct {{short_name}}_desc *{{short_name}} = (struct {{short_name}}_desc *)dev;
trtl_close({{short_name}}->trtl);
free({{short_name}});
dev = NULL;
}
/**
* It returns the Mock Turtle token in order to allows users to run
* functions from the Mock Turtle library
* @param[in] dev device token
* @return the Mock Turtle token
*/
struct trtl_dev *{{short_name}}_get_trtl_dev(struct {{short_name}}_node *dev)
{
struct {{short_name}}_desc *{{short_name}} = (struct {{short_name}}_desc *)dev;
return (struct trtl_dev *)({{short_name}}->trtl);
}
/*
* Copyright (C)
* Author:
* License:
*
* Define in this file the public API
*/
#ifndef __LIB{{short_name_capital}}_H__
#define __LIB{{short_name_capital}}_H__
/** @file lib{{short_name}}.h */
#include <{{short_name}}-common.h>
struct {{short_name}}_node;
enum {{short_name}}_error_list {
__E{{short_name_capital}}_MIN_ERROR_NUMBER = 3200,
/*
* Add new messages here.
* The first one must be equal to __E{{short_name_capital}}_MIN_ERROR_NUMBER
*/
__E{{short_name_capital}}_MAX_ERROR_NUMBER,
};
/**
* @defgroup util Generic Functions
* Generic funcions to handle {{name}} devices
* @{
*/
extern const char *{{short_name}}_strerror(unsigned int error);
extern int {{short_name}}_init();
extern void {{short_name}}_exit();
extern struct {{short_name}}_node *{{short_name}}_open_by_id(uint32_t device_id);
extern void {{short_name}}_close(struct {{short_name}}_node *dev);
extern struct trtl_dev *{{short_name}}_get_trtl_dev(struct {{short_name}}_node *dev);
/**@}*/
#endif
# If it exists includes Makefile.specific. In this Makefile, you should put
# specific Makefile code that you want to run before this. For example,
# build a particular environment.
-include Makefile.specific
DESTDIR ?= /usr/local
TRTL ?= ../mockturtle/
TRTL_SW = $(TRTL)/software
CFLAGS += -Wall -ggdb
CFLAGS += -I. -I../include -I../lib
CFLAGS += -I$(TRTL_SW)/include -I$(TRTL_SW)/lib
CFLAGS += $(EXTRACFLAGS)
LDFLAGS += -L../lib -l{{short_name}} -L$(TRTL_SW)/lib
LDLIBS += -Wl,-Bstatic -lmockturtle
LDLIBS += -Wl,-Bdynamic
PROGS := # List of programs to compile
all: $(PROGS)
install:
install -d $(DESTDIR)/bin
install -D $(PROGS) $(DESTDIR)/bin
# TODO add rules to compile your programs
# make nothing for modules_install, but avoid errors
modules_install:
clean:
rm -f $(PROGS) *.o *~
.PHONY: all, clean
#!/usr/bin/python
"""
Federico Vaga <federico.vaga@cern.ch>
The trtl-project-creater can be used to create an empty project based
on the Mock Turtle architecture.
"""
import argparse
import datetime
import inspect
import jinja2
import os
import string
import shutil
import sys
cur_dir = os.path.dirname(os.path.abspath(inspect.getsourcefile(lambda: 0)))
mock_turtle_repo = "https://gitlab.cern.ch/coht/mockturtle.git"
def tpc_change_file_names(directory, table):
"""It fixes file names according to the project name
"""
os.rename(os.path.join(directory,
"software", "lib",
"libproject.c"),
os.path.join(directory,
"software", "lib",
"lib{short_name}.c".format(**table)))
os.rename(os.path.join(directory,
"software", "lib",
"libproject.h"),
os.path.join(directory,
"software", "lib",
"lib{short_name}.h".format(**table)))
os.rename(os.path.join(directory,
"software", "lib",
"libproject-internal.h"),
os.path.join(directory,
"software", "lib",
"lib{short_name}-internal.h".format(**table)))
os.rename(os.path.join(directory,
"software", "include",
"project-common.h"),
os.path.join(directory,
"software", "include",
"{short_name}-common.h".format(**table)))
os.rename(os.path.join(directory,
"software", "firmware", "fw-01",
"fw-project.c"),
os.path.join(directory,
"software", "firmware", "fw-01",
"fw-{short_name}.c".format(**table)))
os.rename(os.path.join(directory,
"software", "firmware", "common",
"fw-project-common.h"),
os.path.join(directory,
"software", "firmware", "common",
"fw-{short_name}-common.h".format(**table)))
os.rename(os.path.join(directory, "doc",
"doxygen-project-config"),
os.path.join(directory, "doc",
"doxygen-{short_name}-config".format(**table)))
def tpc_copy_structure(directory):
"""It creates all the missing directories in the target directory
"""
template_dir = os.path.join(cur_dir, "templates")
shutil.copytree(template_dir, directory)
def tpc_apply_value_to_template(directory, table):
"""It applys the values to the template files
"""
env = jinja2.Environment(loader=jinja2.FileSystemLoader(directory))
# Adjust content and create new file
for tmpl in ["CHANGELOG",
"README.md",
"LICENSE",
"software/Makefile",
"software/tools/Makefile",
"software/lib/Makefile",
"software/firmware/Makefile",
"software/firmware/fw-01/Makefile",
"doc/Makefile",
"doc/doxygen-project-config",
"doc/img/Makefile",
"software/lib/libproject.c",
"software/lib/libproject.h",
"software/lib/libproject-internal.h",
"software/include/project-common.h",
"software/firmware/fw-01/fw-project.c",
"software/firmware/common/fw-project-common.h",
]:
template = env.get_template(tmpl)
with open(os.path.join(directory, tmpl), "w") as f:
f.write(template.render(table))
def tpc_git_init(directory):
"""It creates a git repository for the project
"""
os.system('cd {dir}; git init'.format(dir=directory))
os.system('cd {dir}; git add README.md CHANGELOG LICENSE .gitignore'.format(dir=directory))
os.system('cd {dir}; git commit -m \"init repo\"'.format(dir=directory))
os.system('cd {dir}; git submodule add {repo}'.format(dir=directory,
repo=mock_turtle_repo))
os.system('cd {dir}; git commit -m \"Add mock turtle module\"'.format(dir=directory))
os.system('cd {dir}; git add .'.format(dir=directory))
os.system('cd {dir}; git commit -m \"Add development skeleton\"'.format(dir=directory))
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="""
This is Mock Turtle project creator. Based on a template, this
program creates a skeleton project which can be used to start
the development of a new Mock Turtle project.
""")
parser.add_argument('-d', '--dst', required=True,
help='Destination directory')
parser.add_argument('-l', '--long_name', required=True,
help='Project name')
parser.add_argument('-s', '--short_name', required=True,
help='Project short name')
parser.add_argument('-g', '--git', action='store_true', default=False,
help='Create a git repo for the project')
args = parser.parse_args()
if not os.path.exists(args.dst):
print("\"{}\" directory does not exists".format(directory))
sys.exit()
dst_dir = os.path.join(args.dst, args.long_name.replace(" ", "_"))
template_fix_table = {
"date": datetime.date.today(),
"name": args.long_name,
"short_name": args.short_name.replace(" ", "_"),
"short_name_capital": args.short_name.replace(" ", "_").upper(),
}
tpc_copy_structure(dst_dir)
tpc_apply_value_to_template(dst_dir, template_fix_table)
tpc_change_file_names(dst_dir, template_fix_table)
if args.git:
tpc_git_init(dst_dir)
print("An empty Mock Turtle project has been created at \"{}\"".format(dst_dir))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment