第 2 節

Linux

0瀏覽次數0訪問次數--跳出率--平均停留

Environment Introduction

This tutorial covers the environment setup:

  1. System: Fedora 42 KDE Edition Linux
  2. System kernel: Linux 6.15.6-200.fc42.x86_64
  3. Architecture: X86_64

Other Linux environments are also acceptable.

Setting up various environments

Setting up the C/C++ environment


# debian系
sudo apt-get install gcc g++ gdb cmake-gui make

# rhel系
sudo dnf install gcc g++ gdb cmake-gui make

Check whether the environment was installed successfully.

gcc -v
g++ -v
gdb -v
cmake --version

Next, test whether C/C++ can be compiled normally. Find a folder containing C++ code, then cd into it in the terminal.

Then create a .cpp file and edit it with vim.

vim hello.cpp

Copy the following code into this file.

#include <iostream> 
int main(int argc,char **argv) 
{ 
    std::cout << "你好,机电创新学会!" << std::endl; 
    return 0; 
}

Then compile

g++ -o hello hello.cpp
ls

Run

./hello

The environment is already set up.

Install CubeMX

Download link:

https://www.st.com.cn/zh/development-tools/stm32cubemx.html

It is recommended to download version 6.14.1 (do not download version 6.15.0, as this version has a bug, and it is unclear when it will be fixed).

Decompress it.

Open this software with root privileges SetupSTM32CubeMX-6.15.0.

sudo ./SetupSTM32CubeMX-6.15.0

In the newly popped-up window, just keep clicking Next until the installation finishes. When it looks like the image below, the installation is successful.

/usr/local/STMicroelectronics/STM32Cube/STM32CubeMX Enter this folder, then open a terminal and type

./STM32CubeMX

Click Help

Select Manage embedded software packages, and check the first and latest firmware for STM32F1, F4, and H7.

Click install.

Logged into the account.

Then wait for the download and installation to finish.

Just download it.

Next, you can configure a desktop shortcut for CubeMX application for quick access. For detailed instructions, refer to the Appimage section of the Vinci Robotics Team Linux Beginner Tutorial. You can use Ctrl+F to quickly locate that section.

The desktop shortcut is as follows:

[Desktop Entry]
Name=STM32CubeMX
Exec=/usr/local/STMicroelectronics/STM32Cube/STM32CubeMX/STM32CubeMX
Icon=/usr/local/STMicroelectronics/STM32Cube/STM32CubeMX/help/STM32CubeMX.png
Type=Application
Categories=Development;Electronics;Embedded;
Comment=STM32CubeMX configuration and code generation tool
Terminal=false

Just follow the tutorial, and you'll be able to achieve this effect.

Install VSCode

https://code.visualstudio.com/Download

If it's a Debian-based system, download the .deb; if it's an RHEL-based system, download the .rpm.

After downloading, open your browser, locate the folder containing this installation package, and open a terminal in that path.

Debian-based: Enter sudo apt install ./code then press the tab key to autocomplete the filename, then press Enter.

RHEL series: Enter sudo dnf install ./code and then press the tab key to autocomplete the filename, then press Enter.

For example, after completion:

sudo dnf install ./code-1.102.1-1752598767.el8.x86_64.rpm

Then open VSCode and enter the following command in the terminal:

code

Then install some plugins.

All of the following need to be installed.

Install the ARM GNU toolchain

Compiler Tool Comparison:

FeaturesARM GCC (GNU Toolchain)Keil AC5 (ARM Compiler 5)Keil AC6 (ARM Compiler 6)
Core identityOpen-source compiler based on GNU GPLARM's traditional proprietary compilerA modern compiler based on LLVM/Clang
Licensing ModelFree, open-sourceCommercial license (included in MDK)Commercial license (included in MDK)
Code Generation / OptimizationGood, continuous improvement.Excellent (especially in small code size)Excellent, striking the best balance between performance and size.
Standard CompatibilityStay up to date with the latest C/C++ standards (such as C17, C++17/20).Primarily supports C++98, which is relatively outdated.Supports modern C++ (C++11/14/17) with better compatibility.
Error/Warning MessagesRelatively clear and easy to understand.relatively obscureVery clear and friendly, similar to GCC/Clang.
Integration with Keil MDKRequires manual configuration or through CubeIDENative, seamless integrationNative, seamless integration—the recommended choice by ARM.
Linker scriptUse a custom linker script syntax (.ld file)Using ARM's own scatter loading file syntax (.sct)Using ARM's own scatter loading file syntax (.sct)
Assembly syntaxUsing GNU assembly syntax (.S file)Using ARM assembly syntax (.s)Using ARM assembly syntax (.s), but AC6 is stricter.
Ecosystem and FutureIts strong ecosystem makes it the top choice for many open-source projects (such as Zephyr, ESP-IDF) and IDEs (CubeIDE, VS Code).In maintenance mode, ARM will no longer add new features and is not recommended for new projects.It is the future and mainstay of ARM, with continuous updates and optimizations.

Install

It is recommended to use the official method for installation.

Method 1 (Official Method)

https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads

Enter the download directory and open the terminal.

In the terminal, enter the following command to copy the compiler's tar archive to the folder where you store your programs (you can choose this folder yourself; it's recommended to place it in the home partition, just make sure you don't delete it later).

The specific command is cp ./arm-gnu, then press tab to autocomplete, then a space, followed by the path to the folder you want to copy to.

For example, the following command:

cp ./arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi.tar.xz ~/UserFolder/Applications/

Then enter the copied folder:

cd ~/UserFolder/Applications/

In the terminal, type tar -xvf ./arm-gnu and press tab to autocomplete.

For example, after I filled it in:

 tar -xvf ./arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi.tar.xz

Then enter this unzipped folder.

cd ./arm-gnuFill in according to tab.

cd ./arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi/
cd ./bin

Check the folder path

pwd

Copy /home/tungchiahui/UserFolder/Applications/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi/bin

Then you need to configure the environment.

vim ~/.bashrc

At the end, enter the following command, replacing ~/UserFolder/Applications/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi/bin with the path you just copied. /home/用户名 can be replaced with ~.

export PATH=/home/tungchiahui/UserFolder/Applications/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi/bin:$PATH

Loading environment

source ~/.bashrc
Method 2 (System Repository Method)

This method is not recommended


# Debian系
sudo apt install arm-none-eabi-gcc

# Rhel系
sudo dnf install arm-none-eabi-gcc

test

Check the version.

arm-none-eabi-gcc -v

Install the libreadline library

We will use the JLinkExe command for flashing, which requires the libreadline library. Therefore, install the libreadline library by executing the following command:


# debian系
sudo apt-get install libreadline-dev

# rhel系
sudo dnf install readline-devel

https://www.segger.com/downloads/jlink/

It is a Debian-based system; download the 64-bit DEB.

Download the 64-bit RPM for RHEL-based systems.

(The 64-bit here refers to amd64 and X86_64. If you are using ARM64, please download the 64-bit version under Linux ARM below.)

Open the downloaded folder, and open the terminal.

Then sudo apt install ./JLink then tab to complete.

Then sudo dnf install ./JLink then tab to complete.

sudo dnf install ./JLink_Linux_V852_x86_64.rpm

Check if the installation was successful.

JLinkExe

We click No, and then enter Commander interactive mode. In this mode, we can execute various commands provided by J-Link Commander to connect, configure the debugger, download programs or files to the target device, and more. Interested students can explore this on their own.

Execute the "q" command to exit this mode.

Download and install Ozone

https://www.segger.com/products/development-tools/ozone-j-link-debugger/

It is a Debian-based system; download the 64-bit DEB.

Download the 64-bit RPM for RHEL-based systems.

(The 64-bit here refers to amd64 and X86_64. If you are using ARM64, please download the 64-bit version under Linux ARM below.)

Then sudo apt install ./Ozone then tab to complete.

Then sudo dnf install ./Ozone then tab to complete.

sudo dnf install ./Ozone_Linux_V338g_x86_64.rpm

test

Open the terminal and enter

ozone

Download SVD

https://www.st.com.cn/content/st\_com/zh.html

Search for the chip model, such as stm32f103c8t6.

CAD resources

Download SVD; click the area inside the red box to download it.

After decompression, you can obtain the SVD files for the F1 series.

Just download and extract the F4 and H7 versions as well, one after the other. (You can extract them into the same folder.)

Then open a terminal in the folder above.

Copy all of these folders into Ozone's Config/Peripherals/ directory. (You need to confirm in advance whether Ozone's configuration uses this path before copying.)

sudo cp ./*.svd /opt/SEGGER/Ozone_V338g/Config/Peripherals/

Project Creation and Testing

Create a project using CubeMX

Click the button to select a microcontroller.

Search for the corresponding chip, and double-click the chip option.

Perform some configuration. The following are all very basic things that you definitely already know before watching this video.

Open any IO for testing, such as the LED's GPIO.

FreeRTOS also needs to be configured.

These folders also need to be configured properly. Finally, select CMake for Toolchain and choose GCC for the compiler (it's normal not to have the compiler selection option in version 6.14.1 and earlier).

(However, CubeMX 6.15.0 has a bug — selecting the GCC compiler here doesn't actually work, and you'll need to manually select the compiler later. This bug may be fixed in a future release.)

Configure and compile the project.

Open a terminal in the project folder.

Then open vscode

code .

After entering VSCode, click on the CMakeLists.txt file in the directory.

Check around line 25 for the following line. If it's not there, you need to manually add these two lines. (Version 6.14.1 does not have this bug.)

tips1: This is the bug in CubeMX version 6.15.0 mentioned above. Because this version added support for the Clang compiler and also allows selecting the compiler in CubeMX, but this option was likely not implemented correctly by the engineers. No matter which compiler you select, it won't actually choose the one you picked, so you need to select it manually.

tips2: CubeMX 6.15.0 has a second bug. It states that the workspace root CMakeLists.txt will only be generated once and will not be overwritten in subsequent generations. However, it turns out that after modifying the configuration in CubeMX and regenerating the code, all other commands are preserved except for this one. It's unclear whether this will be fixed in a future version, or if the bug from tips1 will be addressed directly. So, after each reconfiguration of CubeMX, you need to add this line back in.


# Include toolchain file
include("cmake/gcc-arm-none-eabi.cmake")

Press Ctrl+` to open the built-in terminal.

Use the command below to create and enter the build folder.

mkdir build
cd build

Next, use the cmake command to generate the makefile.

cmake ..

Check whether ARM's C/C++ and assembly compilers have all been found (if not, please check if there are any mistakes in the tutorial above).

Then use the make command to compile, with the command being make or make -jxx. Here, xx is the number of CPU threads you want to use for compilation. For example, if my computer has 8 cores and 16 threads, I can set xx to a number lower than 16. Meanwhile, make uses one thread by default. If you don't know how many threads your CPU has, just stick with the make command and don't use the make -jxx command.

make -j16

That means the compilation was successful.

Configure code hints.

In VSCode, press Ctrl+Shift+P, search for clangd, and select to download the language server.

Select Install in the bottom right corner, and once the installation is complete, a prompt like the one shown below will appear.

Next, disable the code suggestion feature of the C/C++ plugin (if you don't see this interface, scroll down).

If the pop-up shown above does not appear, you can manually close it. Again, press Ctrl+Shift+P, type "settings", and then find the option shown in the image below.

Find the option shown in the image below and change it to disabled.

"C_Cpp.intelliSenseEngine": "disabled"

In VSCode, press Ctrl+Shift+P again, search for clangd, and select Restart clangd language server (you must have compiled the code at least once before restarting the clangd language server).

At this point, you can see that the header files in the code are recognized correctly, and the code suggestions are working properly.

⚠️ Note: Clangd by default looks for the host system's libc/include path (e.g., x86_64's /usr/include) , but our project actually uses the ARM toolchain's header file path , which can cause errors when including C/C++ standard library headers.

For example:

The #include <math.h> here shows that the header file cannot be found, but when we compile it, there is no error, which means the clangd configuration is incorrect. The following describes a solution:

  1. Run the following command to get the standard include paths used by ARM GCC:
arm-none-eabi-gcc -x c -E -v - </dev/null

  1. Create a .clangd file in the project root directory and include your header file path (replace the content inside the quotes with your own ARM GCC header file path).
CompileFlags:
  Add: [
    "-isystem", "/home/xiaofang/Applications/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi/lib/gcc/arm-none-eabi/14.3.1/include",
    "-isystem", "/home/xiaofang/Applications/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi/lib/gcc/arm-none-eabi/14.3.1/include-fixed",
    "-isystem", "/home/xiaofang/Applications/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi/arm-none-eabi/include"
  ]

Save, then refresh clangd. The header file prompt now works normally.

Porting the Vinci Robot Team's standard C/C++ project template

Use the git clone command to clone the repository: https://github.com/tungchiahui/CubeMX_MDK5to6_Template

git clone https://github.com/tungchiahui/CubeMX_MDK5to6_Template.git

Copy all contents from the "工程文件移植" folder in the repository into our CMake project directory.

Then open the applications folder, and create led_task.cpp and led_task.h in the Src and Inc folders respectively, with the following contents:

led_task.cpp:

#include "led_task.h"
#include "cmsis_os.h"
#include "stm32f1xx_hal.h" 

GPIO_PinState pinstate = GPIO_PIN_RESET;

extern "C"
void StartDefaultTask(void *argument)
{
  for(;;)
  {
    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,pinstate);
    pinstate = (pinstate == GPIO_PIN_RESET) ? GPIO_PIN_SET : GPIO_PIN_RESET;
    osDelay(500);
  }
}

led_task.h:

#ifndef __LED_TASK_H_
#define __LED_TASK_H_

#ifdef __cplusplus
extern "C"
{
#endif

#include "cpp_interface.h"

#ifdef __cplusplus
}
#endif

#endif

Then open CMakeLists.txt in the cmake/user folder and add the newly created led_task.cpp file.

Detailed introduction (optional reading): The cmake/stm32cubemx under CMakeLists.txt here is managed by CubeMX. Once you regenerate the code with CubeMX, the contents of this file will be overwritten. However, the CMakeLists.txt at the workspace root will not be overwritten, and it provides some areas for us to add source and header files. But this can make the file too cluttered. So we chose to create a new user folder, set up a CMakeLists.txt inside it, and then use the top-level CMakeLists.txt to load this sub-CMakeLists.txt. This sub-CMakeLists.txt makes it easier for us to modify, and the file structure is clearer. (We don't need to create these ourselves—I've already created them in the Project File Migration section, and you've already copied them over when you copied the files above.)

Then, go to the top-level CMakeLists.txt and add this line to reference our own CMakeLists.txt.


# Add USER generated sources
add_subdirectory(cmake/user)

Great success, let's try compiling once. As shown in the image below, all the newly added files have been compiled.

cmake ..
make

Then go to main.c, include the cpp_interface.h header file, and call the cpp_main() function at this location within the main function. (I have RTOS enabled here, so the cpp_main function needs to be called before starting RTOS. If you are using a bare-metal program without RTOS, just call cpp_main above the while (1) loop.)

Then modify the isRTOS macro in cpp_interface.h to let the program know whether you have enabled RTOS. If enabled, set the macro to 1; if running on bare metal, set it to 0.

For more detailed information about STM32 C/C++ project engineering, please refer to the Vinci Robotics Team Microcontroller Tutorial.

Now compile the program in the build folder and find success!

cmake ..
make

Download the program to the board

Configure CMake to generate .bin and .hex files

Before downloading the program to the board, we need to check what files were actually generated from our previous compilation.

From the image below, it can be seen that it only generated a .elf file, not the common .bin and .hex files we typically see.

We need to modify the CMakeLists.txt in the workspace again so that .hex and .bin files are generated during compilation (unfortunately, it has to be this tedious — I don't know why CubeMX doesn't handle it all).


# 生成 .bin 和 .hex 文件
find_program(OBJCOPY arm-none-eabi-objcopy REQUIRED)

add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD
    COMMAND ${OBJCOPY} -O binary ${CMAKE_PROJECT_NAME}.elf ${CMAKE_PROJECT_NAME}.bin
    COMMAND ${OBJCOPY} -O ihex   ${CMAKE_PROJECT_NAME}.elf ${CMAKE_PROJECT_NAME}.hex
    COMMENT "Generating ${CMAKE_PROJECT_NAME}.bin and ${CMAKE_PROJECT_NAME}.hex from ${CMAKE_PROJECT_NAME}.elf"
)

I've written all the commands that need to be added to the workspace's main CMakeLists.txt in this notepad. Just copy them directly each time you generate a new project.

Then compile again.

cmake ..
make

Now look at the build directory: the .hex or .bin files we need are ready.

Graphical interface flashing
#打开终端输入
JFlashLite

Select the corresponding chip model and speed.

Add hex file

Click to burn and complete:

Successfully lit the LED.

Terminal Flashing

Forget it, forget it, it's too much trouble.

Configure VSCode tasks

When we compile above, we always need to enter the following command

cd build
cmake ..
make

This makes compiling too cumbersome each time, so we use the powerful VSCode for one-click compilation.

First, create the .vscode folder and the tasks.json file.

Here is the content of tasks.json:

{
    "version": "2.0.0",
    "options": {
        "cwd": "${workspaceFolder}/build"    //需要进入到我们执行tasks任务的文件夹中
    },
    "tasks": [    //tasks包含4个任务
        {
            "type": "shell",
            "label": "stm32-cmake",    //第一个任务的名字叫cmake
            "command": "bash",
            "args": [
                "-c",
                "mkdir -p ../log && echo \"===== CMake started at: $(date) =====\" | tee -a ../log/cmake.log && cmake .. 2>&1 | tee -a ../log/cmake.log"
            ],
            "problemMatcher": []    //这里需要添加一个空的问题匹配器,否则会报错
        },
        {
            "label": "stm32-make",    //第二个任务的名字叫make
            "command": "bash",
            "args": [
                "-c",
                "mkdir -p ../log && echo \"===== Make started at: $(date) =====\" | tee -a ../log/make.log && make -j$(grep -c ^processor /proc/cpuinfo) 2>&1 | tee -a ../log/make.log"
            ],
            "problemMatcher": []    //这里也需要添加一个空的问题匹配器,否则会报错
        },
        {
            "label": "stm32-Build",    //第3个任务的名字叫Build
            "group": {               //默认是build任务
                "kind": "build",
                "isDefault": true
            },
            "dependsOrder": "sequence",    //顺序执行依赖项
            "dependsOn":[    //依赖的2个项为cmake、make
                "stm32-cmake",    //即第一个任务的label
                "stm32-make"      //即第二个任务的label
            ]
        },
        {
            "type": "shell",
            "label": "stm32-clean",    //第四个任务:清理 build 文件夹
            "command": "bash",
            "args": [
                "-c",
                "echo \"===== Clean started at: $(date) =====\" && rm -rf * && echo \"Build folder cleaned.\""
            ],
            "options": {
                "cwd": "${workspaceFolder}/build"    //只清理build目录下的文件
            },
            "problemMatcher": []    //不需要问题匹配器
        }

    ]
}

Method 1:

On the VScode title bar, find 终端, then select 运行构建任务. The shortcut key is Ctrl+Shift+B.

It can be seen that the task has already been executed.

Method 2:

On the VScode title bar, find 终端, then select 运行任务.

Below are 4 STM32 tasks. The first one is the stm32-Build task. After running it, the effect is the same as Method 1 just now. The 运行构建任务 button in Method 1 actually runs this stm32-Build task.

This stm32-Build task includes the stm32-cmake and stm32-make tasks.

Then the stm32-clean task is to clear all files in the build folder.

You can try the stm32-clean task.

You can see that everything has been deleted.

You don't need to worry about configuring so many things every time you create a new project.

Most of the configuration files above are already included in https://github.com/tungchiahui/CubeMX\_MDK5to6\_Template仓库下的***`工程文件移植(创建新模板请看这里)`***文件夹了,到时候新建一个工程后,直接把这个文件夹下的所有文件全部复制过来即可。.

Using ozone for Flash programming and Debug debugging

Basic Configuration

Open the terminal, type ozone to launch the software, or directly find the application icon to open Ozone.

First, select a device, such as the STM32F407VET6 for my case.

Select Peripherals:

Click Next.

Fill in SWD if you are using SWD, or JTAG if you are using JTAG.

Choose ELF

You can choose elf, hex, or bin — generally, just pick elf.

Just keep the default setting for this step.

If you have enabled RTOS, you may encounter this issue.

warning (138): The target application seems to be using FreeRTOS, but FreeRTOS-awareness is not enabled.

It means your target application appears to use FreeRTOS, but FreeRTOS debugging support (RTOS-awareness) is currently not enabled.

Just apply the fix directly as instructed below.

Just click continue.

Flashing and Debugging

You can check out the video below, it's pretty good. (Start watching from 30:10)

https://www.bilibili.com/video/BV1yrLHzZEoE

Click File to sort by file name.

Find led_task.cpp and click to open this source file.

音乐页