Update README.md
This commit is contained in:
@@ -1 +1,848 @@
|
||||
# 📦 第八层:项目实战与工具链
|
||||
|
||||
## ✅ 工程管理
|
||||
|
||||
### 🔹 Git 版本控制
|
||||
|
||||
#### 1. **Git 分支策略**
|
||||
- **主干分支(main/master)**:
|
||||
永远代表可发布的稳定版本,仅接受通过CI/CD验证的代码。
|
||||
- **开发分支(develop)**:
|
||||
集成所有新功能的开发,是日常开发的基础分支。
|
||||
- **特性分支(feature/*)**:
|
||||
从develop分支创建,用于开发单个新功能或修复问题,完成后合并回develop。
|
||||
- **发布分支(release/*)**:
|
||||
从develop分支创建,用于准备发布版本,进行最后的测试和Bug修复。
|
||||
- **热修复分支(hotfix/*)**:
|
||||
从main分支创建,用于紧急修复生产环境问题,修复后合并回main和develop。
|
||||
|
||||
#### 2. **提交规范**
|
||||
采用Conventional Commits规范:
|
||||
```
|
||||
<类型>[可选范围]: <描述>
|
||||
|
||||
[可选正文]
|
||||
|
||||
[可选脚注]
|
||||
```
|
||||
- **常见类型**:
|
||||
- `feat`:新功能
|
||||
- `fix`:修复Bug
|
||||
- `docs`:文档更新
|
||||
- `style`:代码格式调整(不影响功能)
|
||||
- `refactor`:代码重构
|
||||
- `test`:添加或修改测试
|
||||
- `chore`:构建或辅助工具的变动
|
||||
|
||||
#### 3. **标签管理**
|
||||
使用语义化版本(SemVer)打标签:
|
||||
```bash
|
||||
# 创建标签
|
||||
git tag v1.0.0
|
||||
|
||||
# 推送标签到远程
|
||||
git push origin v1.0.0
|
||||
|
||||
# 查看所有标签
|
||||
git tag -l
|
||||
```
|
||||
|
||||
|
||||
### 🔹 Makefile、CMake 构建工具
|
||||
|
||||
#### 1. **Makefile 基础**
|
||||
- **简单示例**:
|
||||
```makefile
|
||||
CC = arm-none-eabi-gcc
|
||||
CFLAGS = -Wall -O2 -mcpu=cortex-m4 -mthumb
|
||||
LDFLAGS = -Tstm32f4.ld
|
||||
|
||||
SRCS = $(wildcard *.c)
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
TARGET = firmware.elf
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(OBJS) -o $@
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(TARGET)
|
||||
```
|
||||
|
||||
#### 2. **CMake 高级应用**
|
||||
- **跨平台配置**:
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(EmbeddedProject C)
|
||||
|
||||
# 设置交叉编译工具链
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
|
||||
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
|
||||
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
|
||||
|
||||
# 添加编译选项
|
||||
add_compile_options(
|
||||
-mcpu=cortex-m4
|
||||
-mthumb
|
||||
-mfloat-abi=hard
|
||||
-mfpu=fpv4-sp-d16
|
||||
-Wall
|
||||
-Wextra
|
||||
-Os
|
||||
)
|
||||
|
||||
# 添加链接选项
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T${CMAKE_SOURCE_DIR}/STM32F407VGTx_FLASH.ld")
|
||||
|
||||
# 添加源文件
|
||||
file(GLOB_RECURSE SOURCES "src/*.c" "drivers/*.c")
|
||||
|
||||
# 添加可执行文件
|
||||
add_executable(${PROJECT_NAME}.elf ${SOURCES})
|
||||
|
||||
# 添加目标文件
|
||||
add_custom_target(${PROJECT_NAME}.bin
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin
|
||||
DEPENDS ${PROJECT_NAME}.elf
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
### 🔹 Jenkins/GitHub Actions CI 流水线
|
||||
|
||||
#### 1. **GitHub Actions 配置**
|
||||
- **编译与测试工作流**:
|
||||
```yaml
|
||||
name: Build and Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
pull_request:
|
||||
branches: [ main, develop ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y gcc-arm-none-eabi cmake ninja-build
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake -B build -G Ninja
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd build
|
||||
ctest --output-on-failure
|
||||
```
|
||||
|
||||
#### 2. **Jenkins 集成**
|
||||
- **构建脚本示例**:
|
||||
```groovy
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
checkout scm
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'make clean all'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh 'make test'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Code Coverage') {
|
||||
steps {
|
||||
sh 'make coverage'
|
||||
}
|
||||
post {
|
||||
always {
|
||||
junit 'build/test-results/*.xml'
|
||||
publishCoverage adapters: [coberturaAdapter('build/coverage/coverage.xml')]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy') {
|
||||
when {
|
||||
branch 'main'
|
||||
}
|
||||
steps {
|
||||
sh 'make deploy'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## ✅ 项目实践
|
||||
|
||||
### 🔹 嵌入式应用框架设计
|
||||
|
||||
#### 1. **分层架构**
|
||||
```
|
||||
+----------------------+
|
||||
| 应用层 |
|
||||
| (业务逻辑、算法) |
|
||||
+----------------------+
|
||||
| 服务层 |
|
||||
| (任务管理、事件) |
|
||||
+----------------------+
|
||||
| 驱动层 |
|
||||
| (硬件抽象、BSP) |
|
||||
+----------------------+
|
||||
| 硬件层 |
|
||||
| (MCU、外设) |
|
||||
+----------------------+
|
||||
```
|
||||
|
||||
#### 2. **组件化设计**
|
||||
- **核心组件**:
|
||||
- 任务管理器:负责任务创建、调度和通信。
|
||||
- 事件系统:处理异步事件和回调。
|
||||
- 配置管理:加载和保存系统配置。
|
||||
- 日志系统:分级日志记录和输出。
|
||||
|
||||
#### 3. **代码结构示例**
|
||||
```
|
||||
project/
|
||||
├── app/ # 应用层
|
||||
│ ├── main.c # 主程序入口
|
||||
│ ├── modules/ # 功能模块
|
||||
│ │ ├── sensor/ # 传感器处理
|
||||
│ │ ├── comm/ # 通信处理
|
||||
│ │ └── control/ # 控制逻辑
|
||||
│ └── config/ # 配置文件
|
||||
├── services/ # 服务层
|
||||
│ ├── task_mgr/ # 任务管理器
|
||||
│ ├── event/ # 事件系统
|
||||
│ └── utils/ # 工具函数
|
||||
├── drivers/ # 驱动层
|
||||
│ ├── bsp/ # 板级支持包
|
||||
│ ├── hal/ # 硬件抽象层
|
||||
│ └── periph/ # 外设驱动
|
||||
└── build/ # 构建系统
|
||||
├── cmake/ # CMake配置
|
||||
└── Makefile # Makefile
|
||||
```
|
||||
|
||||
|
||||
### 🔹 通用 BSP 构建
|
||||
|
||||
#### 1. **设计原则**
|
||||
- **硬件无关性**:上层代码不直接访问硬件寄存器。
|
||||
- **可移植性**:相同功能代码可在不同硬件平台复用。
|
||||
- **配置化**:通过配置文件而非修改代码适配不同硬件。
|
||||
|
||||
#### 2. **BSP 实现示例**
|
||||
```c
|
||||
// bsp_led.h
|
||||
#ifndef BSP_LED_H
|
||||
#define BSP_LED_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
LED_RED,
|
||||
LED_GREEN,
|
||||
LED_BLUE
|
||||
} led_t;
|
||||
|
||||
typedef enum {
|
||||
LED_OFF,
|
||||
LED_ON,
|
||||
LED_TOGGLE
|
||||
} led_state_t;
|
||||
|
||||
// 初始化LED
|
||||
void bsp_led_init(void);
|
||||
|
||||
// 设置LED状态
|
||||
void bsp_led_set(led_t led, led_state_t state);
|
||||
|
||||
#endif
|
||||
|
||||
// bsp_led.c (STM32实现)
|
||||
#include "bsp_led.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
// LED GPIO定义
|
||||
#define LED_RED_PIN GPIO_PIN_14
|
||||
#define LED_RED_PORT GPIOG
|
||||
#define LED_GREEN_PIN GPIO_PIN_13
|
||||
#define LED_GREEN_PORT GPIOG
|
||||
#define LED_BLUE_PIN GPIO_PIN_15
|
||||
#define LED_BLUE_PORT GPIOG
|
||||
|
||||
void bsp_led_init(void) {
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
// 使能GPIO时钟
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
|
||||
// 配置GPIO引脚
|
||||
GPIO_InitStruct.Pin = LED_RED_PIN | LED_GREEN_PIN | LED_BLUE_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
|
||||
|
||||
// 默认关闭所有LED
|
||||
HAL_GPIO_WritePin(LED_RED_PORT, LED_RED_PIN, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(LED_GREEN_PORT, LED_GREEN_PIN, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(LED_BLUE_PORT, LED_BLUE_PIN, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
void bsp_led_set(led_t led, led_state_t state) {
|
||||
GPIO_TypeDef *port;
|
||||
uint16_t pin;
|
||||
|
||||
// 根据LED类型选择GPIO
|
||||
switch (led) {
|
||||
case LED_RED:
|
||||
port = LED_RED_PORT;
|
||||
pin = LED_RED_PIN;
|
||||
break;
|
||||
case LED_GREEN:
|
||||
port = LED_GREEN_PORT;
|
||||
pin = LED_GREEN_PIN;
|
||||
break;
|
||||
case LED_BLUE:
|
||||
port = LED_BLUE_PORT;
|
||||
pin = LED_BLUE_PIN;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置LED状态
|
||||
switch (state) {
|
||||
case LED_OFF:
|
||||
HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET);
|
||||
break;
|
||||
case LED_ON:
|
||||
HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET);
|
||||
break;
|
||||
case LED_TOGGLE:
|
||||
HAL_GPIO_TogglePin(port, pin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### 🔹 模块化驱动结构
|
||||
|
||||
#### 1. **驱动分层**
|
||||
- **硬件层**:直接操作寄存器的低级驱动。
|
||||
- **抽象层**:提供统一接口的高级驱动。
|
||||
- **适配层**:连接抽象层和硬件层的中间层。
|
||||
|
||||
#### 2. **SPI驱动示例**
|
||||
```c
|
||||
// spi_interface.h (抽象接口)
|
||||
#ifndef SPI_INTERFACE_H
|
||||
#define SPI_INTERFACE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
// 初始化SPI
|
||||
void (*init)(uint32_t baudrate);
|
||||
|
||||
// 发送数据
|
||||
void (*send)(const uint8_t *data, uint32_t length);
|
||||
|
||||
// 接收数据
|
||||
void (*receive)(uint8_t *data, uint32_t length);
|
||||
|
||||
// 发送并接收数据
|
||||
void (*transfer)(const uint8_t *tx_data, uint8_t *rx_data, uint32_t length);
|
||||
} spi_interface_t;
|
||||
|
||||
// 获取SPI接口实例
|
||||
const spi_interface_t* spi_get_interface(void);
|
||||
|
||||
#endif
|
||||
|
||||
// spi_stm32.c (STM32实现)
|
||||
#include "spi_interface.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
static SPI_HandleTypeDef hspi1;
|
||||
|
||||
static void spi_init(uint32_t baudrate) {
|
||||
// 配置SPI参数
|
||||
hspi1.Instance = SPI1;
|
||||
hspi1.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi1.Init.NSS = SPI_NSS_SOFT;
|
||||
|
||||
// 根据波特率计算分频系数
|
||||
uint32_t prescaler = SPI_BAUDRATEPRESCALER_2;
|
||||
if (baudrate < 1000000) prescaler = SPI_BAUDRATEPRESCALER_128;
|
||||
else if (baudrate < 2000000) prescaler = SPI_BAUDRATEPRESCALER_64;
|
||||
else if (baudrate < 4000000) prescaler = SPI_BAUDRATEPRESCALER_32;
|
||||
else if (baudrate < 8000000) prescaler = SPI_BAUDRATEPRESCALER_16;
|
||||
else if (baudrate < 16000000) prescaler = SPI_BAUDRATEPRESCALER_8;
|
||||
else if (baudrate < 32000000) prescaler = SPI_BAUDRATEPRESCALER_4;
|
||||
|
||||
hspi1.Init.BaudRatePrescaler = prescaler;
|
||||
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
hspi1.Init.CRCPolynomial = 10;
|
||||
|
||||
// 初始化SPI
|
||||
HAL_SPI_Init(&hspi1);
|
||||
}
|
||||
|
||||
static void spi_send(const uint8_t *data, uint32_t length) {
|
||||
HAL_SPI_Transmit(&hspi1, (uint8_t*)data, length, 1000);
|
||||
}
|
||||
|
||||
static void spi_receive(uint8_t *data, uint32_t length) {
|
||||
HAL_SPI_Receive(&hspi1, data, length, 1000);
|
||||
}
|
||||
|
||||
static void spi_transfer(const uint8_t *tx_data, uint8_t *rx_data, uint32_t length) {
|
||||
HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)tx_data, rx_data, length, 1000);
|
||||
}
|
||||
|
||||
// SPI接口实现
|
||||
static const spi_interface_t spi_impl = {
|
||||
.init = spi_init,
|
||||
.send = spi_send,
|
||||
.receive = spi_receive,
|
||||
.transfer = spi_transfer
|
||||
};
|
||||
|
||||
// 获取SPI接口实例
|
||||
const spi_interface_t* spi_get_interface(void) {
|
||||
return &spi_impl;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### 🔹 OTA 升级方案设计
|
||||
|
||||
#### 1. **双分区架构**
|
||||
```
|
||||
Flash布局:
|
||||
+-------------------+ 0x08000000
|
||||
| Bootloader | (80KB)
|
||||
+-------------------+ 0x08014000
|
||||
| Application A | (448KB)
|
||||
+-------------------+ 0x08084000
|
||||
| Application B | (448KB)
|
||||
+-------------------+ 0x08104000
|
||||
| Configuration | (16KB)
|
||||
+-------------------+
|
||||
```
|
||||
|
||||
#### 2. **OTA状态机**
|
||||
```c
|
||||
typedef enum {
|
||||
OTA_IDLE, // 空闲状态
|
||||
OTA_CHECKING, // 检查更新
|
||||
OTA_DOWNLOADING, // 下载中
|
||||
OTA_DOWNLOAD_PAUSED, // 下载暂停
|
||||
OTA_VERIFYING, // 校验中
|
||||
OTA_READY, // 准备重启
|
||||
OTA_UPGRADING, // 升级中
|
||||
OTA_FAILED // 升级失败
|
||||
} ota_state_t;
|
||||
|
||||
typedef struct {
|
||||
ota_state_t state;
|
||||
uint32_t total_size;
|
||||
uint32_t downloaded_size;
|
||||
uint8_t progress;
|
||||
char error_msg[64];
|
||||
uint8_t firmware_hash[32];
|
||||
} ota_context_t;
|
||||
```
|
||||
|
||||
#### 3. **OTA流程**
|
||||
1. **检查更新**:
|
||||
```c
|
||||
bool ota_check_update(void) {
|
||||
// 从服务器获取版本信息
|
||||
http_response_t response = http_get(UPDATE_SERVER_URL "/version");
|
||||
if (response.status != 200) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 解析服务器版本
|
||||
uint32_t server_version = parse_version(response.body);
|
||||
uint32_t current_version = get_current_version();
|
||||
|
||||
// 比较版本
|
||||
return (server_version > current_version);
|
||||
}
|
||||
```
|
||||
|
||||
2. **下载固件**:
|
||||
```c
|
||||
void ota_download_firmware(void) {
|
||||
// 打开固件下载URL
|
||||
http_client_t client = http_open(UPDATE_SERVER_URL "/firmware.bin");
|
||||
if (!client) {
|
||||
ota_set_state(OTA_FAILED, "Failed to open URL");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取文件大小
|
||||
uint32_t file_size = http_get_content_length(client);
|
||||
ota_set_total_size(file_size);
|
||||
|
||||
// 开始下载
|
||||
uint8_t buffer[512];
|
||||
uint32_t bytes_received = 0;
|
||||
uint32_t bytes_written = 0;
|
||||
|
||||
while ((bytes_received = http_read(client, buffer, 512)) > 0) {
|
||||
// 写入到备份区
|
||||
if (!flash_write(APPLICATION_B_ADDRESS + bytes_written, buffer, bytes_received)) {
|
||||
ota_set_state(OTA_FAILED, "Flash write failed");
|
||||
http_close(client);
|
||||
return;
|
||||
}
|
||||
|
||||
bytes_written += bytes_received;
|
||||
ota_update_progress(bytes_written * 100 / file_size);
|
||||
|
||||
// 检查是否需要暂停
|
||||
if (ota_should_pause()) {
|
||||
http_close(client);
|
||||
ota_set_state(OTA_DOWNLOAD_PAUSED, "Download paused");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
http_close(client);
|
||||
ota_set_state(OTA_VERIFYING, "Verifying firmware");
|
||||
}
|
||||
```
|
||||
|
||||
3. **验证与应用**:
|
||||
```c
|
||||
bool ota_verify_firmware(void) {
|
||||
// 计算下载固件的哈希值
|
||||
uint8_t calculated_hash[32];
|
||||
calculate_firmware_hash(APPLICATION_B_ADDRESS, APPLICATION_SIZE, calculated_hash);
|
||||
|
||||
// 与服务器提供的哈希值比较
|
||||
if (memcmp(calculated_hash, ota_get_expected_hash(), 32) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 验证向量表
|
||||
uint32_t *vector_table = (uint32_t*)APPLICATION_B_ADDRESS;
|
||||
if (vector_table[0] == 0 || vector_table[1] == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ota_apply_update(void) {
|
||||
// 设置升级标志
|
||||
set_update_flag(1);
|
||||
|
||||
// 保存新固件版本
|
||||
save_new_version(get_server_version());
|
||||
|
||||
// 重启系统
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
```
|
||||
|
||||
# 开发工具链安装指南
|
||||
## 1. **IDE推荐**
|
||||
|
||||
### VS Code + PlatformIO
|
||||
|
||||
**官网链接**:
|
||||
- [VS Code](https://code.visualstudio.com/)
|
||||
- [PlatformIO](https://platformio.org/)
|
||||
|
||||
**安装步骤**:
|
||||
1. 下载并安装 [VS Code](https://code.visualstudio.com/Download)
|
||||
2. 打开VS Code,点击左侧扩展图标(或按 `Ctrl+Shift+X`)
|
||||
3. 搜索并安装 **PlatformIO IDE** 扩展
|
||||
4. 安装完成后,重启VS Code
|
||||
5. PlatformIO会自动安装所需的工具链和依赖
|
||||
|
||||
**验证安装**:
|
||||
打开VS Code,点击左下角的 **PlatformIO Home** 图标,若能正常打开则安装成功。
|
||||
|
||||
|
||||
### STM32CubeIDE
|
||||
|
||||
**官网链接**:
|
||||
- [STM32CubeIDE](https://www.st.com/en/development-tools/stm32cubeide.html)
|
||||
|
||||
**安装步骤**:
|
||||
1. 访问官网,点击 **Get Software** 下载对应操作系统的安装包
|
||||
2. 运行安装程序,按照向导完成安装
|
||||
3. 安装过程中会自动下载并配置STM32CubeMX
|
||||
|
||||
**验证安装**:
|
||||
启动STM32CubeIDE,创建一个新的STM32项目,若能正常编译则安装成功。
|
||||
|
||||
|
||||
### CLion
|
||||
|
||||
**官网链接**:
|
||||
- [CLion](https://www.jetbrains.com/clion/)
|
||||
|
||||
**安装步骤**:
|
||||
1. 下载并安装 [CLion](https://www.jetbrains.com/clion/download/)
|
||||
2. 安装CMake和MinGW(Windows用户需要):
|
||||
- CMake:从 [官网](https://cmake.org/download/) 下载并安装
|
||||
- MinGW:推荐使用 [MSYS2](https://www.msys2.org/) 安装
|
||||
|
||||
**验证安装**:
|
||||
启动CLion,创建一个新的C/C++项目,选择CMake工具链,若能正常编译则安装成功。
|
||||
|
||||
|
||||
## 2. **调试工具**
|
||||
|
||||
### OpenOCD
|
||||
|
||||
**官网链接**:
|
||||
- [OpenOCD](http://openocd.org/)
|
||||
|
||||
**安装步骤**:
|
||||
- **Windows**:
|
||||
1. 从 [GNU MCU Eclipse](https://github.com/gnu-mcu-eclipse/openocd/releases) 下载预编译二进制包
|
||||
2. 解压到指定目录(如 `C:\openocd`)
|
||||
3. 将 `bin` 目录添加到系统环境变量
|
||||
|
||||
- **Linux**:
|
||||
```bash
|
||||
sudo apt-get install openocd # Ubuntu/Debian
|
||||
sudo yum install openocd # CentOS/RHEL
|
||||
```
|
||||
|
||||
- **macOS**:
|
||||
```bash
|
||||
brew install open-ocd
|
||||
```
|
||||
|
||||
**验证安装**:
|
||||
在终端中运行 `openocd --version`,若显示版本信息则安装成功。
|
||||
|
||||
|
||||
### GDB
|
||||
|
||||
**官网链接**:
|
||||
- [GDB](https://www.gnu.org/software/gdb/)
|
||||
- [ARM GCC Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm)
|
||||
|
||||
**安装步骤**:
|
||||
1. 下载并安装 [ARM GCC Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads)
|
||||
2. 将 `bin` 目录添加到系统环境变量
|
||||
|
||||
**验证安装**:
|
||||
在终端中运行 `arm-none-eabi-gdb --version`,若显示版本信息则安装成功。
|
||||
|
||||
|
||||
### ST-Link/V2
|
||||
|
||||
**官网链接**:
|
||||
- [ST-Link](https://www.st.com/en/development-tools/st-link-v2.html)
|
||||
|
||||
**安装步骤**:
|
||||
- **Windows**:
|
||||
1. 从 [ST官网](https://www.st.com/en/development-tools/stsw-link004.html) 下载并安装ST-Link驱动
|
||||
2. 安装完成后,将ST-Link/V2调试器连接到电脑
|
||||
|
||||
- **Linux**:
|
||||
```bash
|
||||
sudo apt-get install stlink-tools # Ubuntu/Debian
|
||||
```
|
||||
|
||||
**验证安装**:
|
||||
在终端中运行 `st-info --version`,若显示版本信息则安装成功。
|
||||
|
||||
|
||||
## 3. **静态代码分析**
|
||||
|
||||
### CppCheck
|
||||
|
||||
**官网链接**:
|
||||
- [CppCheck](https://cppcheck.sourceforge.io/)
|
||||
|
||||
**安装步骤**:
|
||||
- **Windows**:
|
||||
1. 从 [官网](https://cppcheck.sourceforge.io/) 下载安装包
|
||||
2. 运行安装程序,按照向导完成安装
|
||||
|
||||
- **Linux**:
|
||||
```bash
|
||||
sudo apt-get install cppcheck # Ubuntu/Debian
|
||||
sudo yum install cppcheck # CentOS/RHEL
|
||||
```
|
||||
|
||||
- **macOS**:
|
||||
```bash
|
||||
brew install cppcheck
|
||||
```
|
||||
|
||||
**验证安装**:
|
||||
在终端中运行 `cppcheck --version`,若显示版本信息则安装成功。
|
||||
|
||||
|
||||
### Clang-Tidy
|
||||
|
||||
**官网链接**:
|
||||
- [Clang-Tidy](https://clang.llvm.org/extra/clang-tidy/)
|
||||
|
||||
**安装步骤**:
|
||||
- **Windows**:
|
||||
1. 安装 [LLVM](https://releases.llvm.org/download.html)
|
||||
2. Clang-Tidy会随LLVM一起安装
|
||||
|
||||
- **Linux**:
|
||||
```bash
|
||||
sudo apt-get install clang-tidy # Ubuntu/Debian
|
||||
```
|
||||
|
||||
- **macOS**:
|
||||
```bash
|
||||
brew install llvm
|
||||
```
|
||||
|
||||
**验证安装**:
|
||||
在终端中运行 `clang-tidy --version`,若显示版本信息则安装成功。
|
||||
|
||||
|
||||
### SonarQube
|
||||
|
||||
**官网链接**:
|
||||
- [SonarQube](https://www.sonarqube.org/)
|
||||
|
||||
**安装步骤**:
|
||||
1. 下载并安装 [Docker](https://www.docker.com/get-started)
|
||||
2. 运行SonarQube容器:
|
||||
```bash
|
||||
docker run -d --name sonarqube -p 9000:9000 sonarqube
|
||||
```
|
||||
3. 访问 [http://localhost:9000](http://localhost:9000),使用默认账号(admin/admin)登录
|
||||
|
||||
**验证安装**:
|
||||
在浏览器中打开 [http://localhost:9000](http://localhost:9000),若能看到SonarQube界面则安装成功。
|
||||
|
||||
|
||||
## 4. **单元测试**
|
||||
|
||||
### Unity
|
||||
|
||||
**官网链接**:
|
||||
- [Unity](https://github.com/ThrowTheSwitch/Unity)
|
||||
|
||||
**安装步骤**:
|
||||
1. 从GitHub下载Unity源码:
|
||||
```bash
|
||||
git clone https://github.com/ThrowTheSwitch/Unity.git
|
||||
```
|
||||
2. 将 `src` 目录添加到项目的头文件搜索路径
|
||||
|
||||
**验证安装**:
|
||||
创建一个简单的测试文件,包含Unity头文件,若能正常编译则安装成功。
|
||||
|
||||
|
||||
### CMock
|
||||
|
||||
**官网链接**:
|
||||
- [CMock](https://github.com/ThrowTheSwitch/CMock)
|
||||
|
||||
**安装步骤**:
|
||||
1. 从GitHub下载CMock源码:
|
||||
```bash
|
||||
git clone https://github.com/ThrowTheSwitch/CMock.git
|
||||
```
|
||||
2. 将 `src` 目录添加到项目的头文件搜索路径
|
||||
|
||||
**验证安装**:
|
||||
创建一个简单的测试文件,包含CMock头文件,若能正常编译则安装成功。
|
||||
|
||||
|
||||
### Google Test
|
||||
|
||||
**官网链接**:
|
||||
- [Google Test](https://github.com/google/googletest)
|
||||
|
||||
**安装步骤**:
|
||||
1. 从GitHub下载Google Test源码:
|
||||
```bash
|
||||
git clone https://github.com/google/googletest.git
|
||||
```
|
||||
2. 使用CMake构建并安装:
|
||||
```bash
|
||||
cd googletest
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
**验证安装**:
|
||||
创建一个简单的测试文件,包含Google Test头文件,若能正常编译则安装成功。
|
||||
|
||||
|
||||
## 📚 资源汇总
|
||||
|
||||
| **工具** | **官网链接** | **安装指南** |
|
||||
|------------------|---------------------------------------------|-------------------------------------------|
|
||||
| VS Code | https://code.visualstudio.com/ | 直接下载安装包 |
|
||||
| PlatformIO | https://platformio.org/ | VS Code扩展市场安装 |
|
||||
| STM32CubeIDE | https://www.st.com/en/development-tools/stm32cubeide.html | 官网下载安装包 |
|
||||
| CLion | https://www.jetbrains.com/clion/ | 官网下载安装包 |
|
||||
| OpenOCD | http://openocd.org/ | 包管理器或预编译二进制包 |
|
||||
| GDB | https://www.gnu.org/software/gdb/ | 随ARM GCC Toolchain安装 |
|
||||
| ST-Link/V2 | https://www.st.com/en/development-tools/st-link-v2.html | 官网下载驱动 |
|
||||
| CppCheck | https://cppcheck.sourceforge.io/ | 包管理器或安装包 |
|
||||
| Clang-Tidy | https://clang.llvm.org/extra/clang-tidy/ | 随LLVM安装 |
|
||||
| SonarQube | https://www.sonarqube.org/ | Docker容器或独立安装 |
|
||||
| Unity | https://github.com/ThrowTheSwitch/Unity | 从GitHub下载源码 |
|
||||
| CMock | https://github.com/ThrowTheSwitch/CMock | 从GitHub下载源码 |
|
||||
| Google Test | https://github.com/google/googletest | CMake构建并安装 |
|
||||
|
||||
Reference in New Issue
Block a user