Linux内核文档:如何写符合 kernel-doc 规范的注释

简介:

Linux内核文档:如何写符合 kernel-doc 规范的注释
简介#
Linux内核使用 Sphinx 实现把 Documentation 目录下的 reStructuredText 文件转换为非常漂亮的文档。文档既可以通过 make htmldocs转换成 HTML 格式,也可以通过 make pdfdocs 转换为 PDF 格式。 转换生成的文档存放于 Documentation/output 目录下。

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

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

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

Copy
/**

  • This is a sample of comment
    */

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

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

Copy
$ scripts/kernel-doc -v -none drivers/foo/bar.c
当然,在编译的时候,如果添加以下的选项,也会检查文档的格式:

Copy
make W=n
函数文档#
规范的格式示例如下:

Copy
/**

  • 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.
    */

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

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

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

Copy

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

Copy

  • @argument:
  • some long description
  • that continues on next lines
    函数参数#

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

Copy

  • @...: description
    函数上下文#

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

例如:

Copy

  • Context: Any context.
  • Context: Any context. Takes and releases the RCU lock.
  • Context: Any context. Expects to be held by caller.
  • Context: Process context. May sleep if @gfp flags permit.
  • Context: Process context. Takes and releases .
  • Context: Softirq or process context. Takes and releases , BH-safe.
  • Context: Interrupt context.
    函数返回值#

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

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

Copy

  • Return:
  • 0 - OK
  • -EINVAL - invalid argument
  • -ENOMEM - out of memory
    效果只会是:

Copy
Return: 0 - OK -EINVAL - invalid argument -ENOMEM - out of memory
所以呢,如果你要换行,你需要使用 ReST List,例如:

Copy

  • Return:
    • 0 - OK to runtime suspend the device
    • -EBUSY - Device should not be runtime suspended
      另外,如果字段出现类似key:这样短语加冒号的形式,会被识别为其他的字段。这点需要注意。

struct 和 union 和 enum 类型的注释#
通常 struct ,union 和 enum 类型的注释说明是这样的:

Copy
/**

  • 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 标签必须以*标识开始且不能有缩进,以/标识结束。如果有简介,可以写在:与结束标识/之间,例如:

Copy
/**

  • 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,可以参考下面的做法:

Copy
/**

  • 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;
};
有两点要注意的:

如果嵌套的struct或者union有命名,那么应该使用@foo.bar的形式,例如上例的@bar.st1
如果是匿名的,那么需要直接使用@bar的形式,例如上例的@memb1
细心的小伙伴可能发现,这与C语言上结构体的调用方式非常相似。

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

Copy
/*

  • 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注释#
通常格式如下:

Copy
/**

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

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

Copy
/**

  • 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()

Copy
索引到函数
@parameter

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

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

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

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

Copy
索引到其他结构体
&enum name

Copy
索引到其他的枚举型
&typedef name

Copy
索引到typedef定义的类型
&struct_name->member or &struct_name.member

Copy
索引到制定结构体成员
&name

Copy
泛型类型引用。不建议使用,请使用其他方法
概述说明#
为了便于将源代码和注释紧密结合在一起,可以包含自由格式注释的内核文档块,而不是函数、结构、联合、枚举或typedef的内核文档块。例如,这可以用于驱动程序或库代码的操作理论。

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

通用的格式如下:

Copy
/**

  • 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:后面的标题用作源文件中的标题,也用作提取文档注释的标识符。因此,标题在文件中必须是唯一的。

作者: 广漠飘羽

出处:https://www.cnblogs.com/gmpy/p/12529456.html

相关文章
|
13天前
|
Ubuntu Linux 开发者
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
57 15
|
1月前
|
算法 Linux
深入探索Linux内核的内存管理机制
本文旨在为读者提供对Linux操作系统内核中内存管理机制的深入理解。通过探讨Linux内核如何高效地分配、回收和优化内存资源,我们揭示了这一复杂系统背后的原理及其对系统性能的影响。不同于常规的摘要,本文将直接进入主题,不包含背景信息或研究目的等标准部分,而是专注于技术细节和实际操作。
|
1月前
|
存储 缓存 网络协议
Linux操作系统的内核优化与性能调优####
本文深入探讨了Linux操作系统内核的优化策略与性能调优方法,旨在为系统管理员和高级用户提供一套实用的指南。通过分析内核参数调整、文件系统选择、内存管理及网络配置等关键方面,本文揭示了如何有效提升Linux系统的稳定性和运行效率。不同于常规摘要仅概述内容的做法,本摘要直接指出文章的核心价值——提供具体可行的优化措施,助力读者实现系统性能的飞跃。 ####
|
1月前
|
监控 算法 Linux
Linux内核锁机制深度剖析与实践优化####
本文作为一篇技术性文章,深入探讨了Linux操作系统内核中锁机制的工作原理、类型及其在并发控制中的应用,旨在为开发者提供关于如何有效利用这些工具来提升系统性能和稳定性的见解。不同于常规摘要的概述性质,本文将直接通过具体案例分析,展示在不同场景下选择合适的锁策略对于解决竞争条件、死锁问题的重要性,以及如何根据实际需求调整锁的粒度以达到最佳效果,为读者呈现一份实用性强的实践指南。 ####
|
1月前
|
缓存 监控 网络协议
Linux操作系统的内核优化与实践####
本文旨在探讨Linux操作系统内核的优化策略与实际应用案例,深入分析内核参数调优、编译选项配置及实时性能监控的方法。通过具体实例讲解如何根据不同应用场景调整内核设置,以提升系统性能和稳定性,为系统管理员和技术爱好者提供实用的优化指南。 ####
|
1月前
|
负载均衡 算法 Linux
深入探索Linux内核调度机制:公平与效率的平衡####
本文旨在剖析Linux操作系统内核中的进程调度机制,特别是其如何通过CFS(完全公平调度器)算法实现多任务环境下资源分配的公平性与系统响应速度之间的微妙平衡。不同于传统摘要的概览性质,本文摘要将直接聚焦于CFS的核心原理、设计目标及面临的挑战,为读者揭开Linux高效调度的秘密。 ####
42 3
|
2月前
|
负载均衡 算法 Linux
深入探索Linux内核调度器:公平与效率的平衡####
本文通过剖析Linux内核调度器的工作机制,揭示了其在多任务处理环境中如何实现时间片轮转、优先级调整及完全公平调度算法(CFS),以达到既公平又高效地分配CPU资源的目标。通过对比FIFO和RR等传统调度策略,本文展示了Linux调度器如何在复杂的计算场景下优化性能,为系统设计师和开发者提供了宝贵的设计思路。 ####
44 6
|
1月前
|
消息中间件 安全 Linux
深入探索Linux操作系统的内核机制
本文旨在为读者提供一个关于Linux操作系统内核机制的全面解析。通过探讨Linux内核的设计哲学、核心组件、以及其如何高效地管理硬件资源和系统操作,本文揭示了Linux之所以成为众多开发者和组织首选操作系统的原因。不同于常规摘要,此处我们不涉及具体代码或技术细节,而是从宏观的角度审视Linux内核的架构和功能,为对Linux感兴趣的读者提供一个高层次的理解框架。
|
2月前
|
缓存 网络协议 Linux
深入探索Linux操作系统的内核优化策略####
本文旨在探讨Linux操作系统内核的优化方法,通过分析当前主流的几种内核优化技术,结合具体案例,阐述如何有效提升系统性能与稳定性。文章首先概述了Linux内核的基本结构,随后详细解析了内核优化的必要性及常用手段,包括编译优化、内核参数调整、内存管理优化等,最后通过实例展示了这些优化技巧在实际场景中的应用效果,为读者提供了一套实用的Linux内核优化指南。 ####
56 1
|
2月前
|
算法 前端开发 Linux
深入理解Linux内核调度器:CFS与实时性的平衡####
本文旨在探讨Linux操作系统的核心组件之一——完全公平调度器(CFS)的工作原理,分析其在多任务处理环境中如何实现进程间的公平调度,并进一步讨论Linux对于实时性需求的支持策略。不同于传统摘要仅概述内容要点,本部分将简要预览CFS的设计哲学、核心算法以及它是如何通过红黑树数据结构来维护进程执行顺序,同时触及Linux内核为满足不同应用场景下的实时性要求而做出的权衡与优化。 ####