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

Regctl #16

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
172 changes: 172 additions & 0 deletions regctl/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# name of the executable
EXEC=regctl

# list the c source files
SRCS=regctl.c

# define the object files by using suffix replacement on the SRCS list
OBJS=$(SRCS:.c=.o)

# directories where include files are located
INCLUDE_DIRS=.

# put an "-I" in front of each include directory;
# this is the way GCC needs the include directories specified
INC_PARAMS=$(foreach d, $(INCLUDE_DIRS), -I$d)

# build directories
BUILDDIR=build
X86BUILDDIR=$(BUILDDIR)/x86
ARMBUILDDIR=$(BUILDDIR)/arm

# executable directories
EXECDIR=exec
X86EXECDIR=$(EXECDIR)/x86
ARMEXECDIR=$(EXECDIR)/arm

# GCC flags
# static : use static instead of dynamic linking
# -g : retain debugging/symbol info in executable
# -Wall : enable all compilation warnings
# -std : which c standard to use
# -O : optimization level; 0 is no optimization
# -I : include directories where headers are located
CFLAGS=-static -g -Wall -std=gnu99 -O0 $(INC_PARAMS)

# linker flags
# -g : retain debugging info
# -Wall : enable all compilation warnings
LDFLAGS=-g -Wall

# arm cross compiler
CC_ARM=$(CROSS_COMPILE)gcc

# x86 host compiler
CC_X86=gcc

# Rule syntax:
# target: prerequisites
# recipe
#
# The target is the thing that gets created, prerequisites need to be executed
# before the target can be run, and the recpie defines how to create or update
# the target. Unless declared as phony, targets are assumed to be a real filename.
# Declaring a target as phony indicates that the target name is not a file that
# will be created. If a normal target already exists (e.g. the file or directory
# exists), then the target won't be run if the target is up to date.

# phony target to create the build directories and both exectuables
.PHONY: all
all : dirs arm x86

# phony target to build for the ARM archiecture; first create build directories,
# then build the executable.
.PHONY: arm
ifdef CROSS_COMPILE
arm: armdirs $(ARMEXECDIR)/$(EXEC)
else
arm:
@echo "----------------------------------"
@echo "**not building arm target because CROSS_COMPILE isn't exported**"
@echo "----------------------------------"
endif

# phony target to build for x86; first create build directories, then build
# the executable
.PHONY: x86
x86: x86dirs $(X86EXECDIR)/$(EXEC)

# target to build the ARM executable. The ARM object files are prereqs.
# The recipe runs gcc with the linker flags to make the binary.
# $^ is the list of all the prereqs, and $@ is the target
$(ARMEXECDIR)/$(EXEC): $(ARMBUILDDIR)/$(OBJS)
$(CC_ARM) $(LDFLAGS) $^ -o $@

# target to build the ARM objects from the c files (which are preqreqs);
# the recipe runs gcc with the cflags and creates the objects files for each
# source file.
$(ARMBUILDDIR)/$(OBJS): $(SRCS)
@echo "----------------------------------"
@echo "building for arm..."
@echo "----------------------------------"
$(CC_ARM) $(CFLAGS) -c $^ -o $@

# target to build the x86 exectuable; same as the equivalent ARM target
$(X86EXECDIR)/$(EXEC): $(X86BUILDDIR)/$(OBJS)
$(CC_X86) $(LDFLAGS) $^ -o $@

# target to build the x86 object files; same as the equivalent ARM target
$(X86BUILDDIR)/$(OBJS): $(SRCS)
@echo "----------------------------------"
@echo "building for x86 host..."
@echo "----------------------------------"
$(CC_X86) $(CFLAGS) -c $^ -o $@


# phony target to make make build and executable directories if they don't
# already exist.
.PHONY: dirs
dirs: x86dirs armdirs

# only create the arm directories if teh CROSS_COMPILE environment variable is
# defined
ifdef CROSS_COMPILE
.PHONY: armdirs
armdirs: $(ARMBUILDDIR) $(ARMEXECDIR)
else
armdirs:
endif

# phony targer to create the x86 build directories
.PHONY: x86dirs
x86dirs: $(X86BUILDDIR) $(X86EXECDIR)

# target to create the x86 build directory
$(X86BUILDDIR):
@echo "----------------------------------"
@echo "creating x86 directories..."
@echo "----------------------------------"
mkdir -p $@

# target to create the ARM build directory
$(ARMBUILDDIR):
@echo "----------------------------------"
@echo "creating arm directories..."
@echo "----------------------------------"
mkdir -p $@

# target to create the x86 executable directory
$(X86EXECDIR):
mkdir -p $@

# target to create the ARM executable directory
$(ARMEXECDIR):
mkdir -p $@


# phony target to remove build files and executables
.PHONY: clean
clean:
@echo "----------------------------------"
@echo "removing build files..."
@echo "----------------------------------"
rm -rf $(BUILDDIR)
@echo "----------------------------------"
@echo "removing executable files..."
@echo "----------------------------------"
rm -rf $(EXECDIR)

# phony target that just lists all available targets
.PHONY: help
help:
@echo "----------------------------------"
@echo "available targets:"
@echo "----------------------------------"
@echo "all: build for arm and x86"
@echo "arm: build for arm"
@echo "x86: build for x86"
@echo "dirs: create all build directories"
@echo "x86dirs: create x86 build directories"
@echo "armdirs: create arm build directories"
@echo "clean: remove build and exectuable files"
@echo "help: show this help text"
53 changes: 53 additions & 0 deletions regctl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Register Control Program
`regctl` is a command line program that allows users to read/write registers by name, instead of by address like one would with `devmem`. This *userspace* program uses `mmap()` to access system memory, just like `devmem` does. This program is mostly useful as a slightly higher-level debugging/testing utility compared to using `devmem` (e.g. `busybox devmem` or `devmem2`).

One nice thing about this program is that it handles conversion from human-readable numbers, like 0.34, to their fixed-point representations.



## Usage
```
Usage: regctl [OPTION...] write register_name register_value
or: regctl [OPTION...] read register_name
regctl -- read and write fpga fabric registers by name

-l, --list-registers List available register names
-r, --readback Read back values after writing
-v, --verbose Produce verbose output
-?, --help Give this help list
--usage Give a short usage message
```

**Examples:**

`./regctl -v write left_gain 0.2`

`./regctl --readback --verbose write right_gain 0.732`

`./regctl -v read left_gain`

`./regctl -l`

## Customization
Define your registers and component address/span in `registers.h`. Here's an example of register definitions:
```c
static reg_t registers[] = {
{
.name = "left_gain",
.width = 32,
.fraction_width = 28,
.is_signed = true,
.offset = LEFT_GAIN_OFFSET
},
{
.name = "right_gain",
.width = 32,
.fraction_width = 28,
.is_signed = true,
.offset = RIGHT_GAIN_OFFSET
}
};
```

## Compiling regctl
Run the Makefile. The only prerequisite is that you're on a Linux machine and have exported `CROSS_COMPILE=arm-linux-gnueabihf-` to cross compile the executable for ARM. The Makefile will by default create executables for both x86 and ARM.
Loading