Tutorial needed for GNU blackfin toolchain with Eclipse - gcc

Any body knows of a good tutorial on using the GNU blackfin toolchain with eclipse on Windows?
I'm trying to start with developing bare metal application on blackfin and I've installed the toolchain and eclipse C/C++ Juno but I'm unable to compile. Currently I'm getting the make: *** No rule to make target 'all' error but there are many other things I find myself lost at.
Many thanks in advance,
Hasan.
Edit: I've read a bit about the "make" programme, and decided to start a single-file test project to learn the command line toolchain (without the eclipse environment). Here is my main.c and associated makeFile:
//main.c
#include <stdio.h>
int main(void)
{
volatile int x = 42;
printf("%i\n", x);
return 0;
}
#makeFile
CPU = bf533-any
CROSS_COMPILE = bfin-elf-
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)gcc
CFLAGS = -c -Wall
bfin_test: main.o
$(LD) main.o -mcpu=$(CPU) -o $#
main.o: main.c
$(CC) $(CFLAGS) main.c -mcpu=$(CPU) -o $#
Here is the result of running the make command on the cmd console:
D:\work\experiments\bfin_test_project>dir
Volume in drive D is Data
Volume Serial Number is 248D-2C8D
Directory of D:\work\experiments\bfin_test_project
14/04/2013 12:30 <DIR> .
14/04/2013 12:30 <DIR> ..
11/04/2013 13:30 102 main.c
14/04/2013 12:29 257 makeFile
14/04/2013 12:29 264 makeFile~
3 File(s) 623 bytes
2 Dir(s) 634,582,650,880 bytes free
D:\work\experiments\bfin_test_project>make
bfin-elf-gcc -c -Wall main.c -mcpu=bf533-any -o main.o
bfin-elf-gcc main.o -mcpu=bf533-any -o bfin_test
c:/program files (x86)/analog devices/gnu toolchain/2012r2/elf/bin/../lib/gcc/bf
in-elf/4.3.5/../../../../bfin-elf/lib\libc.a(lib_a-closer.o): In function `close
_r':
/usr/src/packages/BUILD/blackfin-toolchain-2012R2/gcc-4.3/newlib/libc/reent/clos
er.c:53: warning: _close is not implemented and will always fail
c:/program files (x86)/analog devices/gnu toolchain/2012r2/elf/bin/../lib/gcc/bf
in-elf/4.3.5/../../../../bfin-elf/lib\libc.a(lib_a-fstatr.o): In function `fstat
_r':
/usr/src/packages/BUILD/blackfin-toolchain-2012R2/gcc-4.3/newlib/libc/reent/fsta
tr.c:62: warning: _fstat is not implemented and will always fail
c:/program files (x86)/analog devices/gnu toolchain/2012r2/elf/bin/../lib/gcc/bf
in-elf/4.3.5/../../../../bfin-elf/lib\libc.a(lib_a-isattyr.o): In function `isat
ty_r':
/usr/src/packages/BUILD/blackfin-toolchain-2012R2/gcc-4.3/newlib/libc/reent/isat
tyr.c:58: warning: _isatty is not implemented and will always fail
c:/program files (x86)/analog devices/gnu toolchain/2012r2/elf/bin/../lib/gcc/bf
in-elf/4.3.5/../../../../bfin-elf/lib\libc.a(lib_a-lseekr.o): In function `lseek
_r':
/usr/src/packages/BUILD/blackfin-toolchain-2012R2/gcc-4.3/newlib/libc/reent/lsee
kr.c:58: warning: _lseek is not implemented and will always fail
c:/program files (x86)/analog devices/gnu toolchain/2012r2/elf/bin/../lib/gcc/bf
in-elf/4.3.5/../../../../bfin-elf/lib\libc.a(lib_a-readr.o): In function `read_r
':
/usr/src/packages/BUILD/blackfin-toolchain-2012R2/gcc-4.3/newlib/libc/reent/read
r.c:58: warning: _read is not implemented and will always fail
c:/program files (x86)/analog devices/gnu toolchain/2012r2/elf/bin/../lib/gcc/bf
in-elf/4.3.5/../../../../bfin-elf/lib\libc.a(lib_a-writer.o): In function `write
_r':
/usr/src/packages/BUILD/blackfin-toolchain-2012R2/gcc-4.3/newlib/libc/reent/writ
er.c:58: warning: _write is not implemented and will always fail
This produced the .o and (supposedly) the elf file. And here is the result of trying to run the elf file using the toolchain simulator:
D:\work\experiments\bfin_test_project>bfin-elf-run bfin_test
program stopped with signal 11 (Segmentation fault).
According to http://docs.blackfin.uclinux.org/doku.php?id=toolchain:sim, this should be running the simulator in the virtual mode. (Not sure if I should be providing other files)
Also I'm not sure if the output file (bfin_test) is actually an elf file or if it can be run using the simulator (bfin-elf-run). But if so, I'm wondering why am I getting a segmentation fault of such a seemingly simple programme. Any idea anybody? Note that I get the same error when changing main to contain only "return 0;".
Could someone please tell me where I'm going wrong.
Thanks again,

Hasan,
Take a look at these links. They might offer some help.
https://docs.blackfin.uclinux.org/doku.php?id=toolchain:bare_metal:compile
https://docs.blackfin.uclinux.org/doku.php?id=toolchain:bare_metal:link
It is a real struggle getting the GNU toolchain flowing for Blackfin but once you do its works pretty well.
Jim

Related

gcov and gcovr: no .gcno files are generated after compiling

I am trying to get code coverage in my unit test project in windows system.
Description
After compiling with -fprofile-arcs -ftest-coverage, I found out the execution file is generated and works fine. However there's no any .gcno files in the folder. So I cannot output the coverage report properly by gcovr.
Software version
gcc 8.1.0/gcov 8.1.0/gcovr 5.1/python 3.10.2
Steps
Here's what I've done during the whole process. Please help me if there's something wrong.
There are only .c and .h files in one folder
Compile my project using gcc
gcc -Wall -Wno-unknown-pragmas -fcompare-debug-second -fprofile-arcs -ftest-coverage -DUTEST AllTests.c CuTest.c BZR2.c BZR2_test.c -o beta.exe
Then I got beta.exe in the folder.
After runing beta.exe, there's my test result(All tests are passed.) showing in the command line window. Besides there're .gcda files with the same filename as my .c files.
Then I run gcovr -r ., the result is showing below. I think the reson why gcovr can't show the coverage information is there's no any .gcno files generated after compiling my project. But I don't understand why and how to solve this.
------------------------------------------------------------------------------
GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File Lines Exec Cover Missing
------------------------------------------------------------------------------
------------------------------------------------------------------------------
TOTAL 0 0 --%
------------------------------------------------------------------------------
Thanks for your time!
Remove the -fcompare-debug-second option. It is used for debugging the compiler itself, and causes the compiler
to silence warnings, and omitting other options that would cause the compiler to produce output to files or to standard output as a side effect.
(see: https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/Developer-Options.html)
Creation of gcno files is such a side effect.
General tips:
Instead of -fprofile-arcs -test-coverage you can simply use the --coverage option.
When you compile multiple source files in one go, then GCC tries to figure out file names for intermediate files, and also automatically derives some name for secondary outputs like gcno files. This used to be somewhat unintuitive, at least until reasonable behaviour was implemented in GCC 11.
To compile all of the files individually, we would use the structure:
OPTIONS="-Wall -Wno-unknown-pragmas --coverage -DUTEST"
# compile the individual compilation units
gcc -c $OPTIONS AllTests.c -o AllTests.o
gcc -c $OPTIONS BZR2.c -o BZR2.o
gcc -c $OPTIONS BZR2_test.c -o BZR2_test.o
# we should now have three gcno files
ls *.gcno
# link the final executable
gcc $OPTIONS CuTest.o BZR2.o BZR2_test.o -o beta.exe
At this point, it's typically appropriate to use a build system, for example by writing a Makefile:
CFLAGS += -Wall -Wno-unknown-pragmas --coverage -DUTEST
SOURCES = AllTests.c BZR2.c BZR2_tests.c
OBJECTS = $(SOURCES:.c=.o)
beta.exe: $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $#

Creating shared library fails in Git Bash shell using Makefile

I am trying to create shared library i.e. .so from C++ code using Git Bash shell in Windows 10.
I use Makefile for compiling C++ code in Windows 10. Running make through Git bash shell.
Code compiles without any issue and creates object files without fail.
But it fails while creating .so file throwing following error. Following is part of Makefile in which target VLIB_SHARED_LIBRARY is causing this error.
VLIB_SO_DIR = .
VLIB_SHARED_LIBRARY = $(VLIB_SO_DIR)/libvxxx.so
CXX = g++
CXXFLAGS = -Wall -std=c++11 -O2 -D_7ZIP_ST -fPIC
LDFLAGS = -shared
OBJECT_FILES = a.o b.o c.o d.o .. z.o
all: init $(VLIB_SHARED_LIBRARY )
release: init $(VLIB_SHARED_LIBRARY )
$(VLIB_SHARED_LIBRARY): $(OBJECT_FILES) \n
$(CXX) $(LDFLAGS) -o $(VLIB_SHARED_LIBRARY) $(OBJECT_DIR)/*.o
process_begin: CreateProcess(C:\Program, C:/Program Files/Git/usr/bin/sh.exe -c "g++ -shared -o C:/XXXX_YYYY/bbbb/bin_linux/libyyyy.so C:/XXXX_YYYY/bbbb/bin_linux/obj/*.o", ...) failed.
make (e=193): Error 193
Same Makefile works fine in actual Linux Ubuntu OS but fails in Windows 10.
How to fix this error ?
The reason I suggested whitespace issues in my comment above is that the error message CLEARLY shows that it's a whitespace problem:
CreateProcess(C:\Program, C:/Program Files/Git/usr/bin/sh.exe ...
There is a space in this path to sh.exe, and the first argument printed here C:\Program quite clearly shows that the path has been truncated at the space.
I thought maybe your makefile was setting SHELL to some value but it doesn't appear to be. All I can suggest is either (a) remove C:\Program Files\Git\usr\bin from your %Path%, or (b) re-install Git into a path that doesn't contain whitespace so that you don't hit this problem.

How to crosscompile all sources from a directory using gcc-linaro (Windows 10)

I'm running into a problem trying to write a Makefile for cross compilation for a Beaglebone. I'm using gcc-linaro 7.5.0 on a Windows 10 machine.
The problem occurs when I try to put all sources from the directory into a variable for later use.
SRCDIR = $(CURDIR)\source
SRCS := $(wildcard $(SRCDIR)\*.cpp
This and this have previously been posted and this solution has been accepted, however, I cannot seem to get it to work. This line #echo $(SRCS) gives me ECHO is off which makes me assume that I'm doing something wrong because $(SRCS) seems to be empty, hence the message(?) (source folder exists and it is not empty)
Then when the linker is called I get a message possibly also indicating that the directory seems to be empty which it is not.
"D:\UserData\User\DEV\gcc-linaro-7.5.0-2019.12-i686-mingw32_arm-linux-gnueabihf\bin\arm-linux-gnueabihf-g++.exe" -o hellobone -marm -O0 -g -I. -ID:\UserData\User\DEV\hellobone\include
arm-linux-gnueabihf-g++.exe: fatal error: no input files
compilation terminated.
make: *** [hellobone] Fehler 1

Run two instances of the same C++ program simultaneously

I've got a C++ program with a Makefile, building (g++) and running on Windows cmd. Thing is, sometimes it takes a while to run and save the results, and I want to run it with different parameters at the same time so that I can do something else while I wait for the first instance to finish. It doesn't work though, because of the executable I guess:
>make
g++ -c -o main.o main.cpp
Assembler messages:
Fatal error: can't create main.o: Permission denied
make: *** [main.o] Error 1
You have two problems: The one you ask about, and the reason you ask this question in the first place.
Lets start with the problem you have...
Judging by the Makefile you show, you have it all wrong.
Rules are in the format
target: sources_the_target_depend_on
The target is usually a file that need to be created. For an object file that is the name of the actual object file itself. The source files that the object files then depend on should be on the right-hand side.
To take an example from you Makefile (before you edited it away):
graph2: graph2.o
g++ -g -c graph.cpp -o graph2.o
Here you tell make that the file graph2 depends on the file graph2.o, and then it creates the graph2.o file. That's wrong. The rule should be that the file graph2.o depends om the file graph.cpp and go on to generate the file graph2.o:
graph2.o: graph.cpp
g++ -g -c graph.cpp -o graph2.o
This indirectly leads to the problem you have, with this line (deduced from your error and the Makefile):
main: main.o utils.o graph.o heuristics.o
g++ -g main.cpp -o main.o utils.o graph.o heuristics.o
This contains the same error as discussed above: You say that the file main depends on main.o and then the rule create main.o. Your rule should be
main: main.cpp utils.o graph.o heuristics.o
g++ -g main.cpp -o main utils.o graph.o heuristics.o
Note also how I no longer name the executable file main.o, as that is supposed to be used for object files.
Now lets continue with the reason you have the problem in the first place: That you need to edit the code to change data or values.
This is a problem that you need to solve. One common way to solve it is through command line arguments. If your program parses the command line arguments passed to your program you can pass it the values that could change from run to run.
How to do this is whole chapter on its own, so I wont give you any more details. There are plenty of tutorials online.
Lastly, you can simplify your Makefile considerably, by using implicit rules and variables.
I would simply create the Makefile to look something like this
# The compiler to use
CXX = g++
# Flags to pass to the compiler (add warnings when building)
CXXFLAGS = -Wall
# The main executable file to generate
TARGET = main
# List the object files needed to generate the main executable file
OBJECTS = main.o utils.o graph.o heuristics.o
# The all target depends on your main executable file
# Also as the first target in the Makefile, if no specific target is specified
# this will be the one that is used (it's the "default" target for the Makefile)
all: $(TARGET)
# The main executable file depends on the object files
$(TARGET): $(OBJECTS)
This is really it. the object files will be built automatically from their respective source files, and then the executable program will be linked using the object files listed.

How to tell Make to search for header files

If I wanted to compile a simple AVR C program, I would simply go:
avr-gcc -mmcu=atmega2560 -Os avr.c -o avr.o
And the code would compile with no errors. However, as soon as I put the above command in a Makefile, I get a compilation error saying that DDRC, PC2, and PORTC are undeclared (see the error chunk at the bottom). Since these constants are defined in avr/io.h I tried to put an -I parameter to point to the header files, but had no success. Here is my Makefile:
CC=avr-gcc
INCLUDE=-I/usr/avr/include
CCFLAGS+=$(INCLUDE)
build: avr.o
$(CC) -mmcu=atmega2560 -Os avr.c -o avr.o
I found a similar problem here, but I was not lucky applying the solution. I believe the problem is in avr-gcc not being able to find the required libraries, and I thought -I directive would sort that out. But it seems that I am doing some silly mistake I cannot find. What would be the right way of telling a Makefile where header files are?
The error message that happens only when invoked make build:
avr.c: In function 'main':
avr.c:17:5: error: 'DDRC' undeclared (first use in this function)
DDRC |= 1<<PC2; /* PC2 will now be the output pin */
^~~~
avr.c:17:5: note: each undeclared identifier is reported only once for each function it appears in
avr.c:17:16: error: 'PC2' undeclared (first use in this function)
DDRC |= 1<<PC2; /* PC2 will now be the output pin */
^~~
avr.c:19:9: error: 'PORTC' undeclared (first use in this function)
PORTC &= ~(1<<PC2);/* PC2 LOW */
^~~~~
make: *** [<builtin>: avr.o] Error 1
*** Failure: Exit code 2 ***
avr.c I am trying to compile using make:
#define F_CPU 100000000
#include <avr/io.h>
#include <util/delay.h>
void sleep(uint8_t millisec)
{
while (millisec) {
_delay_ms(1);/* 1 ms delay */
millisec--;
}
}
int main()
{
DDRC |= 1<<PC2; /* PC2 will now be the output pin */
while (1) {
PORTC &= ~(1<<PC2);/* PC2 LOW */
sleep(100);/* 100 ms delay */
PORTC |=(1<<PC2); /* PC2 HIGH */
sleep(100);/* 100 ms delay */
}
return 0;
}
This line in your makefile is the cause of your problems:
build: avr.o
What does this mean? It tells make that in order to create a target named build, it should look for a target named avr.o, either already existing or, if it doesn't exist, then make should build it (if it can figure out how to do so).
So before make even tries to run the recipe for this rule, it will FIRST try to create a file avr.o.
Well, you haven't told it how to create such a file, but luckily (or unluckily for you) make has a set of built-in rules that it can use to create some types of files that it knows about. One of those built-in rules says that if make wants to build a file *.o (for some string matching *) and it can find a file *.c (where * is the same as in *.o), then it can create the *.o with this recipe:
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $# $<
How does this expand? Well, you've set CC to avr-cc so it will use that compiler. You haven't set CFLAGS, CXXFLAGS, or TARGET_ARCH so it will use the default value for those variables, which is nothing. So, it will run this compile line:
avr-cc -c -o avr.o avr.c
If you look up at the top of your list of error messages, make will print the compile line it runs and you'll see it's NOT the compile line you wanted it to run.
So, you have lots of ways to fix this problem.
One option is to keep your variables and fix your rule:
CC=avr-gcc
INCLUDE=-I/usr/avr/include
CCFLAGS+=$(INCLUDE)
build: avr.c
$(CC) $(CCFLAGS) -mmcu=atmega2560 -Os avr.c -o avr.o
Here, we list the build prerequisite as avr.c not avr.o, because that's what your recipe expects (it builds a .o from a .c, so the .c is the prerequisite). However, this is really a very bad makefile; it's a "useless use of make" because every time you type make it will rebuild the avr.o file.
A better way is to fix your makefile to use the standard predefined variable settings instead of your own variables, and let make build the object file with its built-in rules:
CC = avr-gcc
CPPFLAGS = -I/usr/avr/include
CFLAGS = -mmcu=atmega2560 -Os
build: avr.o
That's all you have to do (you say "build a simple AVR C program" but your makefile only compiles an object file, it doesn't invoke the linker, so I don't know exactly what you want to do).
If you really want to keep your own rules and not use the built-in rules, then at least write it correctly so that the files built by the recipe are the targets in the makefile rule:
CC=avr-gcc
INCLUDE=-I/usr/avr/include
CCFLAGS+=$(INCLUDE)
build: avr.o
avr.o: avr.c
$(CC) $(CCFLAGS) -mmcu=atmega2560 -Os avr.c -o avr.o

Resources