Skip to content
Back to skills

Embedded Code Skill

ASecurity

Generate, rewrite, or review embedded C code. Use when creating/rewriting/reviewing embedded C for microcontrollers, drivers, firmware. Triggers automatically when user mentions: generate, create, write code, implement driver, rewrite, refactor, review, check, audit.

  • 11 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 10, 2026
code-quality

Works with

  • claude code

Security analysis

A100/100

Pro scans all 10 files and shows the line behind each finding

Scanned September 10, 2026

npx -y skills add luokai0/ai-agent-skills-by-luo-kai --skill embedded-code-skill --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Embedded Code Skill?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Embedded Code Skill
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/luokai0-embedded-code-skill/badge)](https://www.skillsdirectory.com/skills/luokai0-embedded-code-skill)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: embedded-code-skill
description: "Generate, rewrite, or review embedded C code. Use when creating/rewriting/reviewing embedded C for microcontrollers, drivers, firmware. Triggers automatically when user mentions: generate, create, write code, implement driver, rewrite, refactor, review, check, audit."
user-invocable: true
---

# Embedded C 代码生成规范

## 概述

本规范用于生成生产级嵌入式 C 代码,适用于 STM32、PowerPC、RISC-V 等平台。

**核心原则**: 像嵌入式软件架构师一样思考,生成可演进、可测试、可移植的代码。

---

## 思维方式

生成代码时必须以**嵌入式软件架构师**的思维进行:

| 维度 | 要求 |
|------|------|
| **系统视角** | 设计可演进的系统,考虑模块边界、接口契约、依赖关系 |
| **资源意识** | 内存精确计算缓冲区,CPU 减少中断嵌套,优化关键路径 |
| **实时性** | ISR 应尽可能短,考虑 WCET,防范优先级反转/死锁/队列溢出 |
| **可靠性** | 看门狗策略、异常恢复、关键数据冗余存储 |
| **硬件无关** | 寄存器抽象为结构体,驱动与业务逻辑分离 |
| **可测试** | 公共接口易 mock,状态机可单步测试,边界条件覆盖 |

---

## 编码规范

### 1. 类型规范

| 类型 | 用途 | 禁止 |
|------|------|------|
| `uint8_t` | 单字节、GPIO | `char`, `signed char` |
| `uint16_t` | 16位寄存器 | `short`, `unsigned short` |
| `uint32_t` | 32位寄存器、时间戳 | `int`, `long`, `unsigned int` |
| `int32_t` | 有符号值 | - |
| `uint64_t` | 64位数据 | - |
| `bool` | 布尔标志 | - |

**必须包含的头文件:**
```c
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
```

### 2. 命名规范

| 元素 | 格式 | 示例 |
|------|------|------|
| 变量 | `snake_case` | `sensor_value`, `data_count` |
| 全局变量 | `g_snake_case` | `g_system_ticks` |
| 常量/宏 | `SCREAMING_SNAKE` | `MAX_BUFFER_SIZE`, `SPI_CR_EN` |
| 函数 | `camelCase` | `initUart()`, `getSensorData()` |
| 结构体类型 | `snake_case_t` | `uart_config_t` |
| 枚举类型 | `snake_case_t` | `gpio_state_t` |
| 枚举值 | `PREFIXED_SNAKE` | `GPIO_STATE_LOW` |
| 指针 | `p_snake_case` | `p_rx_buffer` |
| 寄存器结构体 | `module_name_reg_t` | `spi_reg_t` |
| 寄存器头文件 | `module_reg.h` | `spi_reg.h` |

### 3. 错误处理

所有 public 函数必须:

1. 返回 `embedded_code_status_t` 枚举类型
2. 验证所有输入指针(NULL 检查)
3. 返回具体错误码

```c
typedef enum {
    EmbedCode_Ok = 0,
    EmbedCode_ErrNullPtr = -1,
    EmbedCode_ErrInvalidArg = -2,
    EmbedCode_ErrTimeout = -3,
    EmbedCode_ErrBusy = -4,
    EmbedCode_ErrNotInit = -5
} embedded_code_status_t;

#define VALIDATE_NOT_NULL(ptr) \
    do { if ((ptr) == NULL) return EmbedCode_ErrNullPtr; } while(0)
```

### 4. 注释规范

**注释语言: 优先使用中文**

| 原则 | 说明 |
|------|------|
| **中文优先** | 便于团队阅读和维护 |
| **解释 WHY** | 注释应说明原因和意图,而非描述代码在做什么 |
| **代码自说明** | 如果代码本身已清楚表达含义,无需注释 |

**Doxygen 文件头格式:**
```c
/**
 * @file spi_reg.h
 * @brief SPI 寄存器结构体定义
 * @author Claude Code
 * @date 2026-04-10
 */
```

**行内注释示例:**
```c
config |= SPI_CR_EN_MASK;  /* 启用 SPI,低电平有效 */
```

### 5. 寄存器结构体定义

**每个外设模块必须有独立的 reg.h 文件:**

| 必需元素 | 说明 |
|----------|------|
| `XXX_BASE_ADDR` | 基地址定义,格式:`XXX_BASE_ADDR` |
| `xxx_reg_t` | 寄存器结构体,使用 `volatile uint32_t` |
| `XXX_XXX_MASK/SHIFT` | 位字段宏定义 |
| `XXX_REG` | 结构体指针访问宏 |

**reg.h 模板:**
```c
/**
 * @file spi_reg.h
 * @brief SPI 外设寄存器定义
 */
#ifndef SPI_REG_H
#define SPI_REG_H

#include <stdint.h>

/* 基地址 */
#define SPI_BASE_ADDR  (0xA0010000U)

/* 寄存器结构体 */
typedef struct {
    volatile uint32_t CTRL;     /* 0x00: 控制寄存器 */
    volatile uint32_t STATUS;   /* 0x04: 状态寄存器 */
    volatile uint32_t DATA;     /* 0x08: 数据寄存器 */
} spi_reg_t;

/* 位字段定义 */
#define SPI_CTRL_EN_MASK      (1U << 0)
#define SPI_CTRL_MODE_MASK    (3U << 2)

/* 寄存器访问 */
#define SPI_REG  ((spi_reg_t *) SPI_BASE_ADDR)

#endif /* SPI_REG_H */
```

### 6. 寄存器赋值规范

**禁止直接赋字面值,必须使用已定义的宏:**

```c
// ❌ 错误
SPI_REG->CTRL = 0x47U;
SPI_REG->BAUD = 250U;

// ✅ 正确
SPI_REG->CTRL = SPI_CTRL_INIT_VAL;
SPI_REG->BAUD = SPI_BAUD_DIV;
```

### 7. 安全编码

| 禁止 | 必须 |
|------|------|
| `malloc`, `free`, `calloc`, `realloc` | 固定大小缓冲区 |
| `new`, `delete` | 环形缓冲区用于数据流 |
| VLA (变长数组) | 精确计算的缓冲区大小 |

```c
#define BUFFER_SIZE 256U
uint8_t buffer[BUFFER_SIZE];
```

### 8. 数据结构

| 场景 | 方式 |
|------|------|
| 相关配置数据 | `struct` |
| 相关常量集合 | `enum` |
| 相关状态数据 | `struct` |

```c
/* 配置结构体 */
typedef struct {
    uint32_t base_address;
    uint16_t interrupt_priority;
    bool     enable_dma;
} peripheral_config_t;

/* 句柄结构体 */
typedef struct {
    bool                initialized;
    peripheral_config_t config;
} peripheral_handle_t;
```

---

## 工作模式

### GENERATE 模式

直接应用本规范生成代码,无需保留任何旧代码。

### REWRITE 模式

**核心原则: 功能流程优先**

> ⚠️ 用户提供的源代码代表着原有的功能实现流程。即使代码有错误,在修改前必须先完整理解其功能流程,再进行符合规范的改写。不得为符合规范而破坏原有的功能流程。

**执行步骤:**

| 步骤 | 内容 |
|------|------|
| **Step 1: 理解原代码** | 梳理数据流、识别状态机/算法、标注寄存器操作 |
| **Step 2: 识别重写部分** | 确定需重构的函数/模块 |
| **Step 3: 按规范重写** | 类型/命名/结构体符合规范,功能逻辑保持一致 |
| **Step 4: 回查验证** | 验证功能流程未改变,所有规范已满足 |

**关于原代码中的 bug:**
- 原代码的 bug 属于"功能流程"的一部分
- 如果 bug 是用户期望保留的行为(如已知的工作around),保持原样
- 如果原代码有语法错误无法编译,标注问题但不擅自修复
- 除非用户明确要求,否则不修改原代码的功能逻辑

### REVIEW 模式

检查现有代码是否符合嵌入式 C 规范。

**执行步骤:**

| 步骤 | 内容 |
|------|------|
| **Step 1: 对照检查** | 按回查清单逐项检查 |
| **Step 2: 标注问题** | 列出不符合规范的地方 |
| **Step 3: 提出建议** | 提供具体的修改建议 |

---

## 项目文件结构

```
project/
├── inc/
│   ├── module_reg.h      # 寄存器结构体定义(每个外设必须有)
│   ├── module_config.h   # 配置参数
│   └── module.h          # 公共接口
└── src/
    └── module.c          # 实现
```

---

## PDCA 工作流

```
┌─────────────────────────────────────────────────────────┐
│  P (Plan) - 分析需求,检查完备性                         │
│    • 确定模式: GENERATE / REWRITE / REVIEW              │
│    • 检测领域/架构/外设关键词                            │
│    • 检查关键信息是否完备(基地址等)                     │
│    ⚡ REWRITE模式: 优先理解原代码功能流程                │
├─────────────────────────────────────────────────────────┤
│  D (Do) - 生成/重写代码                                 │
│    • GENERATE: 直接应用本规范                           │
│    • REWRITE: 保持原功能流程,应用本规范                 │
│    • 创建或更新 reg.h 寄存器结构体定义                   │
│    • 生成符合规范的代码                                  │
├─────────────────────────────────────────────────────────┤
│  C (Check) - 回查验证                                   │
│    • 对照回查清单逐项检查                               │
│    • 验证寄存器结构体定义是否正确                        │
│    ⚡ REWRITE模式: 验证功能流程是否保持一致             │
├─────────────────────────────────────────────────────────┤
│  A (Act) - 修正输出                                     │
│    • 修正所有发现的问题                                  │
│    • 重新回查确认                                       │
│    • 输出合格代码                                        │
└─────────────────────────────────────────────────────────┘
```

---

## 回查清单

生成后必须逐项检查:

| # | 检查项 | 不合格则修正 |
|---|--------|------------|
| 1 | 是否有对应的 reg.h 文件? | 创建 reg.h |
| 2 | 寄存器是否用 `volatile uint32_t` 结构体定义? | 重构为结构体 |
| 3 | 位字段是否有宏定义 (MASK/SHIFT)? | 添加位字段宏 |
| 4 | 类型是否仅用 stdint.h? | 替换所有非标准类型 |
| 5 | 命名是否符合规范表? | 修正所有命名 |
| 6 | 所有 public 函数有错误处理? | 添加状态返回 |
| 7 | 无任何 malloc/free/VLA? | 替换为固定缓冲区 |
| 8 | 注释是否使用中文? | 重写注释 |
| 9 | 文件头是否完整 (Doxygen)? | 添加 Doxygen |
| 10 | 生成的代码是否符合规范? | 修正生成代码 |
| ⚡ 11 | REWRITE 模式: 原代码的功能流程是否保持一致? | 确保数据流/状态机/算法逻辑不变 |
| ⚡ 12 | 寄存器赋值是否都使用宏? | 添加宏定义,禁止字面值赋值 |

---

## 常见错误

### 错误 1: 寄存器定义散落各处

```c
// ❌ 错误
#define SPI_CTRL_ADDR  (*(volatile uint32_t *)0xA0010000)
void spiInit(void) { SPI_CTRL_ADDR = 0x47; }

// ✅ 正确 - 独立的 reg.h,统一的命名风格
#include "spi_reg.h"
void spiInit(void) { SPI_REG->CTRL = SPI_CTRL_INIT_VAL; }
```

### 错误 2: 魔法数字

```c
// ❌ 错误 - 含义不清
if (SPI_REG->STATUS & 0x04) { }
SPI_REG->CTRL |= (1U << 7);

// ✅ 正确 - 命名位字段宏
if (SPI_REG->STATUS & SPI_STATUS_TF_EMPT_MASK) { }  /* TX FIFO empty */
SPI_REG->CTRL |= SPI_CTRL_SCPOL_MASK;               /* 时钟极性 */
```

### 错误 3: 使用 `__I`/`__IO` 前缀

```c
// ❌ 错误 - ARM CMSIS 特有,不具可移植性
typedef struct {
    __I uint32_t DATA;
    __IO uint32_t CTRL;
} spi_reg_t;

// ✅ 正确 - 标准 volatile
typedef struct {
    volatile uint32_t DATA;
    volatile uint32_t CTRL;
} spi_reg_t;
```

### 错误 4: 直接赋字面值

```c
// ❌ 错误 - 魔法数字
SPI_REG->BAUD = 250U;
SPI_REG->CTRL = 0x08U;

// ✅ 正确 - 使用宏定义
SPI_REG->BAUD = SPI_BAUD_DIV;
SPI_REG->CTRL = SPI_CTRL_INIT_VAL;
```

---

## 输出格式

GENERATE 模式输出每个外设模块:

```
module/
├── module_reg.h    # 寄存器结构体定义
├── module.h        # 公共接口
└── module.c       # 实现
```

Files in this skill

  • .clawhub/origin.json151 B
  • README.md5.2 KB
  • README_EN.md5.6 KB
  • README_JP.md6.2 KB
  • SKILL.md11.5 KB
  • _meta.json138 B
  • embedded-code-skill-arch/SKILL.md4.7 KB
  • embedded-code-skill-domains/SKILL.md2.2 KB
  • embedded-code-skill-drivers/SKILL.md2.5 KB
  • embedded-code-skill-standards/SKILL.md2.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…