简介

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. 科研伴我成长——上海交通大学ACM班学生在微软亚洲研究院的幸福实习生活

    每一年,微软亚洲研究院都会迎来一批"特殊的"实习生--他们既不是从五湖四海汇聚而来,也不是在读的硕士和博士.他们相识已久,知道对方的小秘密.小八卦,也相互敬佩.惺惺相惜--他们就是 ...

  2. linux服务器项目部署

    重启服务器 :reboot C:\Users\maple>mysql -u root -pEnter password: ******mysql> use test;Database ch ...

  3. mysql中not exists的简单理解

    http://www.cnblogs.com/glory-jzx/archive/2012/07/19/2599215.html http://sunxiaqw.blog.163.com/blog/s ...

  4. 4.2英寸的iPhone SE2就要来了!但你还会买单吗?

    SE2就要来了!但你还会买单吗?" title="4.2英寸的iPhone SE2就要来了!但你还会买单吗?"> 与其他手机厂商不同,苹果在手机市场的产品策略很&q ...

  5. SpringMVC引入CSS等文件

    在默认情况下Spring MVC 拦截了所有请求,所以自己要把静态资源配置起来,IDEA 在Spring-service 配置,eclipse在自己新建的SpringMVC配置文件里配置,如下代码 & ...

  6. RocketMQ 单机版安装并测试

    一.安装maven 1.下载maven,http://maven.apache.org/download.cgi,并解压: -bin.tar.gz 2.修改系统环境变量,并验证: vim /etc/p ...

  7. Opengl-法线贴图(用来细化表面的表现表现的凹凸)

    我们通过这张图可以看出来,使用了法线贴图的物体表面更有细节更逼真,其实这就是发现贴图的作用,没什么钻牛角尖的. 其实表面没有凹凸的情况是因为我们把表面一直按照平整来做的,要想突出这个表面的凹凸就要用到 ...

  8. linux 的uuid码

    在提到这个之前,有个概念,就是什么是uuid呢? UUID码全称是通用唯一识别码 (Universally Unique Identifier, UUID),它 是一个软件建构的标准,亦为自由软件基金 ...

  9. linux下查找文件及查找包含指定内容的文件常用命令

    whereis <程序名称> 查找软件的安装路径-b 只查找二进制文件-m 只查找帮助文件-s 只查找源代码-u 排除指定类型文件-f 只显示文件名-B <目录> 在指定目录下 ...

  10. L2-013 红色警报(25 分)

    L2-013 红色警报(25 分)战争中保持各个城市间的连通性非常重要.本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报.注意:若该国本来就不完全连通,是 ...