1. 初始化嵌入式DevOps项目结构
任务目标
为嵌入式项目创建一个标准化的DevOps目录结构,将源码、构建脚本、配置文件和文档分离管理,为后续接入CI/CD流水线提供清晰、可扩展的项目骨架。
目录结构设计
embedded-devops-demo/
├── CMakeLists.txt # 顶层CMake构建入口
├── README.md # 项目说明文档
├── .gitignore # Git忽略规则
├── .gitlab-ci.yml # GitLab CI流水线配置(占位)
├── src/ # 源代码目录
│ ├── CMakeLists.txt
│ ├── main.c # 主程序入口
│ └── led_control.c # LED控制模块实现
├── include/ # 公共头文件目录
│ └── led_control.h
├── config/ # 配置文件目录
│ └── board_def.h # 板级硬件配置宏
├── scripts/ # 构建与辅助脚本目录
│ ├── build.sh # 一键构建脚本
│ └── flash.sh # 固件烧录脚本(占位)
├── docs/ # 文档目录
│ └── architecture.md # 架构说明文档
└── tests/ # 测试目录(预留)
└── CMakeLists.txt # 测试构建配置(空壳)
关键完整代码
以下代码为最小可复现实现,覆盖从空目录到可编译二进制文件的完整闭环。
# 1. 顶层 CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(embedded_devops_demo C)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
# 如果使用交叉编译器,通过工具链文件指定
if(CMAKE_TOOLCHAIN_FILE)
message(STATUS "Using toolchain: ${CMAKE_TOOLCHAIN_FILE}")
endif()
# 添加子目录
add_subdirectory(src)
add_subdirectory(tests)
# 2. src/CMakeLists.txt
# 生成目标固件库
add_library(app_objs OBJECT
main.c
led_control.c
)
target_include_directories(app_objs PRIVATE
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/config
)
# 生成可执行文件(模拟固件,实际嵌入式可替换为生成 .hex/.bin)
add_executable(firmware.elf $<TARGET_OBJECTS:app_objs>)
target_link_libraries(firmware.elf PRIVATE app_objs)
# 3. src/main.c
#include <stdio.h>
#include "led_control.h"
#include "board_def.h"
int main(void) {
printf("Embedded DevOps Demo v%d.%d\n", VERSION_MAJOR, VERSION_MINOR);
led_init();
led_set_state(LED_ON);
printf("LED state: %s\n", led_get_state() == LED_ON ? "ON" : "OFF");
return 0;
}
// 4. src/led_control.c
#include "led_control.h"
static led_state_t current_state = LED_OFF;
void led_init(void) {
current_state = LED_OFF;
}
void led_set_state(led_state_t state) {
current_state = state;
}
led_state_t led_get_state(void) {
return current_state;
}
// 5. include/led_control.h
#ifndef LED_CONTROL_H
#define LED_CONTROL_H
typedef enum {
LED_OFF = 0,
LED_ON = 1
} led_state_t;
void led_init(void);
void led_set_state(led_state_t state);
led_state_t led_get_state(void);
#endif // LED_CONTROL_H
// 6. config/board_def.h
#ifndef BOARD_DEF_H
#define BOARD_DEF_H
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
// 板级硬件配置示例
#define LED_GPIO_PORT 'A'
#define LED_GPIO_PIN 5
#endif // BOARD_DEF_H
// 7. tests/CMakeLists.txt(预留测试框架,当前为空)
# 测试目录预留,后续可添加CUnit或Unity测试框架
// 8. scripts/build.sh
#!/bin/bash
# 一键构建脚本
set -e
BUILD_DIR="build"
if [ ! -d "$BUILD_DIR" ]; then
mkdir "$BUILD_DIR"
fi
cd "$BUILD_DIR"
cmake ..
make -j$(nproc)
echo "构建完成: $(pwd)/firmware.elf"
// 9. scripts/flash.sh
#!/bin/bash
# 烧录脚本占位,实际使用时替换为openocd/st-flash等命令
echo "烧录功能待实现,请根据实际硬件配置烧录工具"
// 10. .gitignore
build/
*.o
*.elf
*.hex
*.bin
// 11. .gitlab-ci.yml(占位,后续案例填充)
stages:
- build
build-job:
stage: build
script:
- chmod +x scripts/*.sh
- ./scripts/build.sh
artifacts:
paths:
- build/firmware.elf
运行与验证
- 创建项目结构:按上述目录结构创建文件夹和文件,或直接复制代码块内容到对应路径。
- 赋予脚本执行权限:
chmod +x scripts/*.sh - 执行构建:
./scripts/build.sh - 验证通过条件:
- 构建脚本无报错退出,退出码为0
- 生成
build/firmware.elf文件 - 运行
./build/firmware.elf,预期输出:
Embedded DevOps Demo v1.0 LED state: ON
以上输出为代码逻辑直接推出的确定性结果,非实测数据。若需交叉编译,在CMake命令中通过 -DCMAKE_TOOLCHAIN_FILE 指定工具链文件即可,当前案例以本机编译验证结构正确性。