简介

Linux内核使用 Sphinx 实现把 Documentation 目录下的 reStructuredText 文件转换为非常漂亮的文档。文档既可以通过 make htmldocs 转换成 HTML 格式,也可以通过 make pdfdocs 转换为 PDF 格式。 转换生成的文档存放于 Documentation/output 目录下。

Linux内核强大的文档功能,除了直接转换 .rst文档之外,还能从源码中汲取API说明,结构体说明等信息。当然要做到这样,源码的注释是有一定要求的。而这篇文档,就是介绍如何写符合 kernel-doc 格式要求的注释。

英文版原文,根据个人理解做的翻译,如果有翻译错误的地方,请告知。

注释概述

符合 kernel-doc 的注释,都需要从 /** 开始,其后每一行内容都以 *开头,最后是 */ 表示结束。例如:

/**
* This is a sample of comment
*/

对于函数和类型的注释,必须放在函数和类型之前,以便于别人在修改代码的时候,可以顺手把注释也改了。对概述类型的注释,可以放到文件顶部的位置。

Linux内核有提供一个工具用于对 kernel-doc 的格式进行检查,例如:

$ scripts/kernel-doc -v -none drivers/foo/bar.c

当然,在编译的时候,如果添加以下的选项,也会检查文档的格式:

make W=n

函数文档

规范的格式示例如下:

/**
* function_name() - Brief description of function.
* @arg1: Describe the first argument.
* @arg2: Describe the second argument.
* One can provide multiple line descriptions
* for arguments.
*
* A longer description, with more discussion of the function function_name()
* that might be useful to those using or modifying it. Begins with an
* empty comment line, and may include additional embedded empty
* comment lines.
*
* The longer description may have multiple paragraphs.
*
* Context: Describes whether the function can sleep, what locks it takes,
* releases, or expects to be held. It can extend over multiple
* lines.
* Return: Describe the return value of function_name.
*
* The return value description can also have multiple paragraphs, and should
* be placed at the end of the comment block.
*/

函数名后的函数功能简介可以跨越多行,以函数参数描述、返回值描述或其他描述结束。

函数参数

函数参数的描述,必须直接且按顺序放在函数简介之后。需要注意的是,函数参数与函数简介、函数参数与函数参数之间不能有任何空行。

每个函数参数的描述可以跨行,但要注意的是,必须保持缩进对齐,例如

* @argument: some long description
* that continues on next lines # that 必须与 some对齐(避免排版乱套,补充说明)

或者

* @argument:
* some long description
* that continues on next lines

函数参数

如果出现不定数量个参数,可以这么表示:

* @...: description

函数上下文

描述这个函数会在什么场景下调用,就是函数上下文字段所要做的。函数上下文字段用Context:表示,应该包含函数是否会休眠,是否会在中断中调用,以及它会持有、释放什么锁,和其他所有调用这个函数需要注意的东西。

例如:

* Context: Any context.
* Context: Any context. Takes and releases the RCU lock.
* Context: Any context. Expects <lock> to be held by caller.
* Context: Process context. May sleep if @gfp flags permit.
* Context: Process context. Takes and releases <mutex>.
* Context: Softirq or process context. Takes and releases <lock>, BH-safe.
* Context: Interrupt context.

函数返回值

函数返回值相关的描述应该放在Return:字段。

由于不能识别换行,因此如果你这样写:

* Return:
* 0 - OK
* -EINVAL - invalid argument
* -ENOMEM - out of memory

效果只会是:

Return: 0 - OK -EINVAL - invalid argument -ENOMEM - out of memory

所以呢,如果你要换行,你需要使用 ReST List,例如:

* Return:
* * 0 - OK to runtime suspend the device
* * -EBUSY - Device should not be runtime suspended

另外,如果字段出现类似key:这样短语加冒号的形式,会被识别为其他的字段。这点需要注意。

struct 和 union 和 enum 类型的注释

通常 structunionenum 类型的注释说明是这样的:

/**
* struct struct_name - Brief description.
* @member1: Description of member1.
* @member2: Description of member2.
* One can provide multiple line descriptions
* for members.
*
* Description of the structure.
*/

紧随名字后面的 Brief description 可以跨度几行,它以 @member 字段、空行或者*/表示结束。

成员

structunionenum 的成员注释格式与函数参数的格式一致,他们都需要简短的描述且支持换行。

structunion 里面也支持注释。支持 privatepublic 两种标签。private 标签的成员不会呈现到编译出来的文档上,类似与 C++ 上的 private 成员。

需要注意的是,privatepublic 标签必须以\*标识开始且不能有缩进,以*/标识结束。如果有简介,可以写在:与结束标识*/之间,例如:

/**
* struct my_struct - short description
* @a: first member
* @b: second member
* @d: fourth member
*
* Longer description
*/
struct my_struct {
int a;
int b;
/* private: internal use only */
int c;
/* public: the next one is public */
int d;
};

嵌套struct和union

如果出现嵌套定义 structunion,可以参考下面的做法:

/**
* struct nested_foobar - a struct with nested unions and structs
* @memb1: first member of anonymous union/anonymous struct
* @memb2: second member of anonymous union/anonymous struct
* @memb3: third member of anonymous union/anonymous struct
* @memb4: fourth member of anonymous union/anonymous struct
* @bar: non-anonymous union
* @bar.st1: struct st1 inside @bar
* @bar.st2: struct st2 inside @bar
* @bar.st1.memb1: first member of struct st1 on union bar
* @bar.st1.memb2: second member of struct st1 on union bar
* @bar.st2.memb1: first member of struct st2 on union bar
* @bar.st2.memb2: second member of struct st2 on union bar
*/
struct nested_foobar {
/* Anonymous union/struct*/
union {
struct {
int memb1;
int memb2;
}
struct {
void *memb3;
int memb4;
}
}
union {
struct {
int memb1;
int memb2;
} st1;
struct {
void *memb1;
int memb2;
} st2;
} bar;
};

有两点要注意的:

  1. 如果嵌套的struct或者union有命名,那么应该使用@foo.bar的形式,例如上例的@bar.st1
  2. 如果是匿名的,那么需要直接使用@bar的形式,例如上例的@memb1

细心的小伙伴可能发现,这与C语言上结构体的调用方式非常相似。

内联的成员描述

成员的描述除了放在开头,还可以放在 structunion 里面。支持单行或者多行,以/**开头,以*/结束。例如:

/*
* struct foo - Brief description.
* @foo: The Foo member.
*/
struct foo {
int foo;
/**
* @bar: The Bar member.
*/
int bar;
/**
* @baz: The Baz member.
*
* Here, the member description may contain several paragraphs.
*/
int baz;
union {
/** @foobar: Single line description. */
int foobar;
};
/** @bar2: Description for struct @bar2 inside @foo */
struct {
/**
* @bar2.barbar: Description for @barbar inside @foo.bar2
*/
int barbar;
} bar2;
};

typedef注释

通常格式如下:

/**
* typedef type_name - Brief description.
*
* Description of the type.
*/

如果是函数的类型定义,也可以这样:

/**
* typedef type_name - Brief description.
* @arg1: description of arg1
* @arg2: description of arg2
*
* Description of the type.
*
* Context: Locking context.
* Return: Meaning of the return value.
*/
typedef void (*type_name)(struct v4l2_ctrl *arg1, void *arg2);

高亮和交叉索引

在各种说明字段中,可以用以下的形式做成索引。

funcname()

索引到函数

@parameter

索引到函数参数(只在本函数内索引,不会交叉到其他函数)

%CONST

索引到指定名字的上下文段说明(只在本函数内索引,不会交叉到其他函数)

``literal``

字面意义,让 kernel-doc 不解析,做纯字符串处理。常用于出现与 kernel-doc 或者 reStructuredText 关键字冲突的情况

$ENVVAR

环境变量(只在本函数内索引,不会交叉到其他函数)

&struct name

索引到其他结构体

&enum name

索引到其他的枚举型

&typedef name

索引到typedef定义的类型

&struct_name->member or &struct_name.member

索引到制定结构体成员

&name

泛型类型引用。不建议使用,请使用其他方法

概述说明

为了便于将源代码和注释紧密结合在一起,可以包含自由格式注释的内核文档块,而不是函数、结构、联合、枚举或typedef的内核文档块。例如,这可以用于驱动程序或库代码的操作理论。

这是通过使用带有节标题的DOC:section关键字来完成的。

通用的格式如下:

/**
* DOC: Theory of Operation
*
* The whizbang foobar is a dilly of a gizmo. It can do whatever you
* want it to do, at any time. It reads your mind. Here's how it works.
*
* foo bar splat
*
* The only drawback to this gizmo is that is can sometimes damage
* hardware, software, or its subject(s).
*/

DOC:后面的标题用作源文件中的标题,也用作提取文档注释的标识符。因此,标题在文件中必须是唯一的。

Linux内核文档:如何写符合 kernel-doc 规范的注释的更多相关文章

  1. Where is the kernel documentation?; Ubuntu 上如何安装 linux 内核文档;fedora 上如何安装linux内核文档?

    有时候,linux内核文档对我们很重要,我们可以在linux系统中安装,并及时查看: 参考链接:https://askubuntu.com/questions/841043/where-is-the- ...

  2. LINUX 内核文档地址

    Linux的man很强大,该手册分成很多section,使用man时可以指定不同的section来浏览,各个section意义如下: 1 - commands2 - system calls3 - l ...

  3. Linux内核官方文档atomic_ops.txt【摘自Linux 内核文档】

    摘自Linux内核文档 Documentation/atomic_ops.txt,不是本人原创 Semantics and Behavior of Atomic and Bitmask Operati ...

  4. Linux--2 Linux之文档与目录结构、shell基本命令

    一.Linux之文档与目录结构 1.Linux之文档与目录结构 Linux目录结构的组织形式和Windows有很大的不同.Linux没有“盘(如C盘.D盘.E盘)”的概念,而是建立一个根"/ ...

  5. Linux Kbuild文档(转)

    转载链接:http://blog.chinaunix.net/uid-10221131-id-2943265.html Linux Kbuild文档 Linux Kbuild文档 V 0.1 tang ...

  6. Linux之文档与目录结构 目录的相关操作 Linux的文件系统

    Linux之文档与目录结构   Linux文件系统结构 Linux目录结构的组织形式和Windows有很大的不同.首先Linux没有“盘(C盘.D盘.E盘)”的概念.已经建立文件系统的硬盘分区被挂载到 ...

  7. Linux之文档与目录结构 (/ 用法, 相对路径,绝对路径)

    Linux之文档与目录结构   Linux文件系统结构 Linux目录结构的组织形式和Windows有很大的不同.首先Linux没有“盘(C盘.D盘.E盘)”的概念.已经建立文件系统的硬盘分区被挂载到 ...

  8. 运维 03 Linux之文档与目录结构

    Linux之文档与目录结构   Linux文件系统结构 Linux目录结构的组织形式和Windows有很大的不同.首先Linux没有“盘(C盘.D盘.E盘)”的概念.已经建立文件系统的硬盘分区被挂载到 ...

  9. Linux 在文档中查找满足条件的行并输出到文件:

    Linux 在文档中查找满足条件的行并输出到文件: 文件名称: dlog.log    输出文件: out.log 1.满足一个条件(包含  “TJ”  )的语句: grep  “TJ”  dlog. ...

随机推荐

  1. 吴裕雄--天生自然HTML学习笔记:HTML 布局

    网页布局对改善网站的外观非常重要. 请慎重设计您的网页布局. <!DOCTYPE html> <html> <head>  <meta charset=&qu ...

  2. 前后端分离,使用nginx解决跨域问题

    前端:vue.js+nodejs+webpack 后台:SpringBoot 反向代理服务器:nginx 思想:将前端代码打包,让nginx指向静态资源,nginx对后台请求进行转发. 1.将前端代码 ...

  3. 推荐几位jenkins发布war包和jar包大佬的博客

    jenkins部署tomcat的war包和jar包 https://blog.csdn.net/liuxiaoming1109/article/details/89311696  

  4. 树的DFS

    Depth-first search (DFS) is an algorithm for traversing or searching tree or graph data structures. ...

  5. [CF1009F] Dominant Indices (+dsu on tree详解)

    这道题用到了dsu(Disjoint Set Union) on tree,树上启发式合并. 先看了CF的官方英文题解,又看了看zwz大佬的题解,差不多理解了dsu on tree的算法. 但是时间复 ...

  6. Ionic3学习笔记(十三)HttpClient 实现 HTTP 请求以及踩过的一些坑

    本文为原创文章,转载请标明出处 目录 猫眼API HttpClient 实现 HTTP 请求 安装 HttpClientModule 模块 创建 provider 创建 page 一些坑 坑1: 未在 ...

  7. 双股同时上市!小米IPO是想要玩场大的?

    ​近日,据相关媒体报道,有相关人士称小米IPO最终可能敲定A+H股两地发行.但目前还未得到小米官方证实.此前关于小米要上市的消息已经流传已久了,从雷军刚开始的矢口否认到后来的默认,再到后来相关消息愈来 ...

  8. leetcode_315_逆序对问题

    题目描述 本题来自于Leetcode的算法题库第315题,具体题目描述如下: 给定一个nums整数数组 ,按要求返回一个counts新数组 .数组 counts 有该性质: counts[i]的值是 ...

  9. 使用 javascript 配置 nginx

    在上个月的 nginx.conf 2015 大会上, 官方宣布已经支持通过 javascript 代码来配置 nginx,并把这个实现称命名为--nginscript.使用 nginscript,可以 ...

  10. 关于运算符的那些坑—自增x++&&++y

    题目 比较常见的问题,因为比较细,看书的时候一不注意可能就过去啦,但是遇到的时候就会容易出问题.先看下面程序,考虑一下运行结果是什么呢? int x = 1, y = 1; if(x++ == 2 & ...