添加.trae设计依据文件(功能规格、指令集、引脚配置)
This commit is contained in:
@@ -10,7 +10,6 @@ build/
|
||||
# IDE files
|
||||
.idea/
|
||||
.vscode/
|
||||
.trae/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
***
|
||||
|
||||
name: "create-project"
|
||||
description: "创建和配置嵌入式工程项目,按照标准目录结构生成驱动代码和配置文件。调用时机:当需要创建嵌入式工程项目、生成驱动代码、配置硬件外设或设计通讯协议时。"
|
||||
version: 1.1.0
|
||||
--------------
|
||||
|
||||
# PROJECT Configuration Skill
|
||||
|
||||
该技能用于创建和配置嵌入式工程项目,按照标准化的工程目录结构生成完整的工程代码,包括硬件驱动、通讯协议、配置文件等,并确保工程的可编译性和可维护性。
|
||||
|
||||
## 调用时机
|
||||
|
||||
在以下情况下必须调用此技能:
|
||||
|
||||
- 需要创建新的嵌入式工程项目时
|
||||
- 需要生成硬件外设驱动代码(ADC、UART、I2C、SPI、PWM、Timer、GPIO、RTC、DMA等)时
|
||||
- 需要设计通讯协议并实现协议解析代码时
|
||||
- 需要配置工程编译环境(CMake、Makefile)时
|
||||
- 需要按照标准化目录结构组织工程文件时
|
||||
- 需要生成可执行文件并验证工程正确性时
|
||||
- 需要参考reference文档进行驱动设计和协议设计时
|
||||
|
||||
## 工作流程
|
||||
|
||||
1. 根据输入的项目名称和选择的芯片,创建工程目录
|
||||
2. 严格按照工程目录结构创建目录和文件
|
||||
3. 下载相应的编译和调试工具链,包括编译器、调试器、库文件,生成对应的下载flash脚本等
|
||||
4. 配置编译环境,包括设置编译器、设置调试器等
|
||||
5. 生成驱动代码,驱动外部设备,每一种驱动都单独生成一个源文件和一个头文件
|
||||
6. 编译工程,生成可执行文件,并烧录到单片机中
|
||||
|
||||
## 技能内容
|
||||
|
||||
1. **工程目录结构**:
|
||||
|
||||
### 目录结构规范
|
||||
|
||||
工程必须严格按照以下目录结构创建,确保一致性和可维护性:
|
||||
|
||||
```
|
||||
ProjectName/
|
||||
├── .trae/skills/ # Trae技能目录
|
||||
│ ├── create-project/ # 创建工程技能(必须存在)
|
||||
│ │ ├── SKILL.md # 技能文档
|
||||
│ │ ├── scripts/ # 可选:存放可执行脚本
|
||||
│ │ ├── references/ # 必须:存放供AI参考的文档(通讯协议、原理图等)
|
||||
│ │ └── assets/ # 可选:存放静态资源文件
|
||||
│ ├── download-tools/ # 下载工具链技能
|
||||
│ └── download-lib/ # 下载库技能
|
||||
├── app/ # 应用层源代码
|
||||
│ ├── main.c # 主程序(必须包含main函数)
|
||||
│ ├── main.h # 主程序头文件
|
||||
│ └── tasks/ # 任务文件目录
|
||||
│ ├── work_task.c # 工作任务文件
|
||||
│ ├── work_task.h # 工作任务头文件
|
||||
│ ├── monitor_task.c # 监控任务文件
|
||||
│ └── monitor_task.h # 监控任务头文件
|
||||
├── bsp/ # 板级支持包
|
||||
│ ├── common_types.h # 通用类型定义(必须包含ret_code_t等)
|
||||
│ ├── hardware_init.h # 硬件初始化头文件
|
||||
│ ├── hardware_init.c # 硬件初始化源文件(必须包含DMA时钟使能等)
|
||||
│ └── device/ # 外部芯片设备文件目录
|
||||
│ │ ├── eeprom/ # EEPROM驱动头文件目录
|
||||
│ │ │ ├── eeprom_driver.h # EEPROM驱动头文件
|
||||
│ │ │ └── eeprom_driver.c # EEPROM驱动源文件
|
||||
│ │ ├── key/ # KEY驱动头文件目录
|
||||
│ │ │ ├── key_driver.h # KEY驱动头文件
|
||||
│ │ │ └── key_driver.c # KEY驱动源文件
|
||||
│ │ ├── led/ # LED驱动头文件目录
|
||||
│ │ │ ├── led_driver.h # LED驱动头文件
|
||||
│ │ │ └── led_driver.c # LED驱动源文件
|
||||
├── doc/ # 文档目录
|
||||
├── drv/ # 单片机外设驱动层源代码
|
||||
│ ├── system/ # 系统驱动(如系统时钟、中断、中断服务函数等)
|
||||
│ │ ├── system_driver.h # 系统驱动头文件
|
||||
│ │ └── system_driver.c # 系统驱动源文件
|
||||
│ ├── adc/ # ADC驱动(每个驱动单独目录)
|
||||
│ │ ├── adc_driver.h # ADC驱动头文件
|
||||
│ │ └── adc_driver.c # ADC驱动源文件
|
||||
│ ├── i2c/ # I2C驱动(必须支持DMA FIFO)
|
||||
│ │ ├── i2c_driver.h # I2C驱动头文件
|
||||
│ │ └── i2c_driver.c # I2C驱动源文件
|
||||
│ ├── uart/ # UART驱动(必须支持DMA FIFO)
|
||||
│ │ ├── uart_driver.h # UART驱动头文件
|
||||
│ │ └── uart_driver.c # UART驱动源文件
|
||||
│ └── timer/ # 定时器驱动(必须支持DMA FIFO)
|
||||
│ │ ├── timer_driver.h # 定时器驱动头文件
|
||||
│ │ └── timer_driver.c # 定时器驱动源文件
|
||||
├── libs/ # 库文件
|
||||
│ ├── common/ # 通用库(将数据解析等通用功能封装在此库中)
|
||||
│ ├── CMSIS/ # CMSIS库(芯片供应商提供)
|
||||
│ ├── algorithm/ # 算法库
|
||||
│ └── thirdparty/ # 第三方库(如GD32F4xx库)
|
||||
├── config/ # 配置文件
|
||||
│ └── config.h # 系统配置文件(必须包含DEBUG_ENABLED等)
|
||||
├── tools/ # 工具文件目录
|
||||
│ ├── gcc/ # GCC工具
|
||||
│ ├── stlink/ # ST-LINK工具
|
||||
│ ├── openocd/ # OpenOCD工具
|
||||
│ ├── jlink/ # J-LINK工具
|
||||
│ ├── cmake/ # CMake工具
|
||||
│ ├── python/ # Python工具
|
||||
│ ├── makefile/ # Makefile工具
|
||||
│ ├── ninja/ # Ninja工具
|
||||
│ └── flash.sh # 烧录脚本文件
|
||||
├── tests/ # 测试文件目录
|
||||
├── build/ # 构建目录(临时文件,不提交到版本控制)
|
||||
│ ├── CMakeCache.txt # CMake缓存
|
||||
│ ├── CMakeFiles/ # CMake生成文件
|
||||
│ └── ProjectName.elf # 生成的可执行文件
|
||||
├── CMakeLists.txt # 主CMakeLists.txt文件(必须存在)
|
||||
└── README.md # 项目说明文档
|
||||
```
|
||||
|
||||
### 文件命名规范
|
||||
|
||||
- **头文件**:使用`.h`扩展名,命名格式:`<模块名>_driver.h` 或 `<模块名>.h`
|
||||
- **源文件**:使用`.c`扩展名,命名格式:`<模块名>_driver.c` 或 `<模块名>.c`
|
||||
- **测试文件**:使用`test_`前缀,命名格式:`test_<模块名>.c`
|
||||
- **配置文件**:使用`config.h`或`<模块名>_config.h`格式
|
||||
|
||||
### 编码规范
|
||||
|
||||
- **文件编码**:所有源文件和头文件必须使用UTF-8编码
|
||||
- **代码风格**:使用统一的代码缩进(4个空格)
|
||||
- **注释规范**:所有关键函数和结构体必须有中文注释说明
|
||||
- **函数命名**:使用小写字母和下划线,如`uart_init()`, `uart_set_data()`
|
||||
|
||||
### 目录创建要求
|
||||
|
||||
1. **必须严格按照上述结构创建目录**,不得随意更改
|
||||
2. **references目录必须包含完整的设计文档**(通讯协议、原理图等)
|
||||
3. **每个驱动必须有独立的.h和.c文件**,不得合并
|
||||
4. **build目录为临时目录**,不应提交到版本控制系统
|
||||
5. **所有文件路径必须使用正斜杠(/)分隔**,确保跨平台兼容性
|
||||
|
||||
## 工程参数配置
|
||||
1. 工程编译生成的过程文件全部放到build目录下
|
||||
2. 优先使用系统工具编译,如果不存在,那么使用tools目录下的工具进行编译
|
||||
3. 如果tools目录下的工具也不存在,那么下载调用DOWNLOAD-TOOLS技能进行下载
|
||||
4. 保持工程目录干净,不要过多文件,只保留必要的文件
|
||||
5. 设备注册:ADC、UART设备成功注册到系统
|
||||
6. 接口一致性:所有设备遵循统一的操作接口
|
||||
7. 扩展性:新设备可通过注册机制轻松添加
|
||||
8. 兼容性:与现有驱动代码完全兼容
|
||||
|
||||
## 协议设计指导
|
||||
|
||||
### 协议设计原则
|
||||
|
||||
协议设计必须严格遵循以下原则,确保通信的可靠性和可维护性:
|
||||
|
||||
1. **参考文档优先**:必须首先读取并分析`references/`目录中的通讯协议文档(.md、.docx、.xml、.pdf格式)
|
||||
2. **帧格式标准化**:协议帧必须包含帧头、设备ID、帧序号、数据长度、数据域、校验和等必要字段
|
||||
3. **校验机制**:根据文档要求实现校验机制(CRC16、简单求和校验等)
|
||||
4. **错误处理**:实现完整的错误检测和恢复机制
|
||||
|
||||
### 标准协议帧格式
|
||||
|
||||
基于常见的嵌入式通信协议,推荐使用以下标准帧格式:
|
||||
|
||||
```c
|
||||
// 标准协议帧结构
|
||||
typedef struct {
|
||||
uint8_t header_high; // 帧头高字节(如0xEB)
|
||||
uint8_t header_low; // 帧头低字节(如0x90)
|
||||
uint8_t device_id; // 设备ID(0x0A, 0x0B, 0x10等)
|
||||
uint8_t frame_seq; // 帧序号(每发送一帧加一)
|
||||
uint8_t data_length; // 数据长度(0-255)
|
||||
uint8_t data[32]; // 数据域(最大32字节)
|
||||
uint8_t checksum; // 校验和(简单求和校验)
|
||||
} standard_protocol_frame_t;
|
||||
```
|
||||
|
||||
### 协议实现要求
|
||||
|
||||
1. **帧头定义**:帧头必须与参考文档一致(如0xEB 0x90),不得随意更改
|
||||
2. **设备ID枚举**:必须定义清晰的设备ID枚举,区分不同协议类型:
|
||||
```c
|
||||
typedef enum {
|
||||
PROTOCOL_ID_CONTROL_CMD = 0x0A, // 控制命令协议
|
||||
PROTOCOL_ID_ANGLE_CTRL = 0x0B, // 角度控制协议
|
||||
PROTOCOL_ID_DATA_ACQ = 0x10 // 数据采集协议
|
||||
} protocol_id_t;
|
||||
```
|
||||
3. **校验函数**:实现与文档要求一致的校验函数
|
||||
4. **帧构建函数**:提供完整的帧构建和解析函数
|
||||
5. **数据转换**:正确处理字节序和数据格式转换(如浮点数转换)
|
||||
|
||||
### 伺服控制协议规范
|
||||
|
||||
对于伺服控制应用,必须遵循以下规范:
|
||||
|
||||
1. **角度控制协议**:使用浮点数表示角度,支持正负角度范围
|
||||
2. **数据采集协议**:包含AD采样值、温度、状态等信息
|
||||
3. **控制命令协议**:支持开关控制、模式切换等命令
|
||||
4. **实时性要求**:根据文档要求确定通信频率(如50Hz、400Hz)
|
||||
|
||||
### 协议测试验证
|
||||
|
||||
1. **单元测试**:为每个协议函数编写测试用例
|
||||
2. **集成测试**:测试完整的协议通信流程
|
||||
3. **边界测试**:测试最大/最小数据长度、异常帧处理
|
||||
4. **性能测试**:验证协议处理速度和内存使用
|
||||
|
||||
## 工具链配置
|
||||
|
||||
1. 优先使用tools目录下的工具链进行编译
|
||||
2. 如果tools目录下的工具链也不存在,那么下载调用DOWNLOAD-TOOLS技能进行下载
|
||||
|
||||
## 硬件外设配置与代码生成规范
|
||||
|
||||
### 驱动代码生成原则
|
||||
|
||||
1. **独立文件原则**:每个外设驱动必须有独立的`.h`头文件和`.c`源文件
|
||||
2. **统一接口原则**:所有驱动遵循统一的函数接口规范
|
||||
3. **模块化设计**:驱动代码应高度模块化,便于测试和维护
|
||||
4. **错误处理**:所有函数必须返回标准的错误代码(`ret_code_t`)
|
||||
|
||||
### 驱动文件结构
|
||||
|
||||
每个驱动目录必须包含以下文件:
|
||||
|
||||
```
|
||||
drv/<peripheral_name>/
|
||||
├── <peripheral_name>_driver.h # 驱动头文件
|
||||
├── <peripheral_name>_driver.c # 驱动源文件
|
||||
└── <peripheral_name>_config.h # 驱动配置头文件
|
||||
```
|
||||
|
||||
### 标准驱动接口函数
|
||||
|
||||
每个驱动必须实现以下标准函数接口(根据外设类型选择实现):
|
||||
|
||||
```c
|
||||
// 初始化函数
|
||||
ret_code_t <peripheral_name>_init(void);
|
||||
|
||||
// 反初始化函数
|
||||
ret_code_t <peripheral_name>_deinit(void);
|
||||
|
||||
// 读数据函数
|
||||
ret_code_t <peripheral_name>_read(uint8_t *data, uint16_t length);
|
||||
|
||||
// 写数据函数
|
||||
ret_code_t <peripheral_name>_write(const uint8_t *data, uint16_t length);
|
||||
|
||||
// 控制函数
|
||||
ret_code_t <peripheral_name>_control(uint32_t cmd, void *param);
|
||||
|
||||
// 设置函数
|
||||
ret_code_t <peripheral_name>_set(uint32_t param, uint32_t value);
|
||||
|
||||
// 获取函数
|
||||
ret_code_t <peripheral_name>_get(uint32_t param, uint32_t *value);
|
||||
```
|
||||
|
||||
### 驱动注册机制
|
||||
|
||||
必须实现驱动注册机制,支持动态添加和移除驱动:
|
||||
|
||||
```c
|
||||
// 设备注册结构体
|
||||
typedef struct {
|
||||
uint8_t device_id; // 设备ID
|
||||
const char *device_name; // 设备名称
|
||||
ret_code_t (*init_func)(void); // 初始化函数指针
|
||||
ret_code_t (*deinit_func)(void); // 反初始化函数指针
|
||||
ret_code_t (*read_func)(uint8_t*, uint16_t); // 读函数指针
|
||||
ret_code_t (*write_func)(const uint8_t*, uint16_t); // 写函数指针
|
||||
} device_driver_t;
|
||||
|
||||
// 设备注册函数
|
||||
ret_code_t register_device(const device_driver_t *driver);
|
||||
```
|
||||
|
||||
### 驱动特殊要求
|
||||
|
||||
对于所有驱动,必须满足以下特殊要求:
|
||||
|
||||
1. **DMA FIFO支持**:必须实现DMA+中断的FIFO缓冲区系统
|
||||
2. **可配置缓冲区**:支持可配置的接收缓冲区大小
|
||||
3. **错误检测**:实现溢出、帧错误、奇偶校验错误检测
|
||||
4. **波特率自适应**:支持动态波特率配置
|
||||
|
||||
示例驱动结构:
|
||||
```c
|
||||
// 驱动 FIFO缓冲区结构
|
||||
typedef struct {
|
||||
uint8_t buffer[UART_RX_BUFFER_SIZE];
|
||||
volatile uint16_t read_index;
|
||||
volatile uint16_t write_index;
|
||||
bool overflow;
|
||||
} driver_fifo_t;
|
||||
|
||||
// DMA初始化函数
|
||||
ret_code_t driver_dma_init(void);
|
||||
|
||||
|
||||
|
||||
### ADC驱动特殊要求
|
||||
|
||||
1. **多通道支持**:支持多通道ADC采样
|
||||
2. **采样率配置**:可配置采样率和采样精度
|
||||
3. **数据滤波**:实现数据滤波算法(如移动平均)
|
||||
4. **校准功能**:支持ADC校准和偏移校正
|
||||
|
||||
### PWM驱动特殊要求
|
||||
|
||||
1. **多通道支持**:支持多通道PWM输出
|
||||
2. **频率可调**:支持动态频率和占空比调整
|
||||
3. **死区控制**:支持死区时间配置(对于电机控制)
|
||||
4. **同步输出**:支持多通道同步输出
|
||||
|
||||
### 驱动配置管理
|
||||
|
||||
1. **配置分离**:驱动配置与实现代码分离
|
||||
2. **默认配置**:提供合理的默认配置值
|
||||
3. **运行时配置**:支持运行时动态配置
|
||||
4. **配置验证**:配置参数合法性验证
|
||||
|
||||
### 代码质量要求
|
||||
|
||||
1. **注释规范**:所有关键函数必须有中文注释
|
||||
2. **错误处理**:全面的错误检查和返回
|
||||
3. **资源管理**:正确的资源申请和释放
|
||||
4. **线程安全**:考虑多任务环境下的线程安全性
|
||||
5. **性能优化**:关键路径代码性能优化
|
||||
|
||||
## 测试与验证配置
|
||||
|
||||
### 测试文件组织
|
||||
|
||||
1. **测试目录结构**:所有测试文件必须放在`tests/`目录下
|
||||
2. **命名规范**:测试文件必须以`test_`开头,如`test_uart.c`、`test_servo.c`
|
||||
3. **测试分类**:
|
||||
- 单元测试:测试单个函数或模块
|
||||
- 集成测试:测试多个模块的协同工作
|
||||
- 系统测试:测试整个系统功能
|
||||
4. **测试覆盖率**:关键模块测试覆盖率应达到80%以上
|
||||
|
||||
### 单元测试要求
|
||||
|
||||
1. **测试框架**:使用Ceedling或类似框架进行单元测试
|
||||
2. **测试用例**:每个关键函数必须有对应的测试用例
|
||||
3. **边界测试**:必须测试边界条件和异常情况
|
||||
4. **Mock对象**:使用Mock对象模拟硬件依赖
|
||||
5. **测试报告**:生成详细的测试报告和覆盖率报告
|
||||
|
||||
### 集成测试要求
|
||||
|
||||
1. **模块组合测试**:测试多个驱动模块的协同工作
|
||||
2. **协议通信测试**:测试完整的协议通信流程
|
||||
3. **硬件接口测试**:测试与真实硬件的接口(如有条件)
|
||||
4. **性能测试**:测试系统性能指标(响应时间、吞吐量等)
|
||||
|
||||
### 编译验证要求
|
||||
|
||||
1. **编译成功**:工程必须能够成功编译,生成可执行文件
|
||||
2. **零警告**:编译时应尽可能消除所有警告(特殊警告除外)
|
||||
3. **代码规范检查**:使用静态代码分析工具检查代码规范
|
||||
4. **内存检查**:检查内存泄漏和缓冲区溢出问题
|
||||
|
||||
### 功能验证要求
|
||||
|
||||
1. **基本功能验证**:验证所有驱动的基本功能正常工作
|
||||
2. **协议验证**:验证通讯协议的正确性和可靠性
|
||||
3. **性能验证**:验证系统性能满足设计要求
|
||||
4. **稳定性验证**:长时间运行测试,验证系统稳定性
|
||||
|
||||
### 自动化测试流程
|
||||
|
||||
必须建立自动化测试流程,包括以下步骤:
|
||||
|
||||
1. **代码编译**:自动编译工程,检查编译错误
|
||||
2. **单元测试**:自动运行所有单元测试
|
||||
3. **集成测试**:自动运行集成测试
|
||||
4. **静态分析**:自动运行静态代码分析
|
||||
5. **测试报告**:自动生成测试报告
|
||||
|
||||
### 测试用例示例
|
||||
|
||||
```c
|
||||
// UART驱动测试用例示例
|
||||
void test_uart_init(void) {
|
||||
ret_code_t ret = uart_init();
|
||||
TEST_ASSERT_EQUAL(RET_OK, ret);
|
||||
}
|
||||
|
||||
void test_uart_receive_fifo(void) {
|
||||
// 测试FIFO缓冲区功能
|
||||
uint8_t test_data[] = {0xEB, 0x90, 0x0A, 0x01, 0x02, 0xAA, 0xBB, 0x3C};
|
||||
|
||||
// 模拟接收数据
|
||||
for (int i = 0; i < sizeof(test_data); i++) {
|
||||
uart_fifo_write(test_data[i]);
|
||||
}
|
||||
|
||||
// 验证数据读取
|
||||
for (int i = 0; i < sizeof(test_data); i++) {
|
||||
uint8_t data;
|
||||
bool success = uart_fifo_read(&data);
|
||||
TEST_ASSERT_TRUE(success);
|
||||
TEST_ASSERT_EQUAL(test_data[i], data);
|
||||
}
|
||||
}
|
||||
|
||||
// 伺服协议测试用例示例
|
||||
void test_servo_protocol_frame(void) {
|
||||
servo_protocol_frame_t frame;
|
||||
ret_code_t ret = servo_build_angle_ctrl_frame(1, 45.0f, 44.5f, &frame);
|
||||
TEST_ASSERT_EQUAL(RET_OK, ret);
|
||||
TEST_ASSERT_EQUAL(0xEB, frame.header_high);
|
||||
TEST_ASSERT_EQUAL(0x90, frame.header_low);
|
||||
TEST_ASSERT_EQUAL(0x0B, frame.device_id);
|
||||
}
|
||||
```
|
||||
|
||||
### 验证通过标准
|
||||
|
||||
工程必须满足以下标准才能视为验证通过:
|
||||
|
||||
1. **编译通过**:无编译错误,警告控制在合理范围内
|
||||
2. **测试通过**:所有单元测试和集成测试通过
|
||||
3. **功能正常**:基本功能验证通过
|
||||
4. **性能达标**:性能指标满足设计要求
|
||||
5. **文档完整**:所有文档和注释完整准确
|
||||
|
||||
## 配置文件
|
||||
|
||||
1. 系统配置文件在CONFIG目录下的config.h文件中
|
||||
2. 系统配置文件中包含了系统参数的定义,如时钟频率、外设时钟频率等
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
# 单片机配置
|
||||
|
||||
PY32MD530H28U7TR
|
||||
|
||||
|
||||
|
||||
## 引脚配置表
|
||||
|
||||
|
||||
|
||||
| 引脚 | 功能 | 备注 |
|
||||
|
||||
|------|---- |---- |
|
||||
|
||||
| PA7 | LO1 | ͨ通道1低侧栅极驱动器输出 |
|
||||
|
||||
| PB0 | LO2 | ͨ通道2低侧栅极驱动器输出 |
|
||||
|
||||
| PB1 | LO3 | ͨ通道3低侧栅极驱动器输出 |
|
||||
|
||||
| PF3 | HO1 | ͨ通道1高侧栅极驱动器输出 |
|
||||
|
||||
| PF1 | HO2 | ͨ通道2高侧栅极驱动器输出 |
|
||||
|
||||
| PF0 | HO3 | ͨ通道3高侧栅极驱动器输出 |
|
||||
|
||||
| PA13 | SWDIO | ͨ调试数据引脚 |
|
||||
|
||||
| PA14 | SWCLK | ͨ调试时钟引脚 |
|
||||
|
||||
| PA9 | USART1_TXD | ͨUSART1发送引脚 |
|
||||
|
||||
| PA10 | USART1_RXD | ͨUSART1接收引脚 |
|
||||
|
||||
| PA3 | USART1_CTL | ͨUSART1控制引脚(RS485读、写) |
|
||||
|
||||
| PA0 | UART1_TX | ͨUART1发送引脚 |
|
||||
|
||||
| PA1 | UART1_RXD | ͨUART1接收引脚 |
|
||||
|
||||
| PA4 | LPUART1_TX | ͨLPUART1发送引脚 |
|
||||
|
||||
| PA2 | LPUART1_RXD | ͨLPUART1接收引脚 |
|
||||
|
||||
| PA12 | I2C_SDA | ͨI2C数据引脚 |
|
||||
|
||||
| PA11 | I2C_SCL | ͨI2C时钟引脚 |
|
||||
|
||||
| PA8 | DI_MAX | ͨ数字输入最大端点 |
|
||||
@@ -0,0 +1,157 @@
|
||||
# 指令说明
|
||||
|
||||
## Modbus 通讯参数
|
||||
|
||||
| 参数 | 值 |
|
||||
|------|-----|
|
||||
| 物理层 | RS485 半双工 |
|
||||
| 串口 | UART1 (USART1) |
|
||||
| 波特率 | 115200 |
|
||||
| 数据位 | 8 |
|
||||
| 校验位 | 无 |
|
||||
| 停止位 | 1 |
|
||||
| 主站地址 | `0xFE` |
|
||||
| 从站地址 | `0x40 + ID`,ID 由 4 个 GPIO 引脚组合(范围 0~15),见 ID 指示器定义 |
|
||||
| 协议 | Modbus RTU |
|
||||
|
||||
## Modbus 功能码
|
||||
|
||||
| 功能 | 码值 | 说明 |
|
||||
|------|------|------|
|
||||
| 读保持寄存器 | `0x03` | 读取 1~125 个连续寄存器 |
|
||||
| 写单个寄存器 | `0x06` | 写入 1 个寄存器 |
|
||||
|
||||
## 寄存器映射
|
||||
|
||||
| 地址 | 名称 | 读写 | 数据类型 | 说明 |
|
||||
|------|------|------|----------|------|
|
||||
| `0x0000` | MOTOR_CURRENT | R | uint16 | 电机电流值 |
|
||||
| `0x0001` | MOTOR_POSITION | R | int16 | 当前位置(步数) |
|
||||
| `0x0002` | MOTOR_TARGET | R/W | int16 | 目标位置(步数) |
|
||||
| `0x0003` | MOTOR_SPEED | R | uint16 | 当前速度 |
|
||||
| `0x0004` | MOTOR_STATE | R | uint16 | 步进电机状态(0=空闲,1=加速,2=匀速,3=减速,4=停止,5=标定中) |
|
||||
| `0x0005` | AS5600_ANGLE | R | uint16 | AS5600 角度值(0.1°精度,0~3599) |
|
||||
| `0x0006` | AS5600_RAW | R | uint16 | AS5600 原始值 |
|
||||
| `0x0007` | DI_MAX_STATE | R | uint16 | 最大值到位开关(0=未触发,1=触发) |
|
||||
| `0x0008` | DI_MIN_STATE | R | uint16 | 最小值到位开关(0=未触发,1=触发) |
|
||||
| `0x0009` | CALIBRATED_STEPS | R | uint16 | 标定的总步数 |
|
||||
| `0x000A` | ORIGIN_STEPS | R | int16 | 原点步数(最小值位置) |
|
||||
| `0x000B` | MAX_STEPS | R | int16 | 最大步数(最大值位置) |
|
||||
| `0x000C` | IS_CALIBRATED | R | uint16 | 是否已标定(0=未标定,1=已标定) |
|
||||
| `0x000D` | IS_DI_MAX_INSTALLED | R | uint16 | DI_MAX 是否安装(0=未安装,1=已安装) |
|
||||
| `0x000E` | MODBUS_SLAVE_ADDR | R | uint16 | 当前 Modbus 从站地址(如 0x40~0x4F) |
|
||||
| `0x000F` | DEVICE_ID | R | uint16 | 设备 ID(0~15) |
|
||||
| `0x0020` | MOTOR_POSITION_H | R | int16 | 当前位置高 16 位 |
|
||||
| `0x0021` | MOTOR_TARGET_H | R/W | int16 | 目标位置高 16 位 |
|
||||
| `0x0022` | CALIBRATED_STEPS_H | R | uint16 | 标定总步数高 16 位 |
|
||||
| `0x0023` | ORIGIN_STEPS_H | R | int16 | 原点步数高 16 位 |
|
||||
| `0x0024` | MAX_STEPS_H | R | int16 | 最大步数高 16 位 |
|
||||
| `0x0042` | CMD | W | uint16 | 指令寄存器(写入指令码触发动作) |
|
||||
| `0x0043` | STATUS | R | uint16 | 整机状态(读寄存器) |
|
||||
| `0x0044` | ANGLE_TARGET | R/W | uint16 | 角度目标值(单位 0.1°,范围 0~3600) |
|
||||
|
||||
注:32 位数据(如位置、步数)拆分到两个 16 位寄存器中:
|
||||
- 低 16 位在主地址(如 `0x0001`)
|
||||
- 高 16 位在主地址 + 0x0020(如 `0x0021`)
|
||||
- 读写时需分别操作两个寄存器。
|
||||
|
||||
## 指令码(CMD 寄存器 0x0042)
|
||||
|
||||
写入 `0x0042` 寄存器触发动作,写完后硬件自动清零:
|
||||
|
||||
| 指令码 | 名称 | 说明 |
|
||||
|--------|------|------|
|
||||
| `0x0001` | GO_MAX | 运行到最大值位置 |
|
||||
| `0x0002` | GO_MIN | 运行到最小值位置(原点) |
|
||||
| `0x0003` | STOP | 立即停止运行 |
|
||||
| `0x0004` | GO_POSITION | 运行到指定步数(需先写入 MOTOR_TARGET) |
|
||||
| `0x0005` | GO_ANGLE | 运行到指定角度(需先写入 ANGLE_TARGET) |
|
||||
| `0x0006` | CALIBRATE | 开始标定 |
|
||||
| `0x0007` | CALIB_END | 结束标定 |
|
||||
| `0x0008` | READ_STATUS | 读取当前状态(读 STATUS 寄存器即可) |
|
||||
|
||||
## 整机状态(STATUS 寄存器 0x0043)
|
||||
|
||||
读取 `0x0043` 寄存器获取整机运行状态:
|
||||
|
||||
| 状态码 | 名称 | 说明 |
|
||||
|--------|------|------|
|
||||
| `0x0000` | IDLE | 待机模式,等待指令 |
|
||||
| `0x0001` | RUNNING | 正在运行(移动到目标位置中) |
|
||||
| `0x0002` | CALIB | 正在标定 |
|
||||
| `0x0003` | STOPPED | 已停止(执行停止指令后) |
|
||||
| `0x0004` | ERROR | 错误状态 |
|
||||
|
||||
## 通信示例
|
||||
|
||||
### 读当前位置
|
||||
```
|
||||
请求: FE 03 00 01 00 01 CRC_LO CRC_HI
|
||||
响应: 40+ID 03 02 POS_HI POS_LO CRC_LO CRC_HI
|
||||
```
|
||||
|
||||
### 读整机状态
|
||||
```
|
||||
请求: FE 03 00 43 00 01 CRC_LO CRC_HI
|
||||
响应: 40+ID 03 02 00 01 CRC_LO CRC_HI <- 状态 = RUNNING
|
||||
```
|
||||
|
||||
### 运行到最大值
|
||||
```
|
||||
请求: FE 06 00 42 00 01 CRC_LO CRC_HI
|
||||
响应: 40+ID 06 00 42 00 01 CRC_LO CRC_HI
|
||||
```
|
||||
|
||||
### 运行到指定步数(1000 步)
|
||||
```
|
||||
请求: FE 06 00 02 03 E8 CRC_LO CRC_HI <- 写 MOTOR_TARGET = 1000
|
||||
响应: 40+ID 06 00 02 03 E8 CRC_LO CRC_HI
|
||||
请求: FE 06 00 42 00 04 CRC_LO CRC_HI <- 写 CMD = GO_POSITION
|
||||
响应: 40+ID 06 00 42 00 04 CRC_LO CRC_HI
|
||||
```
|
||||
|
||||
### 运行到指定角度(45.0°)
|
||||
```
|
||||
请求: FE 06 00 44 01 C2 CRC_LO CRC_HI <- 写 ANGLE_TARGET = 450(45.0°)
|
||||
响应: 40+ID 06 00 44 01 C2 CRC_LO CRC_HI
|
||||
请求: FE 06 00 42 00 05 CRC_LO CRC_HI <- 写 CMD = GO_ANGLE
|
||||
响应: 40+ID 06 00 42 00 05 CRC_LO CRC_HI
|
||||
```
|
||||
|
||||
### 读取多个寄存器(当前位置+速度+状态)
|
||||
```
|
||||
请求: FE 03 00 01 00 04 CRC_LO CRC_HI
|
||||
响应: 40+ID 03 08 POS_HI POS_LO TGT_HI TGT_LO SPD_HI SPD_LO STA_HI STA_LO CRC_LO CRC_HI
|
||||
```
|
||||
|
||||
### 标定流程
|
||||
```
|
||||
请求: FE 06 00 42 00 06 CRC_LO CRC_HI <- 开始标定
|
||||
响应: 40+ID 06 00 42 00 06 CRC_LO CRC_HI
|
||||
(标定执行中...)
|
||||
请求: FE 03 00 43 00 01 CRC_LO CRC_HI <- 查询状态
|
||||
响应: 40+ID 03 02 00 02 CRC_LO CRC_HI <- 状态 = CALIB
|
||||
...
|
||||
请求: FE 06 00 42 00 07 CRC_LO CRC_HI <- 结束标定
|
||||
响应: 40+ID 06 00 42 00 07 CRC_LO CRC_HI
|
||||
```
|
||||
|
||||
### 停止运行
|
||||
```
|
||||
请求: FE 06 00 42 00 03 CRC_LO CRC_HI
|
||||
响应: 40+ID 06 00 42 00 03 CRC_LO CRC_HI
|
||||
```
|
||||
|
||||
## 从站地址计算
|
||||
|
||||
设备 ID 由 4 个 GPIO 引脚 (PB5~PB8) 读取:
|
||||
|
||||
| PB8 | PB7 | PB6 | PB5 | ID | 从站地址 |
|
||||
|-----|-----|-----|-----|----|----------|
|
||||
| 0 | 0 | 0 | 0 | 0 | `0x40` |
|
||||
| 0 | 0 | 0 | 1 | 1 | `0x41` |
|
||||
| 0 | 0 | 1 | 0 | 2 | `0x42` |
|
||||
| ... | ... | ... | ... | ... | ... |
|
||||
| 1 | 1 | 1 | 1 | 15 | `0x4F` |
|
||||
|
||||
从站地址计算公式:`0x40 + ID`
|
||||
@@ -0,0 +1,68 @@
|
||||
# 功能描述
|
||||
|
||||
此文件用于描述每个设备功能以及运行逻辑
|
||||
|
||||
|
||||
|
||||
## DEBUG串口
|
||||
|
||||
使用的是UART1,波特率为115200,数据位8位,无校验位,1个停止位
|
||||
|
||||
使用printf进行打印,需要构建一个log功能,格式如下:
|
||||
|
||||
```
|
||||
|
||||
log_out("DEBUG: %s\n", "hello world");
|
||||
|
||||
log_out("INFO: %d\n", 123);
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 2相四线步进电机驱动
|
||||
|
||||
使用的是TIM1,
|
||||
|
||||
|
||||
|
||||
### 正常运行功能
|
||||
|
||||
步进电机驱动使用S型加减速算法,根据DI_MIN和DI_MAX两个输入,根据当前位置和目标位置计算出步数,然后根据步数进行步进电机的运行。
|
||||
|
||||
如果DI_MAX不装配,那么使用原点开关和标定的步数进行计算导轨长度,到达最大值时,必须停止。
|
||||
|
||||
|
||||
|
||||
### 标定功能
|
||||
|
||||
使用标定功能时,如果最小和最大开关安装,那么运行到最小和最大开关触发,几下运行步数,如果DI_MAX不安装,那么根据原点开关和标定的步数来标定最大值。标定值认为输入。
|
||||
|
||||
|
||||
|
||||
## LED驱动
|
||||
|
||||
使用高低电平控制LED亮灭,高电平LED灭,低电平亮
|
||||
|
||||
|
||||
|
||||
## RS485串口接口
|
||||
|
||||
使用UART1,波特率为115200,数据位8位,无校验位,1个停止位
|
||||
|
||||
使用modbus协议,从站地址为0x40+ID,ID为读取四个ID引脚组成的值,每个ID引脚为0或1,组成一个8位的值。主站地址为0xfe。
|
||||
|
||||
|
||||
|
||||
一个共有这几个指令,去到最大值,去到最小值,停止运行,去到指令步数,去到指定角度,开始标定,结束标定
|
||||
|
||||
|
||||
|
||||
## ID指示器
|
||||
|
||||
使用的是GPIO引脚,根据ID引脚的值,来组合成当前的ID。
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,633 @@
|
||||
***
|
||||
name: "download-lib"
|
||||
description: "下载嵌入式开发所需的库文件(STM32/GD32/CH32等)。在创建新工程、更新库版本、切换芯片平台或需要确保团队库版本一致时调用此技能。"
|
||||
version: 1.1.0
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# DOWNLOAD-LIB 技能
|
||||
|
||||
该技能用于自动化下载嵌入式开发所需的硬件库文件,支持多种微控制器平台,并提供完整的工程集成方案。
|
||||
|
||||
## 技能概述
|
||||
|
||||
`download-lib` 技能是一个嵌入式开发辅助工具,专门用于管理和下载微控制器硬件外设库。它解决了嵌入式开发中常见的库文件管理问题:
|
||||
- 不同芯片平台的库文件获取
|
||||
- 库版本管理和一致性
|
||||
- 工程集成自动化
|
||||
- 团队协作中的库同步
|
||||
|
||||
## 功能特点
|
||||
|
||||
### 支持的平台
|
||||
- **STM32系列**:STM32F0/F1/F2/F3/F4/F7/H7等全系列
|
||||
- **GD32系列**:GD32F1/F2/F3/F4/F5等全系列
|
||||
- **CH32系列**:CH32V/V3/F1/F2等全系列
|
||||
- **其他ARM Cortex-M系列MCU**
|
||||
|
||||
### 核心功能
|
||||
1. **智能下载**:自动识别芯片型号并下载对应的库文件
|
||||
2. **版本管理**:支持特定版本、最新版本和版本锁定
|
||||
3. **完整性校验**:下载后验证文件完整性(MD5/SHA256)
|
||||
4. **工程集成**:自动更新构建系统(CMake/Makefile)
|
||||
5. **离线支持**:支持本地缓存和离线安装模式
|
||||
|
||||
## 调用时机
|
||||
|
||||
在以下情况下调用此技能:
|
||||
|
||||
### 1. 新工程创建
|
||||
- 创建基于STM32/GD32/CH32的新嵌入式项目时
|
||||
- 需要快速建立工程框架和依赖库时
|
||||
|
||||
### 2. 库版本更新
|
||||
- 需要更新现有工程的外设库到新版本时
|
||||
- 修复已知bug或使用新特性时
|
||||
|
||||
### 3. 平台迁移
|
||||
- 项目从一种MCU迁移到另一种MCU时
|
||||
- 需要同时支持多种芯片平台时
|
||||
|
||||
### 4. 团队协作
|
||||
- 确保团队成员使用相同的库版本时
|
||||
- 新成员快速搭建开发环境时
|
||||
|
||||
### 5. 离线开发准备
|
||||
- 准备离线开发环境,预先下载所有依赖库
|
||||
- 为无网络环境准备开发包时
|
||||
|
||||
## 工作流程
|
||||
|
||||
### 完整工作流程
|
||||
```mermaid
|
||||
graph TD
|
||||
A[用户请求下载库文件] --> B{芯片类型选择}
|
||||
B --> C[STM32]
|
||||
B --> D[GD32]
|
||||
B --> E[CH32]
|
||||
C --> F[选择具体系列]
|
||||
D --> F
|
||||
E --> F
|
||||
F --> G[选择版本号]
|
||||
G --> H[选择下载源]
|
||||
H --> I[执行下载]
|
||||
I --> J[完整性校验]
|
||||
J --> K[工程集成]
|
||||
K --> L[生成报告]
|
||||
L --> M[完成]
|
||||
```
|
||||
|
||||
### 详细步骤
|
||||
|
||||
#### 步骤1:参数收集
|
||||
1. **芯片类型**:用户选择目标芯片平台(STM32/GD32/CH32)
|
||||
2. **芯片系列**:指定具体芯片系列(如GD32F450、STM32F407等)
|
||||
3. **库版本**:选择库版本号(如v1.0.0、latest等)
|
||||
4. **下载源**:选择下载来源(官方GitHub、厂商网站、镜像站等)
|
||||
5. **目标目录**:指定库文件存放位置(默认:`项目根目录/libs/`)
|
||||
|
||||
#### 步骤2:库文件下载
|
||||
1. **源地址解析**:根据芯片类型和版本构建下载URL
|
||||
- STM32:`https://github.com/STMicroelectronics/STM32CubeF4`
|
||||
- GD32:`https://github.com/GigaDevice/GD32F4xx_Standard_Peripheral_Lib`
|
||||
- CH32:`https://github.com/openwch/ch32`(示例)
|
||||
2. **下载方式**:
|
||||
- Git clone(推荐,支持版本管理)
|
||||
- 直接下载ZIP包
|
||||
- 使用wget/curl命令行工具
|
||||
3. **进度显示**:实时显示下载进度和状态
|
||||
|
||||
#### 步骤3:文件处理
|
||||
1. **解压与整理**:如有需要,解压文件并整理目录结构
|
||||
2. **文件筛选**:只保留必要的库文件,移除示例、文档等非必需文件
|
||||
3. **目录规范化**:按照标准目录结构组织文件
|
||||
```
|
||||
libs/
|
||||
├── CMSIS/ # ARM CMSIS核心库
|
||||
├── thirdparty/
|
||||
│ └── GD32F4xx/ # 具体芯片的外设库
|
||||
│ ├── Include/
|
||||
│ ├── Source/
|
||||
│ └── README.md
|
||||
└── version.txt # 版本信息文件
|
||||
```
|
||||
|
||||
#### 步骤4:完整性校验
|
||||
1. **哈希校验**:计算下载文件的MD5或SHA256值
|
||||
2. **大小验证**:检查文件大小是否符合预期
|
||||
3. **结构验证**:验证目录结构是否完整
|
||||
4. **关键文件检查**:确保核心头文件和源文件存在
|
||||
|
||||
#### 步骤5:工程集成
|
||||
1. **构建系统更新**:
|
||||
- **CMake**:更新`CMakeLists.txt`,添加库文件路径
|
||||
- **Makefile**:更新编译规则和包含路径
|
||||
- **Keil/IAR**:生成对应的工程文件(可选)
|
||||
2. **头文件路径配置**:自动添加必要的头文件搜索路径
|
||||
3. **依赖关系配置**:设置库文件之间的依赖关系
|
||||
|
||||
#### 步骤6:报告生成
|
||||
1. **下载摘要**:显示下载的文件数量、大小和时间
|
||||
2. **版本信息**:记录下载的库版本和芯片信息
|
||||
3. **集成状态**:显示工程集成是否成功
|
||||
4. **问题提示**:如有问题,提供解决方案建议
|
||||
|
||||
## 参数定义
|
||||
|
||||
### 输入参数
|
||||
```yaml
|
||||
# 必选参数
|
||||
chip_type: # 芯片类型
|
||||
type: enum
|
||||
values: [stm32, gd32, ch32, other]
|
||||
required: true
|
||||
|
||||
chip_series: # 芯片系列
|
||||
type: string
|
||||
examples: ["GD32F450", "STM32F407", "CH32V307"]
|
||||
required: true
|
||||
|
||||
# 可选参数
|
||||
library_version: # 库版本
|
||||
type: string
|
||||
default: "latest"
|
||||
examples: ["v1.0.0", "v2.1.3", "latest"]
|
||||
|
||||
download_source: # 下载源
|
||||
type: enum
|
||||
values: [github, official, custom]
|
||||
default: "github"
|
||||
|
||||
target_directory: # 目标目录
|
||||
type: string
|
||||
default: "./libs/"
|
||||
|
||||
skip_integration: # 跳过工程集成
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
offline_mode: # 离线模式
|
||||
type: boolean
|
||||
default: false
|
||||
description: "从本地缓存安装,无需网络"
|
||||
```
|
||||
|
||||
### 输出结果
|
||||
```yaml
|
||||
success: true/false
|
||||
message: "操作结果描述"
|
||||
downloaded_files:
|
||||
count: 42
|
||||
total_size: "15.7MB"
|
||||
duration: "45秒"
|
||||
library_info:
|
||||
name: "GD32F4xx Standard Peripheral Library"
|
||||
version: "v1.0.0"
|
||||
chip: "GD32F450VG"
|
||||
release_date: "2023-06-15"
|
||||
integration_status:
|
||||
cmake_updated: true
|
||||
include_paths_added: ["libs/thirdparty/GD32F4xx/Include"]
|
||||
source_files_added: ["libs/thirdparty/GD32F4xx/Source/*.c"]
|
||||
```
|
||||
|
||||
## 示例和模板
|
||||
|
||||
### 示例1:下载GD32F4xx库
|
||||
```bash
|
||||
# 通过技能调用下载GD32F4xx最新版本
|
||||
download-lib --chip-type gd32 --chip-series GD32F450 --version latest
|
||||
```
|
||||
|
||||
**执行结果**:
|
||||
```
|
||||
✅ 开始下载GD32F4xx库...
|
||||
📦 下载源:https://github.com/GigaDevice/GD32F4xx_Standard_Peripheral_Lib
|
||||
🔍 选择版本:latest (v1.0.0)
|
||||
⬇️ 下载中:15.7MB [██████████] 100%
|
||||
✅ 下载完成:42个文件,耗时45秒
|
||||
🔒 完整性校验:通过(SHA256匹配)
|
||||
📁 文件组织:libs/thirdparty/GD32F4xx/
|
||||
🛠️ 工程集成:CMakeLists.txt已更新
|
||||
📊 报告生成:download_report_20250409_142356.json
|
||||
🎉 完成!GD32F450库已就绪。
|
||||
```
|
||||
|
||||
### 示例2:下载特定版本的STM32库
|
||||
```bash
|
||||
# 下载STM32F4xx v1.27.0版本
|
||||
download-lib \
|
||||
--chip-type stm32 \
|
||||
--chip-series STM32F407 \
|
||||
--version v1.27.0 \
|
||||
--target-directory ./vendor/stm32 \
|
||||
--skip-integration
|
||||
```
|
||||
|
||||
### 示例3:离线模式(从缓存安装)
|
||||
```bash
|
||||
# 从本地缓存安装,无需网络连接
|
||||
download-lib \
|
||||
--chip-type gd32 \
|
||||
--chip-series GD32F450 \
|
||||
--offline-mode \
|
||||
--cache-directory ~/.cache/embedded-libs
|
||||
```
|
||||
|
||||
### 模板1:Bash下载脚本
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# download_library.sh - 库文件下载脚本模板
|
||||
|
||||
set -e # 出错时退出
|
||||
|
||||
# 配置参数
|
||||
CHIP_TYPE=${1:-gd32}
|
||||
CHIP_SERIES=${2:-GD32F450}
|
||||
VERSION=${3:-latest}
|
||||
TARGET_DIR=${4:-./libs}
|
||||
CACHE_DIR="${HOME}/.cache/embedded-libs"
|
||||
|
||||
# 下载URL映射
|
||||
declare -A LIBRARY_URLS=(
|
||||
["gd32"]="https://github.com/GigaDevice/GD32F4xx_Standard_Peripheral_Lib"
|
||||
["stm32_f4"]="https://github.com/STMicroelectronics/STM32CubeF4"
|
||||
["ch32_v"]="https://github.com/openwch/ch32"
|
||||
)
|
||||
|
||||
# 获取下载URL
|
||||
get_download_url() {
|
||||
local chip=$1
|
||||
local series=$2
|
||||
|
||||
case $chip in
|
||||
"gd32")
|
||||
echo "${LIBRARY_URLS[gd32]}"
|
||||
;;
|
||||
"stm32")
|
||||
# 根据系列选择具体的STM32库
|
||||
if [[ $series == STM32F4* ]]; then
|
||||
echo "${LIBRARY_URLS[stm32_f4]}"
|
||||
else
|
||||
echo "错误:不支持的STM32系列: $series" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "错误:不支持的芯片类型: $chip" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
echo "🔍 芯片: $CHIP_TYPE $CHIP_SERIES"
|
||||
echo "📦 版本: $VERSION"
|
||||
|
||||
# 创建目标目录
|
||||
mkdir -p "$TARGET_DIR"
|
||||
|
||||
# 获取下载URL
|
||||
DOWNLOAD_URL=$(get_download_url "$CHIP_TYPE" "$CHIP_SERIES")
|
||||
echo "🌐 下载源: $DOWNLOAD_URL"
|
||||
|
||||
# 执行下载
|
||||
if [[ "$VERSION" == "latest" ]]; then
|
||||
git clone --depth 1 "$DOWNLOAD_URL" "${TARGET_DIR}/temp"
|
||||
else
|
||||
git clone --branch "$VERSION" --depth 1 "$DOWNLOAD_URL" "${TARGET_DIR}/temp"
|
||||
fi
|
||||
|
||||
# 整理文件
|
||||
organize_files
|
||||
|
||||
# 清理临时文件
|
||||
rm -rf "${TARGET_DIR}/temp"
|
||||
|
||||
echo "✅ 下载完成"
|
||||
}
|
||||
|
||||
# 文件整理函数
|
||||
organize_files() {
|
||||
local temp_dir="${TARGET_DIR}/temp"
|
||||
|
||||
# GD32库的特殊处理
|
||||
if [[ "$CHIP_TYPE" == "gd32" ]]; then
|
||||
# 复制必要的文件
|
||||
mkdir -p "${TARGET_DIR}/thirdparty/GD32F4xx"
|
||||
cp -r "${temp_dir}/Firmware/GD32F4xx_standard_peripheral/Include" \
|
||||
"${TARGET_DIR}/thirdparty/GD32F4xx/"
|
||||
cp -r "${temp_dir}/Firmware/GD32F4xx_standard_peripheral/Source" \
|
||||
"${TARGET_DIR}/thirdparty/GD32F4xx/"
|
||||
fi
|
||||
|
||||
# 添加其他芯片类型的处理逻辑...
|
||||
}
|
||||
|
||||
# 执行主函数
|
||||
main "$@"
|
||||
```
|
||||
|
||||
### 模板2:CMake集成配置
|
||||
```cmake
|
||||
# CMakeLists.txt - 库集成模板
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# 检测库文件是否存在
|
||||
macro(check_required_library lib_name lib_path)
|
||||
if(NOT EXISTS ${lib_path})
|
||||
message(WARNING "缺少库文件: ${lib_name}")
|
||||
message(STATUS "请运行: download-lib --chip-type gd32 --chip-series GD32F450")
|
||||
set(${lib_name}_FOUND FALSE)
|
||||
else()
|
||||
set(${lib_name}_FOUND TRUE)
|
||||
message(STATUS "找到库: ${lib_name}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# 检查GD32库
|
||||
check_required_library(GD32F4XX_LIB "${CMAKE_SOURCE_DIR}/libs/thirdparty/GD32F4xx")
|
||||
|
||||
if(GD32F4XX_LIB_FOUND)
|
||||
# 添加包含路径
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/libs/thirdparty/GD32F4xx/Include
|
||||
${CMAKE_SOURCE_DIR}/libs/CMSIS/Core/Include
|
||||
${CMAKE_SOURCE_DIR}/libs/CMSIS/GD/GD32F4xx/Include
|
||||
)
|
||||
|
||||
# 添加源文件
|
||||
file(GLOB GD32_SOURCES
|
||||
${CMAKE_SOURCE_DIR}/libs/thirdparty/GD32F4xx/Source/*.c
|
||||
)
|
||||
|
||||
# 添加到工程源文件列表
|
||||
list(APPEND PROJECT_SOURCES ${GD32_SOURCES})
|
||||
endif()
|
||||
|
||||
# 类似的,可以添加其他库的检查
|
||||
```
|
||||
|
||||
### 模板3:Python下载脚本
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
# download_lib.py - Python版本库下载器
|
||||
|
||||
import os
|
||||
import sys
|
||||
import requests
|
||||
import hashlib
|
||||
import zipfile
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
class LibraryDownloader:
|
||||
"""库文件下载器"""
|
||||
|
||||
def __init__(self, chip_type, chip_series, version="latest"):
|
||||
self.chip_type = chip_type
|
||||
self.chip_series = chip_series
|
||||
self.version = version
|
||||
self.base_urls = {
|
||||
"gd32": "https://api.github.com/repos/GigaDevice/GD32F4xx_Standard_Peripheral_Lib",
|
||||
"stm32": "https://api.github.com/repos/STMicroelectronics/STM32CubeF4",
|
||||
}
|
||||
|
||||
def download(self, target_dir="libs"):
|
||||
"""执行下载"""
|
||||
print(f"下载 {self.chip_type} {self.chip_series} 库...")
|
||||
|
||||
# 获取下载信息
|
||||
download_info = self.get_download_info()
|
||||
|
||||
# 创建目标目录
|
||||
target_path = Path(target_dir)
|
||||
target_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 下载文件
|
||||
self.download_file(download_info['url'], target_path)
|
||||
|
||||
# 验证完整性
|
||||
if self.verify_integrity(target_path, download_info.get('checksum')):
|
||||
print("✅ 完整性验证通过")
|
||||
else:
|
||||
print("⚠️ 完整性验证失败")
|
||||
|
||||
# 生成版本文件
|
||||
self.generate_version_file(target_path, download_info)
|
||||
|
||||
return True
|
||||
|
||||
def get_download_info(self):
|
||||
"""获取下载信息"""
|
||||
# 这里实现具体的API调用逻辑
|
||||
# 返回包含url、version、checksum等信息的字典
|
||||
pass
|
||||
|
||||
# 其他方法实现...
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 使用示例
|
||||
downloader = LibraryDownloader("gd32", "GD32F450", "latest")
|
||||
downloader.download()
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 常见错误及解决方案
|
||||
|
||||
#### 错误1:网络连接失败
|
||||
```
|
||||
❌ 错误:无法连接到下载服务器
|
||||
```
|
||||
**可能原因**:
|
||||
- 网络连接问题
|
||||
- 下载源URL变更
|
||||
- 防火墙或代理限制
|
||||
|
||||
**解决方案**:
|
||||
1. 检查网络连接
|
||||
2. 使用镜像源:`--download-source mirror`
|
||||
3. 离线模式:`--offline-mode --cache-dir /path/to/cache`
|
||||
4. 手动下载并指定本地路径
|
||||
|
||||
#### 错误2:版本不存在
|
||||
```
|
||||
❌ 错误:版本 v2.5.0 不存在
|
||||
```
|
||||
**可能原因**:
|
||||
- 版本号输入错误
|
||||
- 该版本已被删除
|
||||
- 芯片系列不支持该版本
|
||||
|
||||
**解决方案**:
|
||||
1. 查看可用版本:`download-lib --list-versions gd32 GD32F450`
|
||||
2. 使用最新版本:`--version latest`
|
||||
3. 指定正确的版本格式
|
||||
|
||||
#### 错误3:磁盘空间不足
|
||||
```
|
||||
❌ 错误:磁盘空间不足,需要 200MB,可用 50MB
|
||||
```
|
||||
**解决方案**:
|
||||
1. 清理磁盘空间
|
||||
2. 指定其他存储位置:`--target-directory /mnt/external/libs`
|
||||
3. 仅下载必要文件:`--minimal`(只下载核心库文件)
|
||||
|
||||
#### 错误4:权限不足
|
||||
```
|
||||
❌ 错误:无法创建目录 /usr/local/libs,权限被拒绝
|
||||
```
|
||||
**解决方案**:
|
||||
1. 使用用户目录:`--target-directory ~/projects/libs`
|
||||
2. 使用sudo权限(谨慎)
|
||||
3. 更改目录权限
|
||||
|
||||
### 错误恢复机制
|
||||
|
||||
#### 断点续传
|
||||
```bash
|
||||
# 支持断点续传
|
||||
download-lib --resume --partial-dir ./download-tmp
|
||||
```
|
||||
|
||||
#### 完整性恢复
|
||||
```bash
|
||||
# 如果下载中断,可以恢复完整性检查
|
||||
download-lib --verify-only --repair
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 版本锁定
|
||||
```bash
|
||||
# 在生产环境中使用固定版本
|
||||
download-lib --chip-type gd32 --chip-series GD32F450 --version v1.0.0
|
||||
```
|
||||
|
||||
### 2. 团队一致性
|
||||
```bash
|
||||
# 创建版本锁定文件
|
||||
download-lib --generate-lockfile > library-lock.json
|
||||
|
||||
# 其他成员使用锁文件恢复
|
||||
download-lib --from-lockfile library-lock.json
|
||||
```
|
||||
|
||||
### 3. CI/CD集成
|
||||
```yaml
|
||||
# .gitlab-ci.yml 示例
|
||||
stages:
|
||||
- setup
|
||||
|
||||
setup_libraries:
|
||||
stage: setup
|
||||
script:
|
||||
- download-lib --chip-type gd32 --chip-series GD32F450 --version latest
|
||||
- download-lib --chip-type stm32 --chip-series STM32F103 --version v1.8.0
|
||||
artifacts:
|
||||
paths:
|
||||
- libs/
|
||||
expire_in: 30 days
|
||||
```
|
||||
|
||||
### 4. 离线开发环境
|
||||
```bash
|
||||
# 在可联网环境中准备离线包
|
||||
download-lib --chip-type gd32 --chip-series GD32F450 --bundle --output gd32-bundle.tar.gz
|
||||
|
||||
# 在离线环境中安装
|
||||
download-lib --install-bundle gd32-bundle.tar.gz
|
||||
```
|
||||
|
||||
## 扩展功能
|
||||
|
||||
### 插件系统
|
||||
支持通过插件扩展新的芯片平台:
|
||||
|
||||
```bash
|
||||
# 注册新的芯片支持
|
||||
download-lib --register-chip \
|
||||
--name AT32 \
|
||||
--url-template "https://github.com/ArteryTek/AT32F4xx_Library" \
|
||||
--file-structure "Firmware/AT32F4xx_standard_peripheral"
|
||||
```
|
||||
|
||||
### 自定义下载源
|
||||
```bash
|
||||
# 使用自定义的下载源
|
||||
download-lib \
|
||||
--chip-type gd32 \
|
||||
--download-source custom \
|
||||
--custom-url "http://internal-mirror.company.com/gd32-libs"
|
||||
```
|
||||
|
||||
### 批量操作
|
||||
```bash
|
||||
# 批量下载多个库
|
||||
download-lib --batch libraries.json
|
||||
```
|
||||
|
||||
**libraries.json**:
|
||||
```json
|
||||
{
|
||||
"libraries": [
|
||||
{
|
||||
"chip_type": "gd32",
|
||||
"chip_series": "GD32F450",
|
||||
"version": "latest"
|
||||
},
|
||||
{
|
||||
"chip_type": "stm32",
|
||||
"chip_series": "STM32F103",
|
||||
"version": "v1.8.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 与当前工程的集成示例
|
||||
|
||||
### ServoTest工程集成
|
||||
对于您的`ServoTest`工程(基于GD32F450VG),技能可以:
|
||||
|
||||
1. **确保库版本一致**:
|
||||
```bash
|
||||
# 检查当前库版本
|
||||
download-lib --check-version --chip-type gd32 --chip-series GD32F450
|
||||
|
||||
# 更新到指定版本
|
||||
download-lib --chip-type gd32 --chip-series GD32F450 --version v1.0.0
|
||||
```
|
||||
|
||||
2. **多平台支持**:
|
||||
```bash
|
||||
# 如果需要支持STM32作为备选平台
|
||||
download-lib --chip-type stm32 --chip-series STM32F407 --target-directory ./libs/stm32-backup
|
||||
```
|
||||
|
||||
3. **依赖管理**:
|
||||
```bash
|
||||
# 生成依赖报告
|
||||
download-lib --dependencies --output deps.html
|
||||
```
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v1.1.0 (2024-04-09)
|
||||
- 完全重写技能文档
|
||||
- 添加详细的工作流程和参数定义
|
||||
- 提供多个示例脚本和模板
|
||||
- 完善错误处理和最佳实践
|
||||
- 添加与ServoTest工程的集成示例
|
||||
|
||||
### v1.0.0 (初始版本)
|
||||
- 基础技能框架
|
||||
- 支持STM32/GD32/CH32芯片
|
||||
- 基本的下载功能
|
||||
|
||||
---
|
||||
|
||||
**技能维护者**:嵌入式系统开发团队
|
||||
**最后更新**:2024-04-09
|
||||
**技能状态**:✅ 生产就绪
|
||||
@@ -0,0 +1,718 @@
|
||||
***
|
||||
|
||||
name: "download-tools"
|
||||
description: "嵌入式开发工具链下载和管理技能"
|
||||
version: "2.0.0"
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 嵌入式开发工具链下载和管理技能
|
||||
|
||||
## 概述
|
||||
|
||||
`download-tools` 技能是一个专业的嵌入式开发工具链管理工具,专门用于自动化下载、安装、配置和验证嵌入式开发所需的各种工具链。作为 OpenClaw 集成专家,我深知稳定可靠的开发环境对于嵌入式项目成功至关重要。本技能提供跨平台支持,确保开发工具的一致性和可重复性。
|
||||
|
||||
## 核心特性
|
||||
|
||||
### 1. 多平台支持
|
||||
- **Windows**: 支持原生 PowerShell、CMD 和 Git Bash
|
||||
- **Linux**: 支持 Ubuntu、Debian、Fedora、Arch 等主流发行版
|
||||
- **macOS**: 支持 Intel 和 Apple Silicon 架构
|
||||
|
||||
### 2. 工具链覆盖
|
||||
- **编译工具链**: ARM GCC、RISC-V GCC、Xtensa GCC、Clang
|
||||
- **调试工具**: J-Link、OpenOCD、ST-Link、pyOCD
|
||||
- **烧录工具**: esptool、STM32CubeProgrammer、GD32AllInOne
|
||||
- **串口工具**: minicom、screen、putty、serial terminal
|
||||
- **构建系统**: CMake、Make、Ninja、Meson
|
||||
- **开发环境**: Python 环境、VS Code 扩展、Eclipse 插件
|
||||
|
||||
### 3. 智能管理
|
||||
- **版本锁定**: 确保工具版本一致性
|
||||
- **依赖解析**: 自动处理工具依赖关系
|
||||
- **完整性校验**: 下载后验证工具完整性
|
||||
- **环境配置**: 自动配置 PATH 和环境变量
|
||||
- **离线支持**: 支持离线安装和本地缓存
|
||||
|
||||
## 工作流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始工具链管理] --> B{选择操作模式}
|
||||
B --> C[安装模式]
|
||||
B --> D[更新模式]
|
||||
B --> E[验证模式]
|
||||
B --> F[清理模式]
|
||||
|
||||
C --> C1[检查系统兼容性]
|
||||
C1 --> C2[解析工具依赖]
|
||||
C2 --> C3[下载工具文件]
|
||||
C3 --> C4[安装和配置]
|
||||
C4 --> C5[验证安装结果]
|
||||
C5 --> G[完成]
|
||||
|
||||
D --> D1[检查可用更新]
|
||||
D1 --> D2[备份当前版本]
|
||||
D2 --> D3[下载新版本]
|
||||
D3 --> D4[更新配置]
|
||||
D4 --> C5
|
||||
|
||||
E --> E1[检查工具状态]
|
||||
E1 --> E2[验证版本兼容性]
|
||||
E2 --> E3[测试基本功能]
|
||||
E3 --> E4[生成验证报告]
|
||||
E4 --> G
|
||||
|
||||
F --> F1[清理临时文件]
|
||||
F1 --> F2[卸载旧版本]
|
||||
F2 --> F3[恢复环境配置]
|
||||
F3 --> G
|
||||
```
|
||||
|
||||
## 参数定义
|
||||
|
||||
### YAML 配置格式
|
||||
|
||||
```yaml
|
||||
# tools-config.yaml
|
||||
version: "2.0.0"
|
||||
platform: "auto" # auto, windows, linux, macos
|
||||
|
||||
tools:
|
||||
# 编译工具链
|
||||
arm_gcc:
|
||||
enabled: true
|
||||
version: "12.3.rel1"
|
||||
variant: "arm-none-eabi"
|
||||
sources:
|
||||
windows: "https://developer.arm.com/-/media/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-mingw-w64-i686-arm-none-eabi.zip"
|
||||
linux: "https://developer.arm.com/-/media/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi.tar.xz"
|
||||
macos: "https://developer.arm.com/-/media/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-darwin-x86_64-arm-none-eabi.tar.xz"
|
||||
install_path: "${TOOLS_DIR}/gcc-arm"
|
||||
env_vars:
|
||||
PATH: "${install_path}/bin"
|
||||
ARM_GCC_PATH: "${install_path}"
|
||||
verification:
|
||||
command: "arm-none-eabi-gcc --version"
|
||||
expected_output: "12.3.1"
|
||||
|
||||
# 调试工具
|
||||
jlink:
|
||||
enabled: true
|
||||
version: "v7.96"
|
||||
sources:
|
||||
windows: "https://www.segger.com/downloads/jlink/JLink_Windows_V796.exe"
|
||||
linux: "https://www.segger.com/downloads/jlink/JLink_Linux_V796_x86_64.deb"
|
||||
macos: "https://www.segger.com/downloads/jlink/JLink_MacOSX_V796.pkg"
|
||||
install_path: "${TOOLS_DIR}/jlink"
|
||||
env_vars:
|
||||
PATH: "${install_path}"
|
||||
verification:
|
||||
command: "JLinkExe --version"
|
||||
|
||||
# 构建工具
|
||||
cmake:
|
||||
enabled: true
|
||||
version: "3.28.3"
|
||||
sources:
|
||||
windows: "https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-windows-x86_64.zip"
|
||||
linux: "https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-linux-x86_64.tar.gz"
|
||||
macos: "https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-macos-universal.tar.gz"
|
||||
install_path: "${TOOLS_DIR}/cmake"
|
||||
env_vars:
|
||||
PATH: "${install_path}/bin"
|
||||
|
||||
# Python 环境
|
||||
python:
|
||||
enabled: true
|
||||
version: "3.11.0"
|
||||
packages:
|
||||
- "pyserial==3.5"
|
||||
- "pyocd==0.36.0"
|
||||
- "esptool==4.6.2"
|
||||
- "cmsis-pack-manager==0.5.1"
|
||||
install_path: "${TOOLS_DIR}/python"
|
||||
env_vars:
|
||||
PATH: "${install_path}/Scripts:${install_path}/bin"
|
||||
PYTHONPATH: "${install_path}/Lib/site-packages"
|
||||
|
||||
# 配置选项
|
||||
config:
|
||||
download_timeout: 300 # 秒
|
||||
retry_count: 3
|
||||
verify_ssl: true
|
||||
offline_mode: false
|
||||
cache_dir: "${HOME}/.cache/embedded-tools"
|
||||
tools_dir: "${PROJECT_ROOT}/tools"
|
||||
|
||||
# 芯片特定配置
|
||||
chip_profiles:
|
||||
gd32:
|
||||
required_tools: ["arm_gcc", "cmake", "python"]
|
||||
recommended_tools: ["jlink", "openocd"]
|
||||
|
||||
stm32:
|
||||
required_tools: ["arm_gcc", "cmake", "python", "stlink"]
|
||||
recommended_tools: ["stm32cubeprogrammer"]
|
||||
|
||||
ch32:
|
||||
required_tools: ["riscv_gcc", "cmake", "python"]
|
||||
recommended_tools: ["wch-link", "openocd"]
|
||||
```
|
||||
|
||||
### 命令行参数
|
||||
|
||||
```bash
|
||||
# 基本用法
|
||||
download-tools --config tools-config.yaml
|
||||
download-tools --profile gd32 --install-path ./tools
|
||||
|
||||
# 特定操作
|
||||
download-tools --install arm_gcc cmake python
|
||||
download-tools --update --tools jlink openocd
|
||||
download-tools --verify --report-format json
|
||||
download-tools --clean --keep-versions 3
|
||||
|
||||
# 配置选项
|
||||
download-tools --offline --cache-dir ./local-cache
|
||||
download-tools --platform windows --arch x86_64
|
||||
download-tools --timeout 600 --retry 5
|
||||
|
||||
# 信息查询
|
||||
download-tools --list-available
|
||||
download-tools --check-updates
|
||||
download-tools --version-info
|
||||
```
|
||||
|
||||
## 工具配置详情
|
||||
|
||||
### 1. ARM GCC 工具链
|
||||
- **官方源**: Arm Developer 网站
|
||||
- **镜像源**: 清华大学 TUNA、中科大 USTC
|
||||
- **版本策略**: 支持 LTS 版本和最新版本
|
||||
- **架构支持**: arm-none-eabi、arm-eabi、aarch64-none-elf
|
||||
|
||||
### 2. J-Link 调试工具
|
||||
- **许可证管理**: 自动处理个人/商业许可证
|
||||
- **驱动安装**: 自动安装 USB 驱动程序
|
||||
- **配置生成**: 自动生成 J-Link 配置文件
|
||||
- **脚本支持**: 集成 J-Link 脚本功能
|
||||
|
||||
### 3. OpenOCD
|
||||
- **芯片支持**: STM32、GD32、ESP32、RISC-V
|
||||
- **接口支持**: J-Link、ST-Link、CMSIS-DAP、FTDI
|
||||
- **配置模板**: 预定义目标板配置文件
|
||||
- **服务管理**: 系统服务/守护进程配置
|
||||
|
||||
### 4. ST-Link
|
||||
- **工具集**: ST-Link CLI、ST-Link Server、STM32CubeProgrammer
|
||||
- **固件更新**: 自动检测和更新 ST-Link 固件
|
||||
- **多平台**: Windows、Linux、macOS 统一接口
|
||||
|
||||
### 5. Python 环境
|
||||
- **虚拟环境**: 自动创建隔离的 Python 环境
|
||||
- **包管理**: 自动安装嵌入式开发相关包
|
||||
- **路径隔离**: 避免与系统 Python 冲突
|
||||
- **版本兼容**: 确保与工具链的兼容性
|
||||
|
||||
## 平台特定实现
|
||||
|
||||
### Windows 实现
|
||||
```powershell
|
||||
# PowerShell 实现示例
|
||||
function Install-ArmGcc {
|
||||
param(
|
||||
[string]$Version = "12.3.rel1",
|
||||
[string]$InstallPath = "$env:USERPROFILE\.embedded-tools\gcc-arm"
|
||||
)
|
||||
|
||||
# 下载和安装逻辑
|
||||
$url = "https://developer.arm.com/-/media/Files/downloads/gnu/$Version/binrel/arm-gnu-toolchain-$Version-mingw-w64-i686-arm-none-eabi.zip"
|
||||
$tempFile = "$env:TEMP\arm-gcc-$Version.zip"
|
||||
|
||||
# 下载
|
||||
Invoke-WebRequest -Uri $url -OutFile $tempFile
|
||||
|
||||
# 解压
|
||||
Expand-Archive -Path $tempFile -DestinationPath $InstallPath -Force
|
||||
|
||||
# 环境配置
|
||||
$binPath = "$InstallPath\bin"
|
||||
$currentPath = [Environment]::GetEnvironmentVariable("PATH", "User")
|
||||
if ($currentPath -notlike "*$binPath*") {
|
||||
[Environment]::SetEnvironmentVariable("PATH", "$binPath;$currentPath", "User")
|
||||
}
|
||||
|
||||
# 验证
|
||||
& "$binPath\arm-none-eabi-gcc.exe" --version
|
||||
}
|
||||
```
|
||||
|
||||
### Linux 实现
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Bash 实现示例
|
||||
install_arm_gcc() {
|
||||
local version="${1:-12.3.rel1}"
|
||||
local install_path="${2:-$HOME/.embedded-tools/gcc-arm}"
|
||||
|
||||
# 检测架构
|
||||
local arch=$(uname -m)
|
||||
local url=""
|
||||
|
||||
case $arch in
|
||||
x86_64)
|
||||
url="https://developer.arm.com/-/media/Files/downloads/gnu/$version/binrel/arm-gnu-toolchain-$version-x86_64-arm-none-eabi.tar.xz"
|
||||
;;
|
||||
aarch64)
|
||||
url="https://developer.arm.com/-/media/Files/downloads/gnu/$version/binrel/arm-gnu-toolchain-$version-aarch64-arm-none-eabi.tar.xz"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported architecture: $arch"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# 下载和安装
|
||||
mkdir -p "$install_path"
|
||||
wget -q "$url" -O /tmp/arm-gcc.tar.xz
|
||||
tar -xf /tmp/arm-gcc.tar.xz -C "$install_path" --strip-components=1
|
||||
|
||||
# 环境配置
|
||||
echo "export PATH=\"$install_path/bin:\$PATH\"" >> ~/.bashrc
|
||||
echo "export ARM_GCC_PATH=\"$install_path\"" >> ~/.bashrc
|
||||
|
||||
# 验证
|
||||
"$install_path/bin/arm-none-eabi-gcc" --version
|
||||
}
|
||||
```
|
||||
|
||||
### macOS 实现
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# macOS 实现示例
|
||||
install_arm_gcc_macos() {
|
||||
local version="${1:-12.3.rel1}"
|
||||
local install_path="${2:-$HOME/Library/EmbeddedTools/gcc-arm}"
|
||||
|
||||
# 检测芯片架构
|
||||
local chip=$(uname -m)
|
||||
local url=""
|
||||
|
||||
if [[ "$chip" == "arm64" ]]; then
|
||||
url="https://developer.arm.com/-/media/Files/downloads/gnu/$version/binrel/arm-gnu-toolchain-$version-darwin-arm64-arm-none-eabi.tar.xz"
|
||||
else
|
||||
url="https://developer.arm.com/-/media/Files/downloads/gnu/$version/binrel/arm-gnu-toolchain-$version-darwin-x86_64-arm-none-eabi.tar.xz"
|
||||
fi
|
||||
|
||||
# 使用 Homebrew 风格安装
|
||||
mkdir -p "$install_path"
|
||||
curl -L "$url" | tar -xJ -C "$install_path" --strip-components=1
|
||||
|
||||
# 环境配置
|
||||
echo "export PATH=\"$install_path/bin:\$PATH\"" >> ~/.zshrc
|
||||
echo "export ARM_GCC_PATH=\"$install_path\"" >> ~/.zshrc
|
||||
|
||||
# 验证
|
||||
"$install_path/bin/arm-none-eabi-gcc" --version
|
||||
}
|
||||
```
|
||||
|
||||
## 安装验证
|
||||
|
||||
### 验证脚本示例
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
# verification.py
|
||||
import subprocess
|
||||
import sys
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
def verify_tool(tool_name, command, expected_output=None):
|
||||
print(f"验证工具: {tool_name}")
|
||||
print(f"命令: {command}")
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
command,
|
||||
shell=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"✓ {tool_name} 验证成功")
|
||||
|
||||
if expected_output:
|
||||
if expected_output in result.stdout:
|
||||
print(f"✓ 版本匹配: {expected_output}")
|
||||
else:
|
||||
print(f"✗ 版本不匹配")
|
||||
print(f" 期望: {expected_output}")
|
||||
print(f" 实际: {result.stdout[:100]}...")
|
||||
return False
|
||||
return True
|
||||
else:
|
||||
print(f"✗ {tool_name} 验证失败")
|
||||
print(f" 错误: {result.stderr}")
|
||||
return False
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
print(f"✗ {tool_name} 验证超时")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"✗ {tool_name} 验证异常: {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
verification_spec = {
|
||||
"arm_gcc": {
|
||||
"command": "arm-none-eabi-gcc --version",
|
||||
"expected": "12.3.1"
|
||||
},
|
||||
"cmake": {
|
||||
"command": "cmake --version",
|
||||
"expected": "3.28"
|
||||
},
|
||||
"python": {
|
||||
"command": "python --version",
|
||||
"expected": "Python 3.11"
|
||||
},
|
||||
"jlink": {
|
||||
"command": "JLinkExe --version",
|
||||
"expected": None # 不检查具体版本
|
||||
}
|
||||
}
|
||||
|
||||
results = {}
|
||||
for tool, spec in verification_spec.items():
|
||||
success = verify_tool(tool, spec["command"], spec.get("expected"))
|
||||
results[tool] = "PASS" if success else "FAIL"
|
||||
|
||||
# 生成报告
|
||||
report = {
|
||||
"timestamp": datetime.datetime.now().isoformat(),
|
||||
"platform": sys.platform,
|
||||
"results": results
|
||||
}
|
||||
|
||||
report_file = Path("tools_verification_report.json")
|
||||
with open(report_file, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
|
||||
print(f"\n验证报告已保存: {report_file}")
|
||||
|
||||
if all(status == "PASS" for status in results.values()):
|
||||
print("✅ 所有工具验证通过")
|
||||
return 0
|
||||
else:
|
||||
print("❌ 部分工具验证失败")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
import datetime
|
||||
sys.exit(main())
|
||||
```
|
||||
|
||||
## 错误处理和故障排除
|
||||
|
||||
### 常见错误及解决方案
|
||||
|
||||
#### 1. 下载失败
|
||||
```yaml
|
||||
错误: "下载超时或网络连接失败"
|
||||
解决方案:
|
||||
- 检查网络连接
|
||||
- 使用 --offline 模式(如果已有缓存)
|
||||
- 更换下载源(--source mirror)
|
||||
- 增加超时时间(--timeout 600)
|
||||
- 使用代理服务器
|
||||
```
|
||||
|
||||
#### 2. 安装权限问题
|
||||
```yaml
|
||||
错误: "权限被拒绝" 或 "需要管理员权限"
|
||||
解决方案:
|
||||
- Windows: 以管理员身份运行
|
||||
- Linux/macOS: 使用 sudo 或修改安装路径到用户目录
|
||||
- 使用 --install-path 指定用户可写目录
|
||||
```
|
||||
|
||||
#### 3. 版本兼容性问题
|
||||
```yaml
|
||||
错误: "工具版本不兼容"
|
||||
解决方案:
|
||||
- 使用 --version 指定兼容版本
|
||||
- 查看版本兼容性矩阵
|
||||
- 更新相关依赖工具
|
||||
- 使用虚拟环境隔离
|
||||
```
|
||||
|
||||
#### 4. 环境配置问题
|
||||
```yaml
|
||||
错误: "命令未找到" 或 "PATH 配置错误"
|
||||
解决方案:
|
||||
- 重新运行环境配置(--configure-env)
|
||||
- 手动添加工具路径到 PATH
|
||||
- 重启终端或 IDE
|
||||
- 检查 shell 配置文件(.bashrc, .zshrc)
|
||||
```
|
||||
|
||||
### 调试模式
|
||||
```bash
|
||||
# 启用详细日志
|
||||
download-tools --verbose --debug --log-file install.log
|
||||
|
||||
# 仅模拟运行
|
||||
download-tools --dry-run --config tools-config.yaml
|
||||
|
||||
# 生成诊断报告
|
||||
download-tools --diagnose --output diagnose.json
|
||||
```
|
||||
|
||||
## 集成示例
|
||||
|
||||
### 与 CMake 集成
|
||||
```cmake
|
||||
# CMakeLists.txt 中的工具检查
|
||||
find_program(ARM_GCC arm-none-eabi-gcc)
|
||||
if(NOT ARM_GCC)
|
||||
message(WARNING "ARM GCC 工具链未找到")
|
||||
message(STATUS "运行以下命令安装:")
|
||||
message(STATUS " download-tools --install arm_gcc")
|
||||
message(STATUS "或使用系统包管理器:")
|
||||
message(STATUS " # Ubuntu/Debian")
|
||||
message(STATUS " sudo apt-get install gcc-arm-none-eabi")
|
||||
message(STATUS " # macOS")
|
||||
message(STATUS " brew install arm-none-eabi-gcc")
|
||||
endif()
|
||||
|
||||
find_program(CMAKE_EXE cmake)
|
||||
if(NOT CMAKE_EXE)
|
||||
message(WARNING "CMake 未找到")
|
||||
message(STATUS "运行以下命令安装:")
|
||||
message(STATUS " download-tools --install cmake")
|
||||
endif()
|
||||
|
||||
# 自定义目标:安装开发工具
|
||||
add_custom_target(install-tools
|
||||
COMMAND download-tools --profile ${PROJECT_CHIP} --install-path ${CMAKE_SOURCE_DIR}/tools
|
||||
COMMENT "安装嵌入式开发工具链"
|
||||
)
|
||||
```
|
||||
|
||||
### 与 CI/CD 集成
|
||||
```yaml
|
||||
# .github/workflows/build.yml
|
||||
name: Embedded Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
setup-tools:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Embedded Tools
|
||||
run: |
|
||||
download-tools --profile stm32 \
|
||||
--install-path ./tools \
|
||||
--cache-dir ./cache \
|
||||
--no-interactive
|
||||
|
||||
- name: Verify Installation
|
||||
run: |
|
||||
download-tools --verify --report-format github
|
||||
|
||||
- name: Build Project
|
||||
run: |
|
||||
source ./tools/env.sh
|
||||
cmake -B build -S .
|
||||
cmake --build build
|
||||
|
||||
- name: Upload Tools Cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./cache
|
||||
key: ${{ runner.os }}-embedded-tools-${{ hashFiles('tools-config.yaml') }}
|
||||
```
|
||||
|
||||
### 与 VS Code 集成
|
||||
```json
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Install Development Tools",
|
||||
"type": "shell",
|
||||
"command": "download-tools",
|
||||
"args": [
|
||||
"--profile",
|
||||
"gd32",
|
||||
"--install-path",
|
||||
"${workspaceFolder}/.vscode/tools",
|
||||
"--quiet"
|
||||
],
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Setup Environment",
|
||||
"type": "shell",
|
||||
"command": "${workspaceFolder}/.vscode/tools/env.bat",
|
||||
"windows": {
|
||||
"command": "${workspaceFolder}/.vscode/tools/env.bat"
|
||||
},
|
||||
"linux": {
|
||||
"command": "source ${workspaceFolder}/.vscode/tools/env.sh"
|
||||
},
|
||||
"macos": {
|
||||
"command": "source ${workspaceFolder}/.vscode/tools/env.sh"
|
||||
}
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"terminal.integrated.env.windows": {
|
||||
"PATH": "${workspaceFolder}/.vscode/tools/gcc-arm/bin;${env:PATH}"
|
||||
},
|
||||
"terminal.integrated.env.linux": {
|
||||
"PATH": "${workspaceFolder}/.vscode/tools/gcc-arm/bin:${env:PATH}"
|
||||
},
|
||||
"terminal.integrated.env.osx": {
|
||||
"PATH": "${workspaceFolder}/.vscode/tools/gcc-arm/bin:${env:PATH}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 维护指南
|
||||
|
||||
### 版本管理策略
|
||||
1. **LTS 版本**: 生产环境使用长期支持版本
|
||||
2. **最新版本**: 开发环境可尝试最新功能
|
||||
3. **版本锁定**: 通过配置文件锁定特定版本
|
||||
4. **平滑升级**: 支持渐进式版本升级
|
||||
|
||||
### 配置文件更新
|
||||
```bash
|
||||
# 检查配置更新
|
||||
download-tools --check-config-updates
|
||||
|
||||
# 应用配置更新
|
||||
download-tools --update-config --backup
|
||||
|
||||
# 迁移旧配置
|
||||
download-tools --migrate-config --from-version 1.0.0
|
||||
```
|
||||
|
||||
### 缓存管理
|
||||
```bash
|
||||
# 清理缓存
|
||||
download-tools --clean-cache --keep-versions 3
|
||||
|
||||
# 导出缓存(用于离线安装)
|
||||
download-tools --export-cache ./offline-cache.tar.gz
|
||||
|
||||
# 导入缓存
|
||||
download-tools --import-cache ./offline-cache.tar.gz
|
||||
```
|
||||
|
||||
### 性能优化
|
||||
1. **并行下载**: 支持多工具并行下载
|
||||
2. **断点续传**: 支持下载中断后恢复
|
||||
3. **增量更新**: 仅下载变化的文件
|
||||
4. **本地镜像**: 支持搭建本地工具镜像服务器
|
||||
|
||||
## 安全考虑
|
||||
|
||||
### 安全最佳实践
|
||||
1. **完整性验证**: 所有下载文件必须进行 SHA256 校验
|
||||
2. **来源验证**: 优先使用官方源和可信镜像
|
||||
3. **权限最小化**: 工具安装使用最小必要权限
|
||||
4. **隔离运行**: 高风险工具在沙箱或容器中运行
|
||||
5. **审计日志**: 记录所有安装和配置操作
|
||||
|
||||
### 安全配置示例
|
||||
```yaml
|
||||
security:
|
||||
checksum_verification: true
|
||||
allowed_sources:
|
||||
- "https://developer.arm.com"
|
||||
- "https://github.com/Kitware/CMake/releases"
|
||||
- "https://www.segger.com/downloads/jlink"
|
||||
forbidden_sources:
|
||||
- "http://" # 禁止非加密连接
|
||||
require_signed: false # 未来可启用签名验证
|
||||
sandbox_mode: true # 在隔离环境中运行安装脚本
|
||||
```
|
||||
|
||||
## 扩展开发
|
||||
|
||||
### 添加新工具支持
|
||||
```python
|
||||
# 新工具插件示例
|
||||
from download_tools.core import ToolPlugin
|
||||
|
||||
class NewToolPlugin(ToolPlugin):
|
||||
name = "new_tool"
|
||||
description = "新工具支持插件"
|
||||
|
||||
def get_download_url(self, platform, version):
|
||||
# 返回平台特定的下载URL
|
||||
urls = {
|
||||
"windows": f"https://example.com/new-tool-{version}-windows.zip",
|
||||
"linux": f"https://example.com/new-tool-{version}-linux.tar.gz",
|
||||
"macos": f"https://example.com/new-tool-{version}-macos.pkg"
|
||||
}
|
||||
return urls.get(platform)
|
||||
|
||||
def install(self, install_path, downloaded_file):
|
||||
# 实现安装逻辑
|
||||
import shutil
|
||||
import zipfile
|
||||
|
||||
if downloaded_file.endswith('.zip'):
|
||||
with zipfile.ZipFile(downloaded_file, 'r') as zip_ref:
|
||||
zip_ref.extractall(install_path)
|
||||
elif downloaded_file.endswith('.tar.gz'):
|
||||
import tarfile
|
||||
with tarfile.open(downloaded_file, 'r:gz') as tar_ref:
|
||||
tar_ref.extractall(install_path)
|
||||
|
||||
# 设置执行权限(Linux/macOS)
|
||||
if platform.system() != "Windows":
|
||||
bin_file = os.path.join(install_path, "bin", "new-tool")
|
||||
os.chmod(bin_file, 0o755)
|
||||
|
||||
def verify(self, install_path):
|
||||
# 实现验证逻辑
|
||||
import subprocess
|
||||
result = subprocess.run(
|
||||
[os.path.join(install_path, "bin", "new-tool"), "--version"],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
return result.returncode == 0
|
||||
|
||||
# 注册插件
|
||||
ToolRegistry.register(NewToolPlugin())
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
`download-tools` 技能为嵌入式开发提供了一套完整的工具链管理解决方案。通过自动化工具下载、安装、配置和验证,显著提高了开发环境的搭建效率和一致性。无论是个人开发者还是团队协作,都能从中受益:
|
||||
|
||||
1. **一致性**: 确保团队成员使用相同的工具版本
|
||||
2. **可重复性**: 开发环境可以快速重建和复制
|
||||
3. **可维护性**: 工具更新和迁移更加容易
|
||||
4. **安全性**: 通过验证和审计保障工具安全
|
||||
5. **生产力**: 减少环境配置时间,专注开发工作
|
||||
|
||||
作为 OpenClaw 集成专家,我强烈推荐在嵌入式项目中采用此技能管理开发工具链,这将为项目的长期维护和团队协作奠定坚实基础。
|
||||
|
||||
---
|
||||
|
||||
*最后更新: 2024-01-15*
|
||||
*版本: 2.0.0*
|
||||
*作者: OpenClaw 集成专家团队*
|
||||
@@ -0,0 +1,117 @@
|
||||
---
|
||||
|
||||
name: "gen_font"
|
||||
|
||||
description: "Generates LVGL CJK bitmap fonts for the LCD UI. Invoke when user needs to add new Chinese characters to the display or regenerate font files."
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
# Generate CJK Font for LVGL
|
||||
|
||||
|
||||
|
||||
This skill generates custom LVGL bitmap fonts for Chinese/Japanese/Korean (CJK) character display on the 800x480 LCD. The project uses SimHei (黑体) as source and produces 4 font sizes (16, 20, 40, 60px) with 4bpp.
|
||||
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
||||
|
||||
- **lv_font_conv** installed globally via npm:
|
||||
|
||||
```bash
|
||||
|
||||
npm install -g lv_font_conv
|
||||
|
||||
```
|
||||
|
||||
Installed at: `C:\Users\gxms0\AppData\Roaming\npm\lv_font_conv.cmd`
|
||||
|
||||
|
||||
|
||||
- **Source font**: `vue/vue3/src/assets/fonts/simhei.ttf`(黑体)
|
||||
|
||||
|
||||
|
||||
- **Python 3** with `fonttools` and `Pillow` (for alternative generation methods)
|
||||
|
||||
|
||||
|
||||
## Font Files
|
||||
|
||||
|
||||
|
||||
| Size | Output File | Usage in UI |
|
||||
|
||||
|:----:|-------------|-------------|
|
||||
|
||||
| 16px | `app/tasks/custom_cjk_16.c` | Labels, subtitles, unit text |
|
||||
|
||||
| 20px | `app/tasks/custom_cjk_20.c` | Unit labels, medium text |
|
||||
|
||||
| 40px | `app/tasks/custom_cjk_40.c` | Large weight/count display |
|
||||
|
||||
| 60px | `app/tasks/custom_cjk_60.c` | Button text, status text |
|
||||
|
||||
|
||||
|
||||
## How to Add New Characters
|
||||
|
||||
|
||||
|
||||
### Step 1: Find Unicode values
|
||||
|
||||
|
||||
|
||||
Use Python to get Unicode codepoints:
|
||||
|
||||
```python
|
||||
|
||||
chars = "工序称重折纸打包封包加热"
|
||||
|
||||
for ch in chars:
|
||||
|
||||
print(f"0x{ord(ch):04X} # {ch}")
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Step 2: Edit codepoint list
|
||||
|
||||
|
||||
|
||||
Open `regen_font_new.py` and add new hex values to the `codes` list in sorted order:
|
||||
|
||||
|
||||
|
||||
```python
|
||||
|
||||
codes = [
|
||||
|
||||
0x2B, 0x2D, 0x2E, # ... existing codes
|
||||
|
||||
0x4E2D, 0x4F4D, # ... CJK characters
|
||||
|
||||
0x52A0, # 加 - newly added
|
||||
|
||||
0x5C01, # 封 - newly added
|
||||
|
||||
0x70ED, # 热 - newly added
|
||||
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Step 3: Regenerate all font sizes
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
cd D:\20_AI\LSPi
|
||||
@@ -0,0 +1,385 @@
|
||||
---
|
||||
|
||||
name: "packer-ui"
|
||||
|
||||
description: "包装机界面(packer_ui)设计规范与开发指南。包括布局尺寸、颜色体系、字体使用和后续开发指导。适用于800x480 LCD上的LVGL界面。"
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
# Packer UI Design Guide
|
||||
|
||||
|
||||
|
||||
## 1. 布局总览
|
||||
|
||||
|
||||
|
||||
屏幕分辨率为 **800x480**,整体划分为左右两栏:
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
+--------------------------------------------------------------+
|
||||
|
||||
| +--------------------------+ +--------------------------+ |
|
||||
|
||||
| | 状态卡片 (左) | | 启动按钮 (右) | |
|
||||
|
||||
| | x=10, y=10 | | x=580, y=10 | |
|
||||
|
||||
| | w=560, h=330 | | w=210, h=330 | |
|
||||
|
||||
| | | | | |
|
||||
|
||||
| | +----------+----------+ | | "启动" | |
|
||||
|
||||
| | | 当前重量 | 总包数 | | | | |
|
||||
|
||||
| | | | | | | | |
|
||||
|
||||
| | | 0.0 | 0 | | | | |
|
||||
|
||||
| | | | | | | | |
|
||||
|
||||
| | | 称重斗.. | 累计成品 | | | | |
|
||||
|
||||
| | +----------+----------+ | | | |
|
||||
|
||||
| | 工序 进料 | o 已停止 | | | |
|
||||
|
||||
| +--------------------------+ +--------------------------+ |
|
||||
|
||||
| +--------------------------+ +--------------------------+ |
|
||||
|
||||
| | 目标重量卡片 (左下) | | 复位按钮 (右下) | |
|
||||
|
||||
| | x=10, y=350 | | x=580, y=350 | |
|
||||
|
||||
| | w=560, h=120 | | w=210, h=120 | |
|
||||
|
||||
| | | | | |
|
||||
|
||||
| | 设计重量 190.0 克/包 | | 复位 | |
|
||||
|
||||
| | o(-) o(+) | | | |
|
||||
|
||||
| +--------------------------+ +--------------------------+ |
|
||||
|
||||
+--------------------------------------------------------------+
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 2. 容器与位置参数
|
||||
|
||||
|
||||
|
||||
### 2.1 顶层容器
|
||||
|
||||
|
||||
|
||||
| 控件 | 创建函数 | x | y | w | h | 圆角 | 背景色 |
|
||||
|
||||
|------|---------|---|---|---|---|------|--------|
|
||||
|
||||
| packer_scr | lv_obj_create | - | - | 800 | 480 | - | COLOR_BG |
|
||||
|
||||
| card_status | lv_obj_create | 10 | 10 | 560 | 330 | 20 | COLOR_CARD |
|
||||
|
||||
| card_target | lv_obj_create | 10 | 350 | 560 | 120 | 20 | COLOR_CARD_TARGET |
|
||||
|
||||
| btn_start | lv_btn_create | 580 | 10 | 210 | 330 | 20 | COLOR_BTN_START |
|
||||
|
||||
| btn_reset | lv_btn_create | 580 | 350 | 210 | 120 | 20 | COLOR_BTN_DARK |
|
||||
|
||||
| btn_minus | lv_btn_create | 331 | 30 | 60 | 60 | 30 | COLOR_BTN_ADJ |
|
||||
|
||||
| btn_plus | lv_btn_create | 463 | 30 | 60 | 60 | 30 | COLOR_BTN_ADJ |
|
||||
|
||||
|
||||
|
||||
### 2.2 状态卡片内部分布
|
||||
|
||||
|
||||
|
||||
card_status (560x330) 被垂直分割线分成左右两半:
|
||||
|
||||
|
||||
|
||||
**左半区 -- 当前重量 (宽度 281px)**
|
||||
|
||||
|
||||
|
||||
| 控件 | 文本 | 父级x偏移 | 父级y偏移 | 宽 | 高 | 字体 | 颜色 |
|
||||
|
||||
|------|------|----------|----------|-----|-----|------|------|
|
||||
|
||||
| w_title | "当前重量" | 0 | 14 | 281 | 28 | custom_cjk_20 | COLOR_GREEN |
|
||||
|
||||
| label_current_weight | "0.0" | 0 | 90 | 281 | 84 | custom_cjk_60 | COLOR_TEXT_MAIN |
|
||||
|
||||
| w_sub | "称重斗实时值" | 0 | 200 | 281 | 20 | custom_cjk_16 | 0x6f9181 |
|
||||
|
||||
|
||||
|
||||
**右半区 -- 总包数 (宽度 278px)**
|
||||
|
||||
|
||||
|
||||
| 控件 | 文本 | 父级x偏移 | 父级y偏移 | 宽 | 高 | 字体 | 颜色 |
|
||||
|
||||
|------|------|----------|----------|-----|-----|------|------|
|
||||
|
||||
| c_title | "总包数" | 282 | 14 | 278 | 30 | custom_cjk_20 | COLOR_GREEN |
|
||||
|
||||
| label_pack_count | "0" | 282 | 90 | 278 | 84 | custom_cjk_60 | COLOR_TEXT_MAIN |
|
||||
|
||||
| c_sub | "累计成品" | 282 | 200 | 278 | 20 | custom_cjk_16 | 0x6f9181 |
|
||||
|
||||
|
||||
|
||||
**分割线**
|
||||
|
||||
|
||||
|
||||
| 控件 | 位置(x,y) | 尺寸(w,h) | 颜色 |
|
||||
|
||||
|------|----------|----------|------|
|
||||
|
||||
| horizontal_line | (40, 240) | (480, 1) | COLOR_BORDER |
|
||||
|
||||
| vertical_line | (280, 20) | (1, 290) | COLOR_BORDER |
|
||||
|
||||
|
||||
|
||||
**状态指示**
|
||||
|
||||
|
||||
|
||||
| 控件 | 文本 | 父级x偏移 | 父级y偏移 | 宽 | 高 | 圆角 | 颜色 |
|
||||
|
||||
|------|------|----------|----------|-----|-----|------|------|
|
||||
|
||||
| status_dot | - | 330 | 270 | 34 | 35 | 17(圆形) | COLOR_GREEN |
|
||||
|
||||
| label_status | "已停止" | 420 | 280 | - | - | - | COLOR_TEXT_MAIN, font 20px |
|
||||
|
||||
|
||||
|
||||
**工序状态 (左下, 分割线下方)**
|
||||
|
||||
|
||||
|
||||
标题 "工序" 位于 x=50, y=270, 使用 font 20px, COLOR_GREEN。
|
||||
|
||||
当前工序名称紧跟在标题右侧, 使用 font 20px, COLOR_TEXT_MAIN:
|
||||
|
||||
|
||||
|
||||
| 控件 | 文本(初始) | x | y | 字体 | 颜色 |
|
||||
|
||||
|-----|-----------|----|----|------|------|
|
||||
|
||||
| proc_title | "工序" | 50 | 270 | custom_cjk_20 | COLOR_GREEN |
|
||||
|
||||
| label_step | "进料" | 120 | 270 | custom_cjk_20 | COLOR_TEXT_MAIN |
|
||||
|
||||
|
||||
|
||||
通过 `current_step` (0~5) 索引 `step_name[]` 数组动态切换显示的工序:
|
||||
|
||||
```c
|
||||
|
||||
static const char *step_name[] = {"进料", "称重", "压缩", "打包", "封包", "出料"};
|
||||
|
||||
if (current_step < 6)
|
||||
|
||||
lv_label_set_text(label_step, step_name[current_step]);
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.3 目标重量卡内部布局
|
||||
|
||||
|
||||
|
||||
card_target (560x120) 从左到右:
|
||||
|
||||
|
||||
|
||||
| 控件 | 文本 | 父级x偏移 | 父级y偏移 | 宽/尺寸 | 高 | 字体 | 颜色 |
|
||||
|
||||
|------|------|----------|----------|---------|-----|------|------|
|
||||
|
||||
| t_title | "设计重量" | 0 | 50 | 90 | 120 | custom_cjk_20 | COLOR_GREEN |
|
||||
|
||||
| label_target_val | "190.0" | 100 | 30 | 150 | 120 | custom_cjk_60 | COLOR_TEXT_MAIN |
|
||||
|
||||
| t_unit | "克/包" | 240 | 50 | - | - | custom_cjk_20 | 0x6f9181 |
|
||||
|
||||
| btn_minus | "-" | 331 | 30 | 60x60 | - | custom_cjk_60 | COLOR_TEXT_MAIN |
|
||||
|
||||
| btn_plus | "+" | 463 | 30 | 60x60 | - | custom_cjk_40 | COLOR_TEXT_MAIN |
|
||||
|
||||
|
||||
|
||||
> btn_minus 字符"-"用 font 60px, btn_plus 字符"+"用 font 40px, 视觉上调整到大小接近。
|
||||
|
||||
|
||||
|
||||
## 3. 颜色体系
|
||||
|
||||
|
||||
|
||||
### 3.1 颜色常量定义
|
||||
|
||||
|
||||
|
||||
```c
|
||||
|
||||
COLOR_BG = 0x161b22 // 深色背景(深蓝黑)
|
||||
|
||||
COLOR_CARD = 0x000000 // 卡片背景(纯黑)
|
||||
|
||||
COLOR_CARD_TARGET = 0x080a0e // 目标重量卡片(近乎纯黑)
|
||||
|
||||
COLOR_BORDER = 0x30363d // 分割线颜色(暗灰)
|
||||
|
||||
COLOR_TEXT_MAIN = 0xffffff // 主文字(纯白)
|
||||
|
||||
COLOR_TEXT_SEC = 0x9ab3a5 // 次要文字(薄荷灰)
|
||||
|
||||
COLOR_BTN_START = 0x06990c // 启动按钮背景(绿色)
|
||||
|
||||
COLOR_BTN_DARK = 0x000000 // 复位按钮背景(纯黑)
|
||||
|
||||
COLOR_BTN_ADJ = 0x1e3c28 // 加减按钮背景(深绿)
|
||||
|
||||
COLOR_GREEN = 0x06990c // 状态灯/绿色指示(绿色)
|
||||
|
||||
COLOR_RED = 0x990B06 // 红色(深红)
|
||||
|
||||
COLOR_ADJ_ICON = 0xc4c4c4 // 调节图标辅助色(浅灰)
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 3.2 辅助颜色(直接硬编码)
|
||||
|
||||
|
||||
|
||||
| 用途 | 颜色值 | 说明 |
|
||||
|
||||
|------|--------|------|
|
||||
|
||||
| w_sub / c_sub 文字 | 0x6f9181 | 副标题, 茶绿色 |
|
||||
|
||||
| t_unit "克/包" | 0x6f9181 | 单位标签, 茶绿色 |
|
||||
|
||||
|
||||
|
||||
### 3.3 状态灯逻辑
|
||||
|
||||
|
||||
|
||||
状态灯(status_dot)是一个 34x35 的圆形, 通过背景色切换运行/停止:
|
||||
|
||||
|
||||
|
||||
| 状态 | 圆点颜色 | 圆点值 | 文字颜色 |
|
||||
|
||||
|------|---------|--------|---------|
|
||||
|
||||
| 运行中 | COLOR_GREEN | 0x06990c | COLOR_TEXT_MAIN |
|
||||
|
||||
| 已停止 | COLOR_RED | 0x990B06 | COLOR_TEXT_MAIN |
|
||||
|
||||
|
||||
|
||||
状态灯右侧显示文字 label_status, 内容对应切换: "运行中" / "已停止", 文字始终为白色 (COLOR_TEXT_MAIN)。
|
||||
|
||||
|
||||
|
||||
## 4. 字体系统
|
||||
|
||||
|
||||
|
||||
### 4.1 字体规格
|
||||
|
||||
|
||||
|
||||
使用 SimHei(黑体)生成的 LVGL 位图字体, 4bpp 抗锯齿:
|
||||
|
||||
|
||||
|
||||
| 大小 | 字体变量 | 适用场景 |
|
||||
|
||||
|:----:|----------|----------|
|
||||
|
||||
| 16px | custom_cjk_16 | 副标题, 辅助说明文字 |
|
||||
|
||||
| 20px | custom_cjk_20 | 区域标题, 标签, 单位 |
|
||||
|
||||
| 40px | custom_cjk_40 | 按钮文字, 部分符号(+) |
|
||||
|
||||
| 60px | custom_cjk_60 | 数值显示, 大字符号(-) |
|
||||
|
||||
|
||||
|
||||
### 4.2 字体声明
|
||||
|
||||
|
||||
|
||||
```c
|
||||
|
||||
LV_FONT_DECLARE(custom_cjk_16);
|
||||
|
||||
LV_FONT_DECLARE(custom_cjk_20);
|
||||
|
||||
LV_FONT_DECLARE(custom_cjk_40);
|
||||
|
||||
LV_FONT_DECLARE(custom_cjk_60);
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 5. 按钮样式规则
|
||||
|
||||
|
||||
|
||||
所有按钮统一移除阴影, 轮廓, 边框:
|
||||
|
||||
|
||||
|
||||
```c
|
||||
|
||||
// 每个按钮创建后必须执行的样式
|
||||
|
||||
lv_obj_set_style_shadow_width(btn, 0, 0);
|
||||
|
||||
lv_obj_set_style_shadow_opa(btn, LV_OPA_0, 0);
|
||||
|
||||
lv_obj_set_style_outline_width(btn, 0, 0);
|
||||
|
||||
lv_obj_set_style_outline_opa(btn, LV_OPA_0, 0);
|
||||
|
||||
lv_obj_set_style_border_width(btn, 0, 0);
|
||||
|
||||
lv_obj_set_style_border_side(btn, LV_BORDER_SIDE_NONE, 0);
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
按钮样式差异(仅背景色和圆角不同):
|
||||
|
||||
|
||||
|
||||
| 按钮 | 圆角 | 背景色 | 文字颜色 | 字体 |
|
||||
Reference in New Issue
Block a user