I have rebooted my software development activities with the STM32F4-Discovery around a (for me) new concept: minimalist bare metal programming from scratch. The idea is to go through the development of an unlimited number of self-contained applications of increasing complexity, starting from scratch.
More on the concept can be found at bare.
See also my Git repo’s feed on this page.
I could post walk-throughs if there is some interest. Drop me a line in that case.
I have left my STM32F4-Discovery in its box for a long time while, among others, working on Nand2Tetris, but I have been missing it. I would now like to rebuild the while_one project from scratch and continue from there, with only the bare necessities:
the two latter simply being unpacked in my home directory, with the purpose of serving as code copy/paste sources, my idea being to include as little generic code as possible in my projects, in order to keep control over it. The tool chain from “GNU Tools” is of course also my tool chain.
I basically run the same procedure as described in Running ARM samples on the STM32F4-Discovery, except that I run GDB in Emacs (
M-gdb, command edited to
arm-none-eabi-gdb -i=mi). I also change the original ARM Makefile to compile with debugging symbols (see Stm32F4DiscoveryTest).
I can then step through the source code, both the startup assembly code and the C-code in Emacs by using
stepi in GDB.
Note: I finally keep the structure provided by the samples in GNU Tools for ARM Embedded Processors because it has a simple Makefile hierarchy, and seems to limit boilerplate code to a minimum. My intention is to build further from minimum.c, which basically is a “while one” program (it is actually a “for (;;);” program).
Here comes a short interruption from my Nand2Tetris studies. The interruption is actually strongly related to Nand2Tetris. I am at the point where I should write an assembler in a language of my choice. Given my personal experience and environment, my natural choice is C++ under Linux.
When it comes to the IDE choice, I have recently used Code::Blocks with success, except for one very irritating issue. I and apparently others (Google for it if you are interested) have experienced that when using Code::Blocks in XFCE (Manjaro’s standard desktop environment), copy/paste of code does not work well. This is a pretty basic function and while there is a workaround, it is painful and I finally got tired of it. Being nerdy as I am, I decided to gave a new go to GNU Emacs, my friend of old times. Since I wanted my experience to be as modern as possible – in the scope of Emacs – I watched through this and other videos, read quite many blog articles, and finally installed CEDET from their Bazaar repository, since the version bundled with my Emacs 24.3.1 is not complete.
I went through the beginning of the CEDET manual and was quite impressed by what I saw. But when I got into the EDE part (project management) I just found it too complicated for the kind of small project I am starting right now (a small assembler, remember?).
So I will still use Emacs + CEDET, but “managing source files” and building will be handled by a simple Makefile.
And if anybody is interested and doesn’t know, it is possible to a write Makefile that is generic for a C++ flat project (all cpp, hpp and Makefile in the same directory). And by generic I mean:
- Put any number of cpp and hpp files in the directory TheUltimateApplication.
- Put the generic Makefile in the same directory. Do not make a single change in the file (except of course, if you are using special libraries or flags, in which case, well, just add them).
./TheUltimateApplication. Watch the results on your screen.
- Of course, I also mean that the dependencies are handled correctly (as far as I know, I make no guarantee).
Here is the Makefile:
CUR_PATH_NAMES = $(subst /,$(SPACE),$(subst $(SPACE),_,$(CURDIR)))
EXE = $(word $(words $(CUR_PATH_NAMES)),$(CUR_PATH_NAMES))
EXE = a.out
DEP_FLAGS = -MD -MP
CPPFLAGS = $(DEP_FLAGS) $(DEBUG_FLAGS) -Wall -std=c++11
CXXFLAGS = -g -O3
SRC = $(wildcard *.cpp)
OBJS = $(SRC:%.cpp=%.o)
DEPS = $(SRC:%.cpp=%.d)
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)
rm -f *.o $(EXE) *~
@echo 'EXE:' $(EXE)
Note that there is even a target that will run your program:
make run. I use that to run the program from Emacs (
M-x compile RET make run RET).
Also note how this Makefile automagically learns about any new file in the project. Just put in it the directory, it will be in the project (i.e. automatically built and linked next time you run
make). That’s what I call effective source file management!