Previously, in this article (https://qiita.com/take-iwiw/items/46119bb7d41c6030d34f), I easily built a C / C ++ development environment for Raspberry Pi. At this time, all build and debug was done on Raspberry Pi.
This time, I will describe cross-compilation on Ubuntu and remote debugging method using gdbserver. Finally, you will be able to debug the Raspberry Pi by GUI operation from VS Code on the host PC. Debugging is now possible from both Ubuntu and Windows.
Although this article targets Raspberry Pi, I think it can also be applied to general embedded Linux cross-development.
Basically, you only have to do it once.
Terminal on Ubuntu
sudo apt-get update
sudo apt-get install build-essential libncurses-dev git git-core
mkdir ~/raspberry
cd ~/raspberry
git clone https://github.com/raspberrypi/tools
Try to build ~ / work / pi / sample01 / sample01.cpp as below.
sample01.cpp
#include <stdio.h>
int main()
{
printf("Hello World\n");
for (int i = 0; i < 10; i++)
printf("i = %d\n", i);
return 0;
}
Terminal on Ubuntu
mkdir ~/work/pi/sample01 && cd ~/work/pi/sample01
code sample01.cpp &
ARCH=arm ~/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-g++ sample01.cpp
# ARCH=arm ~/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ sample01.cpp
scp a.out [email protected]:.
You can execute the a.out transferred by the last scp command on the Raspberry Pi.
For 32-bit environment, raspberry / tools / arm-bcm2708 / gcc-linaro-arm-linux-gnueabihf-raspbian / bin
may be better.
I have referred to this article very much. (https://qiita.com/tetsu_koba/items/ebbac47e3fb43c86f412). Thank you very much.
Basically, you only have to do it once.
Terminal on Raspberry Pi
sudo apt-get install gdbserver
Terminal on Ubuntu
mkdir ~/temp && cd ~/temp
wget http://ftp.jaist.ac.jp/pub/GNU/gdb/gdb-8.0.1.tar.gz
tar xf gdb-8.0.1.tar.gz
cd gdb-8.0.1
mkdir build && cd build
sudo apt-get install libexpat1-dev expat
../configure --target=arm-buildroot-linux-gnueabi --with-expat
make -j4
sudo make install
Terminal on Raspberry Pi
gdbserver --multi :5555
Create the following file (~ / work / pi / sample01 / gdb_load) in the same place as the executable file you want to debug.
gdb autorun script
target extended-remote 192.168.1.89:5555
file ./a.out
remote put ./a.out /home/pi/a.out
set remote exec-file /home/pi/a.out
start
Execute the following command with the same path as gdb_load and a.out to start debugging. Debug information is output to the terminal on the Ubuntu side, and output such as printf is output to the terminal on the Raspberry Pi side.
Terminal on Ubuntu
arm-buildroot-linux-gnueabi-gdb -x gdb_load
#↓ is the prompt in gdb
>>> n
Basically, gdbserver started on the Raspberry Pi side can always be started. Therefore, no operation is required on the Raspberry Pi side.
In the gdb terminal on the Ubuntu side, do q
and run gdb again to restart.
Debugging with the gdb command is inefficient unless you are very familiar with it. Allows you to debug with GUI from Visual Studio Code. As with general application development, step execution and break pointer settings can be made from the GUI so that variables in the scope can be referenced automatically.
Open the ~ / work / pi / sample01 /
directory from VS Code and press F5 to try to debug. After that, you will be asked to create debug settings, so select C ++ (GDB / LLDB).
Since launch.json is opened, edit it as follows.
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/a.out", //★ Edit
"args": [],
"stopAtEntry": true, //★ Edit(as you like)
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "arm-buildroot-linux-gnueabi-gdb", //★ Addition
"setupCommands": [ //★ Addition
{"text": "target extended-remote 192.168.1.89:5555"},
{"text": "file a.out"},
{"text": "remote put a.out /home/pi/a.out"},
{"text": "set remote exec-file /home/pi/a.out"}
]
}
]
}
Press F5 again to start debugging. After that, when debugging the project in this directory, just press the F5 key. The output of printf etc. is output to the terminal on the Raspberry Pi side.
Generally, if the target is Linux, I think the development HOST environment is also Linux. However, for some reason you often want to edit or debug your code on a Windows PC. (For example, I think it's a common practice to build on a Linux build server, download the binary built on the developer's Windows PC, and write it to the target). In such an environment, I think it is troublesome to put Ubuntu only for debugging, so I will make it possible on Windows as well. Use MSYS2 for terminal operation.
Create a gdb binary for ARM with the following command.
Terminal on MSYS
mkdir ~/temp && cd ~/temp
wget http://ftp.jaist.ac.jp/pub/GNU/gdb/gdb-8.0.1.tar.gz
tar xf gdb-8.0.1.tar.gz
cd gdb-8.0.1
mkdir build && cd build
../configure --target=arm-buildroot-linux-gnueabi --with-expat
make -j4
make install
_ Note
The build was successful once, but after installing python (pacman -S python2
) and doing various things, I couldn't rebuild. .. .. _
It's basically exactly the same as I did on Ubuntu. Suppose you have the source code and pre-built ARM binaries in C: / Users / tak / Desktop / win_share / sample01 /
.
Edit launch.json as below.
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/a.out", //★ Edit
"args": [],
"stopAtEntry": true, //★ Edit(as you like)
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "C:/msys64/mingw64/bin/arm-buildroot-linux-gnueabi-gdb.exe", //★ Addition
"setupCommands": [ //★ Addition
{"text": "target extended-remote 192.168.1.89:5555"},
{"text": "file C:/Users/tak/Desktop/win_share/sample01/a.out"},
{"text": "remote put C:/Users/tak/Desktop/win_share/sample01/a.out /home/pi/a.out"},
{"text": "set remote exec-file /home/pi/a.out"}
]
}
]
}
Note that the ARM gdb you built yourself does not have a path on Windows, so you need to specify the full path. I also had to specify the full path of the binary file to load. I tried using $ {workspaceFolder}
to see if it could be omitted, but it didn't work.
You can debug as below by pressing F5 again.
Since my main PC is Windows, I only build with Raspberry Pi and debug with VS Code on Windows.
g++ -O0 -g3 sample01.cpp
--When exiting gdbserver, use the monitor exit
from the gdb prompt on the host side.
--When specifying the location of the shared library, set sysroot ./
--If the source configuration and path are different between the build environment and the gdb execution environment, set substitute-path from-path to-path
――Even if the environment is different, it worked well for the time being. If there is a relative path, it seems to be a little okay.