当前位置: 首页 > news >正文

Linux内核C语言代码规范

Linux内核C语言代码规范

一、命名规范详解

1. 变量/函数命名
/* 正确示例 */
int device_driver_count;        // 设备驱动计数
void register_pci_device(void); // 注册PCI设备/* 错误示例 */
int DeviceCount;                // 首字母大写
void RegisterPCI();             // 首字母大写+缩写

规范要求

  • 全小写snake_case,单词间用下划线连接
  • 全局变量/函数需带模块前缀(如pci_, usb_
  • 避免缩写(除非广泛接受如dev
2. 类型定义
/* 正确示例 */
struct list_head {      // 链表头struct list_head *next, *prev;
};
typedef void (*irq_handler_t)(int, void*);  // 中断处理函数指针/* 错误示例 */
typedef struct {        // 匿名结构体int x, y;
} Point_t;              // _t后缀用于基本类型

规范要求

  • 结构体/联合体使用struct关键字显式声明
  • typedef仅用于函数指针和特定场景
  • 避免使用_t后缀(内核约定)
3. 宏命名
/* 正确示例 */
#define MAX_IRQ_NUM 256                 // 常量宏
#define container_of(ptr, type, member) // 函数式宏((type *)((char *)(ptr) - offsetof(type, member)))/* 错误示例 */
#define MaxIrq 256      // 混合大小写
#define min(a,b) a<b?a:b // 缺少参数括号

规范要求

  • 常量宏全大写SCREAMING_SNAKE_CASE
  • 函数式宏使用小写和括号保护参数
  • 多行宏用do {...} while(0)包裹

二、格式规范详解

1. 缩进与空格
/* 正确示例 */
if (irq < MAX_IRQ_NUM) {    // 关键字后空格struct irq_desc *desc = &irq_desc[irq];  // *靠近变量名desc->handler(irq, desc->dev_id);        // ->操作符无空格
}/* 错误示例 */
if(irq<MAX_IRQ_NUM){        // 缺少空格struct irq_desc* desc = &irq_desc [ irq ]; // *位置错误+多余空格
}

规范要求

  • 8字符Tab缩进(非空格)
  • 关键字后加空格:if (, while (
  • 指针声明:char *ptr*靠左)
  • 操作符两侧空格:a = b + c
2. 大括号规则
/* 函数 */
int init_module(void)        // 函数大括号独占一行
{/* ... */
}/* 语句块 */
if (condition) {             // 左大括号同行do_this();do_that();
} else {                     // else单独一行do_otherwise();
}/* 单行语句 */
if (condition)single_statement();      // 无大括号但独占一行
3. 行长度与换行
/* 正确换行 */
static int process_packet(struct sk_buff *skb, struct net_device *dev,struct packet_type *pt)
{return netif_rx(skb) == NET_RX_SUCCESS ? 0 : -EIO;
}/* 错误换行 */
int result = function_with_long_name(argument1, argument2, argument3, argument4);  // 错误:续行缩进不足

规范要求

  • 行长度≤100字符
  • 续行对齐参数或操作符
  • 函数参数过多时每行一个参数

三、文件组织规范

1. 头文件格式
#ifndef _LINUX_SCHED_H     // 保护宏格式:_LINUX_<文件名>_H
#define _LINUX_SCHED_H#include <linux/pid.h>     // 标准头文件
#include <asm/current.h>   // 体系结构相关头文件/* 内联函数 */
static inline void __set_task_state(struct task_struct *tsk, int state)
{tsk->state = state;
}/* 函数声明 */
extern void scheduler_tick(void);#endif /* _LINUX_SCHED_H */
2. 源文件结构
/* * 文件注释:描述模块功能* Copyright (c) ... 许可证信息*/
#include <linux/module.h>
#include "internal.h"       // 本地头文件#define LOCAL_DEBUG 0       // 本地宏定义static int instance_count;  // 静态全局变量/* 主功能函数 */
int core_function(void)
{/* ... */
}/* 辅助函数 */
static void helper(void)    // 静态函数
{/* ... */
}

四、内核特有规范

1. 错误处理模式
int device_probe(struct device *dev)
{int ret;struct resource *res;res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);if (!res)return -ENOMEM;     // 直接返回错误码ret = device_init(res);if (ret < 0)goto err_init;      // 错误时跳转清理ret = register_device(res);if (ret < 0)goto err_register;return 0;/* 逆向资源释放 */
err_register:device_deinit(res);
err_init:devm_kfree(dev, res);return ret;
}
2. 并发控制
static DEFINE_SPINLOCK(counter_lock);
static atomic_t online_devices = ATOMIC_INIT(0);void add_device(void)
{unsigned long flags;spin_lock_irqsave(&counter_lock, flags); // 保存中断状态atomic_inc(&online_devices);spin_unlock_irqrestore(&counter_lock, flags);
}
3. 内存管理
/* 标准分配 */
struct data *p = kmalloc(sizeof(*p), GFP_KERNEL);
if (!p)return -ENOMEM;/* 清零分配 */
struct config *cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);/* 高性能对象池 */
static struct kmem_cache *data_cache;data_cache = kmem_cache_create("data_cache", sizeof(struct data), 0, SLAB_HWCACHE_ALIGN, NULL);
struct data *item = kmem_cache_alloc(data_cache, GFP_KERNEL);

五、注释规范

1. 函数注释
/*** irq_handler - 中断服务函数* @irq: 中断号* @dev_id: 设备标识指针** 处理来自设备的硬件中断,读取状态寄存器并* 调度下半部处理程序。** 返回: IRQ_HANDLED 表示成功处理*/
irqreturn_t irq_handler(int irq, void *dev_id)
{/* ... */return IRQ_HANDLED;
}
2. 数据结构注释
/** 进程描述符 - 内核中进程/线程的核心数据结构* * @state: 进程状态(运行、睡眠等)* @stack: 内核栈指针* @tasks: 用于链接到任务列表*/
struct task_struct {volatile long state;void *stack;struct list_head tasks;/* ... */
};

六、典型违规案例

案例1:命名不规范
// 错误
int DeviceCounter;              // 首字母大写
#define MAXDEV 10               // 未全大写// 正确
int device_count;
#define MAX_DEVICES 10
案例2:指针声明位置错误
// 错误
char* buffer;                   // *靠近类型// 正确
char *buffer;                   // *靠近变量名
案例3:大括号使用错误
// 错误
if (condition)
{do_something();             // 左大括号单独一行
}// 正确
if (condition) {do_something();
}

七、工具使用示例

1. checkpatch.pl检查
$ ./scripts/checkpatch.pl -f --strict drivers/net/ethernet.c
2. 代码格式化
$ ./scripts/Lindent drivers/char/mydriver.c
3. 静态分析
$ make C=2 drivers/usb/

总结:Linux内核编码黄金法则

  1. 可读性优先:代码是给人看的,其次才是机器
  2. 一致性至上:严格遵循现有代码风格
  3. 内存安全:每次分配都要考虑释放路径
  4. 并发意识:假设代码会在多核环境运行
  5. 性能敏感:关键路径避免函数调用和分支

内核大师Linus Torvalds的忠告:“糟糕的代码不会被接受,无论它实现了多么炫酷的功能。良好的风格是进入内核社区的门票。”

通过严格遵守这些规范,开发者可以:

  • 提高代码被主线接纳的概率
  • 减少内存泄漏和竞态条件风险
  • 增强代码可维护性和可读性
  • 加速代码审查过程
  • 建立良好的内核开发声誉
http://www.dtcms.com/a/315955.html

相关文章:

  • 解决IntelliJ IDEA 项目名称后带中括号问题(模块名不一致)
  • OpenGL状态机与对象管理:优化图形渲染的高效方法
  • 支持在电脑桌面悬挂的便利贴工具好用评测
  • LeetCode 面试经典 150_数组/字符串_H 指数(9_274_C++_中等)(排序后再进行判断)(计数)
  • 应用科普 | 漫谈6G通信的未来
  • Vue中使用步骤条Steps-手写简单的步骤条功能
  • 大模型下一个飞跃?OpenAI的“新突破”:通用验证器
  • FANCU发那科机器人双脉冲焊接省气
  • 解决英飞凌Tricore编译软件Tasking加载过慢编译卡死问题
  • Windows驱动更新下载工具,电脑硬件设备驱动程序自动安装下载更新,可备份还原!键盘鼠标声卡网卡显卡主板硬盘驱动都可以下载,免费使用的神器!
  • 从传统架构到创新安全:Web2.0与Web3.0的比较分析
  • 10-红黑树
  • Python--JSON格式
  • 艺术性与真实感并存:FLUX.1 Krea [dev] 开源模型速览
  • 复杂环境跌倒识别准确率↑31%!陌讯多模态算法在智慧养老的落地实践
  • 嵌入式硬件中运放内部底层分析
  • Java、Android及计算机基础面试题总结
  • Salesforce Hub-Spoke 架构介绍
  • LoRa基站和网关的区别
  • C++-特殊类设计
  • 学习游戏制作记录(将各种属性应用于战斗以及实体的死亡)8.5
  • 生物医药科研革命:深度解析协同实验记录如何重塑新药研发全流程
  • 应急响应实验复现
  • 浅谈 NUMA 与 MySQL
  • MySQL 在麒麟系统上部署使用 + DBeaver 远程连接 + SQL 数据导入完整流程
  • 华为云代理商的作用与价值解析
  • 嵌套路由配置(React-Router5)
  • Android原生项目集成Flutter模块极简指南
  • 使用buildx构建镜像
  • 若依前后端分离版学习笔记(五)——Spring Boot简介与Spring Security