Linux内核⽂档:如何写符合kernel-doc规范的注释
简介
Linux内核使⽤实现把Documentation⽬录下的⽂件转换为⾮常漂亮的⽂档。⽂档既可以通过 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 类型的注释
通常struct,union和enum类型的注释说明是这样的:
/**
* 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字段、空⾏或者*/表⽰结束。
成员
struct,union和enum的成员注释格式与函数参数的格式⼀致,他们都需要简短的描述且⽀持换⾏。
在struct和union⾥⾯也⽀持注释。⽀持private和public两种标签。private标签的成员不会呈现到编译出来的⽂档上,类似与C++上的private 成员。
需要注意的是,private和public标签必须以\*标识开始且不能有缩进,以*/标识结束。如果有简介,可以写在:与结束标识*/之间,例如:
/**
* 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
如果出现嵌套定义struct和union,可以参考下⾯的做法:
/**
* 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
* @b1: first member of struct st1 on union bar
* @b2: second member of struct st1 on union bar
* @b1: first member of struct st2 on union bar
* @b2: 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语⾔上结构体的调⽤⽅式⾮常相似。
内联的成员描述
成员的描述除了放在开头,还可以放在struct和union⾥⾯。⽀持单⾏或者多⾏,以/**开头,以*/结束。例如:/*
* struct foo - Brief description.
* @foo: The Foo member.
*/linux内核文件放在哪
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 &ber
索引到制定结构体成员
&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:后⾯的标题⽤作源⽂件中的标题,也⽤作提取⽂档注释的标识符。因此,标题在⽂件中必须是唯⼀的。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。