Frrouting学习笔记(六)——代码维护

本文档翻译自doc/developer/workflow.rst

        FRR是一个由许多不同团体开发的大型项目。本文档记录了要求所有贡献者遵守的代码样式和质量、提交消息、拉取请求和最佳实践的标准。

        本章是“描述性/后事实性”的,因为它记录了正在使用的实践;它不是预先规定的“决定性的/预先事实的”。这意味着,当程序发生变化时,会达成一致,然后付诸实践,然后在此处进行记录。如果此文档与现实不匹配,则需要更新的是文档,而不是现实。

一、邮件列表

        FRR开发小组维护多个邮件列表供社区使用。邮件列表是私有的。

        开发列表用于讨论和记录与项目开发和治理相关的一般问题。公共`Slack实例<https://frrouting.slack.com>`每周技术会议为讨论提供了更高带宽的渠道。此类讨论的结果必须酌情反映在代码更新(如合并)、“GitHub Issues”中,对于治理或流程更改,必须更新开发列表以及发布在FRRouting.

二、开发和发布周期

        2.1 开发

   FRR开发工作流程概述

        FRR的主Git位于“GitHub”上。

        开发有一个主要分支,即“master”。对于每个主要版本(2.0、3.0等),都会基于主版本创建一个新的发布分支。重要的错误修复应该向后移植到不超过1年的即将发布和现有发布分支。一般来说,新功能不会向后移植到发布分支。基于主要分支的后续点发布使用git标记进行处理。

        2.2 发布

        FRR使用`<MAJOR><MINOR><BUGFIX>``版本控制方案。

        A. ``MAJOR``

        重要的新功能或多个次要功能。这应该主要涵盖运营商可见或“有风险”的任何类型的破坏性变化。新的功能或协议不一定会触发这种情况。(在用户反馈主要版本号增量太快后,FRR7.x对此进行了更改。)

        B. ``MINOR``

        一般增量开发发布,不包括上述“重大”变更。不一定完全向后兼容,因为较小(但仍然可见)的更改或不推荐的功能删除仍可能发生。然而,小版本之间不应该有任何巨大的“惊喜”。

        C. ``BUGFIX``

        修复了实际错误和/或安全问题。完全兼容。

        发行计划在每年3月/7/11月的第一个星期二进行,为期4个月。从此日期向后走:

      - 提前6周,“master”被冻结用于新功能,功能PR被视为最低优先级(无论何时打开)

     - 提前4周,稳定分支与master(此时命名为“dev/MAJOR.MINOR”)分离,并标记为“base_X.Y "。Master已解除冻结,新功能可能会再次运行。

        解冻master的一部分是在文件`configure.AC`中编辑`AC_INIT`语句,以反映master现在引用的新开发版本。这伴随着“frr-X.Y-dev”标记在master上,它应该总是在稳定分支分叉后的master上的第一个提交上(即使这不对“AC_INIT”的编辑;更重要的是在分叉后的主上的第一次提交上。)

(文件`configure.ac`编辑和标记推送被视为git内务处理,并直接推送到`master`,而不是通过PR。)

        下面是要在此步骤中使用的命令片段。

        在这一步中,我们还必须更新包版本以反映开发版本。版本需要使用基于master分支的标准开发方式(Pull Request)进行更新。

        只更改版本号,不进行其他更改。这将生成版本号高于任何以前版本的包。一旦发布完成,我们对发布分支上的变更日志文件所做的任何更新都需要仔细选择到主分支。

        在下次冻结时提前更新基本日期,dev/X.Y、RC和发布阶段已排定。这应该放在“master”分支中。

         - 提前两周,一个“frr-X.Y-rc”发布候选被标记。

         -在发布日期,分支机构被重命名为“stable/MAJOR.MINOR”。

        每个事件之间的2周窗口应用于运行正在进行的发布的任何和所有可能的测试。然而,目前的意图是坚持时间表,即使已知的问题仍然存在。只有在用尽所有解决问题的途径后,才有望实现这一点,但为了实现这一目标,需要尽早提供一份尽可能详尽的问题清单,即第一个两周的窗口期。

        作为参考,根据上述内容的预期发布时间表为:

以下是如何轻松获取日期的提示:

        每次发布都由FRR社区的一名或多名志愿者发布经理管理。预计这些发布经理将在一年内处理分支机构。为了分散和分发此工作负载,应为后续版本轮换此工作负载。目前假设/预计发布经理将在上述几周内召开发布管理会议。除非有其他限制,这将安排在每周定期的FRR社区电话会议之前,以便将重要项目转移到该电话会议中。

        修补程序应用于最近的两个版本。预计每个后移植的错误修复程序都应该包括一些包含它的理由,并在接受到发布分支之前获得该发布的发布经理的批准。这并不一定排除将错误修复后移植到两个最新版本之前的版本。

        安全修复程序后移植到所有小于或等于一年的版本。根据严重程度的不同,安全修复程序也可以后移植到较旧的版本。

        有关如何生成FRR发布的详细说明,请参阅:ref:` frr-release-procedure`。

2.3 长期支持分支( LTS )

        这类分支尚未得到官方支持,在生效之前需要进行实验。

        先前版本的定义阻止了对先前版本的长期支持。例如,如果稳定分支太旧,则不会应用错误和安全修复。

        FRR用户需要在稳定分支太旧后对bug和安全修复进行后台移植,所以需要在该稳定分支上提供长期支持。如果这种支持应用于该稳定分支,那么该分支就是长期支持分支。

        拥有一个LTS分支需要额外的工作,并且需要一个人在一定的时间内负责该维护分支。默认情况下,时间将设置为4个月,并且可以增加。4个月代表两次发布之间的时间,这段时间可以应用于是否继续发布LTS的决定。在任何情况下,都将明确规定并公布这一时间段。此外,还需要提议处理LTS分支的人员自我提名。工作可以由多个人共享。在任何情况下,必须至少有一个人负责维护分支机构。负责维护分支机构的人员必须是FRR维护人员。请注意,他们可以随时选择放弃对维护分支的支持。如果没有人接管LTS分支的责任,那么支持将停止。

        LTS分支机构的职责如下:

        A. 每(两)周或每月组织一次会议,处理与该分支机构相关的问题和请求。如果时间允许,可以在定期安排的FRR会议期间进行。

        B.通过使用并最终调整FRR的CI工具来确保分支的稳定性(事实上,维护可能会导致为拓扑测试或CI创建维护分支)。

        将功能请求反输出到LTS分支是不可能的。事实上,使用LTS来满足这种需求是一个错误的好主意。引入功能请求可能会打破所有最新版本都应该包含功能请求的模式。这将要求LTS维护人员确保所有最新版本都支持此功能请求。此外,引入特征请求可能会破坏分支的稳定性。LTS分支首先为稳定性带来长期支持。

2.4 Development分支

        有时,社区会希望能够共同开发对FRR有用的功能。在这种情况下,各方可以要求维护方在主FRR存储库中创建一个开发分支。实现这一点的要求是:

        A. 对正在实施的功能的一段描述,以便于对该功能进行讨论。这可能包括指向相关RFC的指针或解释计划内容的演示文稿。这是为了给组织设置一个较低的标准。

        B.必须命名一个分支维护器。该人员负责保持分支机构的最新情况,并与其他FRR维护人员就项目进行一般沟通。此外,此人必须已经是FRR维护人员。

        C.该分支机构的承诺必须遵循本文件其他领域中概述的正常PR和承诺流程。这样做的目的是防止目前提交的大型功能太大,难以审查。

        在Development分支共同完成工作后,可以进行最终审查,并将该分支合并为master。如果一个开发分支在三个月后变得不维护或没有被积极处理,那么维护人员可以决定删除该分支。

2.5 Debian分支

        Debian项目包含FRR的“官方”包。虽然FRR维护人员可能会参与创建这些,但运送什么以及如何处理这些完全由Debian项目决定。

        出于礼貌和FRR的利益,这项打包工作目前在FRR git主存储库上名为“debian/*”的git分支中可见。这些分支仅供参与FRR Debian包装工作的人员使用。可以提供直接提交访问权限,并且FRR git规则(审查、测试等)不适用。在没有与目标分支上“debian/control”中“Maintainer:”和“Uploader:”下的人员交谈的情况下,不要推送到这些分支——即使您是FRR Maintainer。

2.6 修改日志Changelog

        变更日志将作为发布说明的基础。通常不需要更改日志条目,维护人员会根据您的提交消息添加该条目。但是,您可以自由地在变更日志中添加更新,并提供更好的描述。

三、 协议:非代码社区共识

        FRR存储库有一个“协议”的地方——这些是FRR的考虑事项,会影响我们作为一个社区的工作方式,但要么还没有产生代码,要么可能永远不会产生代码。它们被放在`doc/accords/``目录中。

        一般的想法是通过我们的常规PR程序简单地传递文本的小简介,使它们具有与代码PR相同的可见性、注释和审查机制,稍后更改它们是另一个PR。有关更多详细信息,请参阅`doc/accounts/``中的自述文件。该目录中项目的文件名有望有助于确定其中一些项目是否与您的工作相关。

四、 提交修补程序和增强功能

        FRR接受使用GitHub拉取请求的修补程序。

        新贡献和非关键错误修复的基本分支应该是“master”。提交提取请求时,请确保您的提取请求基于此分支。

        通过拉取请求提交的代码将由一个或多个CI系统自动测试。一旦自动化测试成功,其他开发人员将审查您的代码的质量和正确性。在解决了任何问题后,您的代码将被合并到提交时所针对的分支中。

        拉取请求的标题应提供所包含修补程序的高级技术摘要。描述应提供额外的详细信息,以帮助审查人员了解所包含补丁的上下文。

        4.1 压扁提交

        在合并之前,请确保PR已经压制了以下类型的提交:

  1. 修复/审查反馈
  2. 拼写错误
  3. 合并和重新基准
  4. 正在进行的工作

        这有助于自动生成人类可读的变更日志消息。

        4.2 提交指南

        有一个内置的提交linter。基本规则:

        A. 提交消息必须以更改的子系统的名称为前缀,后跟冒号和空格,并以命令动词开头。

        B.检查<https://github.com/frrouting/frr/tree/master/.github/commitlint.config.js>`_所有支持的子系统。

        C.提交消息必须以大写字母开头

        D.提交消息不能以句点“.”结尾

        4.3 为什么我的拉取请求被关闭了?

        超过180天的拉取请求将被关闭。对于具有活动审核意见的拉取请求,或者正在等待其他相关拉取请求的请求,可以例外。关闭的拉取请求很容易重新创建,并且关闭随后需要重新打开的拉取申请几乎不会损失工作。

        我们希望将传输中的提取请求总数限制为:

        A.保持项目清洁

        B.删除旧的拉取请求,因为底层代码随着时间的推移而发生了变化,所以这些请求很难重新建立基础

        C.鼓励代码速度

        4.4 贡献许可证

        FRR拥有“GPLv2或更高版本”的许可证。提交的任何代码都必须根据相同的许可证(首选)或允许根据GPLv2许可证(如MIT许可证)重新分发的任何许可证发布。禁止推送任何阻止使用GPLv3许可证的代码。这成为了一条社区规则,因为FRR生成与Apache2.0库链接的二进制文件。Apache 2.0和GPLv2许可证如果放在一起,是不兼容的。请参阅`<http://www.apache.org/licenses/gpl-compatibility.html>`_了解更多信息。此规则保证用户在没有任何许可问题的情况下分发FRR二进制代码。

        4.5 提交前检查表

        A.格式化代码(请参阅`code Formatting<#code formating>`__)

        B.验证并确认许可证(请参阅:ref:`license-for-contributions')

        C.确保您已正确签署(请参阅:ref:`signing-off')

        D.具有各种配置的测试用例:   -  ``buildtest.sh`

        E.验证编译源分布:   -  ``make dist`` (and try rebuilding from the resulting tar file)

        F.运行单元测试:     -  ``make test``

        G.如果出现重大新功能或其他重大更改,请记录该功能的持续维护计划。此外,还要求必须编写自动化测试,以便在我们现有的CI基础架构中使用新功能。此外,还鼓励增加自动测试以覆盖任何拉取请求。

        H.所有新代码都必须使用可接受代码的当前最新版本。

                a.如果守护进程被转换为YANG,那么新代码必须使用YANG。

                b.DEFPY必须用于新的cli

                c.必须使用类型安全列表

                d.必须使用printf格式更改

        4.6 签名

        提交给FRR的代码必须经过签名。我们对使用经过签名的进程的要求与Linux内核相同。简而言之,您必须在每个修补程序中包含一个“Signed off by”标记。

        一个简单的方法是使用“git commit-s”,其中“-s”将自动在提交消息的末尾附加一个签名行。此外,如果您提交并忘记添加行,则可以使用“git-commit--modify-s”将已签名的行添加到最后一次提交中。

        ``Signed-off-by“”签署的是开发者的证书,证明他们有权提交补丁以纳入项目。这是对以下内容的协议:ref:`Developer's Certificate of Origin <developers-certificate-of origin>`。没有正确的“signed-off-by”行签名的代码不能也不会被合并。

   如果你不熟悉这个过程,你应该阅读kernel.org上的官方政策<https://www.kernel.org/doc/html/latest/process/submitting-patches.html>`。你也可以找到这篇文章<http://www.linuxfoundation.org/content/how-participate-linux-community-0>`关于参与Linux基金会网站上的Linux社区,成为一个有用的资源。

        简言之,当你签署承诺时,你就对以下所有事项表示同意:

        开发起源证书1.1

        通过对本项目的贡献,我证明:

        (a) 该贡献全部或部分由我创建,我有权根据文件中所示的开源许可提交;或

        (b) 据我所知,我的贡献是基于以前的作品,这些作品属于适当的开源许可证,根据该许可证,我有权根据文件中所示的相同开源许可证提交修改后的作品,无论是全部还是部分由我创建的(除非我被允许根据不同的许可证提交);或

        (c) 捐款是由其他认证(a)、(b)或(c)的人直接提供给我的,我没有修改。

        (d) 我理解并同意,本项目和贡献是公开的,贡献的记录(包括我提交的所有个人信息,包括我的签字)将无限期保存,并可能根据本项目或所涉及的开源许可证进行重新分发。

        4.7 提交更改后

  1. 关注持续集成(CI)测试结果       
    1. 您应该在提交后不到2小时内自动收到一封包含测试结果的电子邮件。如果您没有收到电子邮件,请检查GitHub拉取请求的状态。
    2. 如果您认为有些东西不起作用,请通知开发邮件列表。
  2. 如果测试失败:
    1.  一般来说,希望社区在测试通过之前忽略提交的内容。
    2.  由您来修复并重新提交。
      1. 这包括修复现有的单元(“进行测试”)测试,如果您的更改破坏或更改了它们。
      2. 它还包括为出现故障的平台修复分发包(即,如果需要新的库)。
      3. 请随时在开发列表中寻求帮助。
    3. 返回到提交过程并重复,直到测试通过。
  3. 如果测试通过:
    1. 等待审阅者。有人将审查您的代码或被指派审查您的编码。
    2. 在所有评论和问题都得到解决后,希望您的补丁被合并。
    3. 当自动生成的评论不是来自该自动评论源的最新结果时,作者和其他人可能会删除自动生成的注释,例如CI系统生成的评论。
    4. 至少只要有负面的CI结果或负面的评论,作者就有责任保持PR的进展。如果您忘记将评论标记为已处理(通过单击“重新请求评论”),评论人很可能不会注意到,也不会回到您的PR。
    5. 当你处理了某人的评论后,请单击“重新请求评论”按钮(在PR页面的右上角,在评论人姓名旁边,有一个看起来像“重新加载”的图标)
    6. 作者不得删除或手动驳回他人的评论或评论。(审查可在每周技术会议上通过协议推翻。)
    7. 回应评审员的任何意见或顾虑。使用电子邮件或通过github添加评论来回复或让审查者知道他们的评论或担忧是如何解决的。
  4. 注意邮件列表上的问题。此时,将由各个社区成员进行手动代码审查和进一步的(更长的)测试。
  5. 一旦您的提交被合并到master分支,它就完成了。

五、程序设计语言、工具和库

        FRR的核心是用C编写的(支持gcc或clang),并使用GNU编译器扩展。一些非必要的脚本是用Perl和Python实现的。FRR需要以下工具来构建分发包:automake、autoconf、texinfo、libtool和gawk以及各种库(即libpam和libjson-c)。

        如果您的贡献需要一个新的库或其他工具,请在您对更改的描述中强调这一点。还要确保它得到所有FRR平台操作系统的支持,或者提供一种在其他平台上不使用库(可能没有新功能)进行构建的方法。

        文档应使用reStructuredText编写。可以使用Sphinx扩展,但在可能的情况下最好使用纯ReST。请参阅:ref:`documentation`。

        5.1 C++的使用

        虽然FRR的核心组件不接受C++,但扩展、模块或其他不同的组件可能希望使用C++并包括FRR头文件。没有要求贡献者努力保持C++兼容性,但欢迎对C++兼容性进行修复。

        这意味着保持C++兼容性的工作负担是由需要它的人承担的,他们可以在空闲时提供对他们有用的东西。因此,如果只有头文件的一个子集,甚至头文件的部分对C++可用,这是完全可以的。

六、代码评审

        代码质量对于任何大型程序来说都是至关重要的。因此,我们要求在合并补丁之前,至少由提交者以外的一个人对所有提交的补丁进行审查。

        由于软件的性质,FRR的维护者列表(即具有提交权限的维护者)往往包含各种组织的员工/成员。为了防止利益冲突,我们使用了一种荣誉制度,即代表一家公司的个人提交的材料应由与该公司无关的人合并。

        6.1 代码审查指南

  1. 根据经验,审查的深度应与补丁的范围和/或影响成比例。
  2. 任何人都可以查看补丁。
  3. 当使用GitHub评论时,在代码评论上标记“批准”表示愿意合并PR。
  4. 对于拥有合并权限的个人,标记“Changes requested”相当于NAK。
  5. 对于您标记为“Changes requested”的PR,请及时回复更新,以避免阻碍开发流程
  6. 被拒绝或过时的PR通常由提交者根据PR评论中的请求和/或协议关闭。评论可能源于Slack、开发邮件列表或每周技术会议上达成的审查人或文件协议。
  7. 如果评审员认为代码更改足够大/足够重要,足以满足这样的要求,他们可能会要求进行新的自动化测试。

对于具有合并权限的项目成员,出现了以下模式:

  1. 具有任何要求更改的审查的PR不得合并。
  2. 具有任何负CI结果的PR可以不被合并。
  3. 开放的“黄色”审查标记(“要求审查,但未完成”)应给予一些时间(几天到几周,取决于PR的大小),但不是合并阻止程序。
  4. “textbubble”评论标记(“评论,但不是正面/负面”)应该通读,但不是合并阻止符。
  5. 非琐碎的PR通常会有一些时间(同样取决于大小)让人们标记对审查的兴趣。当CI为绿色时,可以立即合并琐碎的PR。

七、编码实践与风格

        7.1 提交消息

        提交消息的格式应与Linux内核提交消息相同。格式大致为:

                dir:short summary

                extended summary

``dir“”应该是在其下进行更改的顶级源目录。例如,:file:`bgpd/rfpi`中的更改将格式化为:

                bgpd: short summary

                ...

        第一行的长度不应超过50个字符。后续行应换行为72个字符。

        提交消息的目的是简要总结提交正在更改的内容。因此,扩展摘要部分应采用英文段落的形式。程序输出的简短示例是可以接受的,但如果存在,则应简短(大约10行),并清楚地说明发生了什么变化。目标应该是,只对有问题的代码稍微熟悉一点的人就可以理解正在更改的内容。

        完全由程序输出组成的提交消息是不可接受的。这些并没有描述行为的改变。例如,将VTYSH输出或测试运行的结果作为提交消息的唯一内容是不可接受的。

        您还必须签署您的承诺。

        7.2 源文件头

        新文件必须在文件中添加版权标头(请参见上面的:ref:`license for contributions `)。标题应为:

        请逐字复制粘贴此标题。特别是:

  1. 不要将“此程序”替换为“FRR”
  2. 不要更改FSF的地址
  3. 保留``#include<zebra.h>``。任何C文件中包含的绝对第一个标头必须为`zebra.h ``或`config.h ``(带HAVE_config_h保护)

        7.3 将版权声明添加到现有文件

        在为修改现有文件添加版权声明时,请添加“部分:”部分,如下所示。如果此部分已经存在,请在列表末尾添加您的新声明。

        7.4 防御性编码要求

        一般来说,如果提交到FRR的代码使用了不安全的编程实践,它将被拒绝。虽然没有强制执行的总体规则集,但以下要求已达成共识:

  1. ``strcpy“”、“strcat”和“sprintf”无一例外都是不可接受的。请改用“strlcpy”、“strlcat”和“snprintf”。(理由:即使您知道操作不能使缓冲区溢出,未来的代码更改也可能会无意中导致溢出。)
  2. 缓冲区大小参数,特别是“strlcpy”和“snprintf”的参数,必须尽可能使用“sizeof()”。特别是,在这些情况下不要使用大小常数。(理由:将缓冲区更改为另一个大小常数可能会使写入操作的大小限制现在不正确。)
  3. 对于应该为零初始化的堆栈分配的结构和数组,尽可能使用初始化器表达式而不是“memset()”。这有助于防止分支中丢失“memset()”调用,并消除“memset”()参数的错误“size”类。

例如,不能是如下:

而应该是:

        4.不要对堆栈分配的值进行零初始化,这些值必须使用非零值进行初始化才能使用。通过这种方式,编译器和内存检查工具可以捕获未初始化的值使用,否则这些值将被(不正确的)零初始化所抑制。

        除了这些特定的规则之外,Linux内核的编码实践以及CERT或MISRA C指南可能会为安全的C代码提供有用的输入。然而,这些规则并没有按原样适用;其中一些显然与既定做法相冲突。

        7.5 容器实现

        特别是为了从更好的编译器类型检查中获得防御性编码优势,可以在:file:`lib/typesafe.h`中找到一组替换容器数据结构。它们记录在:ref:`lists`下。

        不幸的是,FRR代码库相当大,迁移现有代码以使用这些新结构是一个乏味而深远的过程(即使它可以用coccinele实现自动化,补丁也会接触到整片代码,并为正在进行的工作产生大量合并冲突。)因此,几乎没有迁移现有代码。

        但是,**新代码和现有代码的重构都应该使用新容器**。如果有任何原因无法做到这一点,请努力消除这些原因(例如,通过向新容器添加必要的功能),而不是回到旧代码。

        按照拆卸的顺序,这些是旧容器:

        7.6 代码格式化

        7.6.1 C语言代码

        对于C代码,FRR使用Linux内核风格,除非下面有说明。不符合这些风格准则的代码将不被接受。

        该项目提供了多种工具,使您能够尽可能轻松地正确地设计代码样式,主要围绕“clang format”构建。

        clang-format:

        在项目根目录中有一个:file:`.clang-format`配置文件,该文件可与LLVM项目中的`clang-format``源格式化程序工具一起使用。大多数时候,这是最简单、最聪明的工具。它可以用多种方式运行。如果您将其指向C源文件或源文件目录,它将格式化所有源文件。在LLVM源代码树中,有一些脚本允许您将其与“git”、“vim”和“emacs”集成,还有用于其他编辑器的第三方插件。“数字”一体化特别有用;假设您的git索引发生了一些更改。然后,安装集成后,您可以执行以下操作:

                         git clang-format

      这将只格式化索引中的更改。如果您刚刚进行了几次提交,并且只想正确地设置这些提交中所做更改的样式,则可以使用以下语法:

                        git clang-format HEAD~X  

        其中,X比您希望“clang format”查看的从分支顶端返回的提交数多出一个(类似于指定rebase的目标).

        “vim”插件特别有用。它允许您在可视行模式下选择行,并按下键绑定仅在这些行上调用“clang format”。

        使用“clang格式”时,建议使用最新版本。每个连续的版本通常都能更好地处理各种边缘情况。您有时可能会注意到,在同一代码上连续运行两次“clang format”可能会导致在第二次运行时发生更改。这是一个不幸的工具工件。如果有疑问,请参阅内核样式指南。

        FRR代码库的一个风格问题是使用“DEFUN”宏来定义CLI命令``clang-format``很乐意格式化这些宏调用,但结果往往很难看,很难阅读。因此,FRR对这些文件的格式采取了更宽松的立场。一般来说,您应该倾向于使用:ref:`命令行界面'一节中举例说明的样式。因为“clang format”破坏了这种风格,所以有一个名为“tools/intent.py”的Python脚本包装“clang form”并处理“DEFUN”宏以及FRR特有的其他一些边缘情况。如果您正在提交一个新文件,建议您在新文件上运行该脚本,最好是在确保“clang format”的最新稳定版本在您的“PATH”中之后。

   关于“clang-format”及其各种集成的文档保存在LLVM网站上。   https://clang.llvm.org/docs/ClangFormat.html

checkpatch.sh

        在Linux内核源代码树中,有一个Perl脚本用于检查传入的补丁是否存在样式错误。FRR出于同样的目的使用了该脚本的改编版本。它可以在以下位置找到:file:`tools/checkpatch.sh`。此脚本采用git格式的diff或补丁文件,将其应用于干净的FRR树,并检查结果以捕捉潜在的样式错误。强烈建议在提交之前在修补程序上运行此脚本。CI系统也会运行此脚本,如果发现样式错误,将对PR和结果进行评论。

  它是这样运行的:

                ./checkpatch.sh <patch><tree>

    在“stderr”上生成报告,退出代码指示是否发现问题,发现(2,1),未发现(0)。

        其中“<patch>”是diff或patch文件的路径,“<tree>”是FRR源树的路径。树应该位于要提交修补程序的分支上。脚本将尽最大努力在应用修补程序之前保存工作树和索引的状态,并在完成后恢复它,但仍然建议您有一个干净的工作树,因为脚本在运行过程中确实会对树执行硬重置。

        脚本报告两类问题,即警告和错误。请注意他们两个。脚本通常会在无法100%确定特定问题是否真实的情况下报告警告。在大多数情况下,警告表示需要解决的问题。有时脚本会报告误报;这些将在代码审查中根据具体情况进行处理。由于脚本只查看更改的行,偶尔更改行的一部分可能会导致脚本报告该行上已经存在的与更改无关的样式问题。在方便的时候,最好是在线清理,但这不是必须的。

        一般来说,开发人员应该注意checkpatch报告的信息。然而,对于人工判断比脚本更清晰的情况,需要一些灵活性。因此,在更改的提交者和审阅者之间的每次讨论中,忽略一些checkpatch.sh警告可能是合适的。脚本可能会误报错误。发生这种情况时,应通过修补checkpatch以更正错误报告,或通过在以下文档中记录异常:ref:'style-exceptions'来处理异常。如果错误的报告可能再次出现,则首选检查补丁更新。

        如果脚本找到一个或多个警告,它将以1退出。如果它发现一个或多个ERROR,它将以2退出。

        请记住,虽然FRR提供这些工具是为了方便您,但正确格式化代码的责任最终落在提交者的肩上。因此,建议仔细检查这些工具的结果,以避免合并提交时出现延迟。

        在某些情况下,这些工具修改或标记格式的方式超出了规范文档化的Linux内核样式,甚至与之冲突[#tool_style_conflicts]。在这些情况下,Linux内核风格优先;工具标记的非规范问题不是强制性的,而是变更提交者和审查者之间讨论的机会。

        **在更改实际代码的修补程序中,不接受对代码未受影响部分进行空白更改。**若要更改/修复格式问题,请创建一个单独的修补程序,只进行格式更改,不进行其他更改。

        内核和BSD样式在外部有文档记录:

-  https://www.kernel.org/doc/html/latest/process/coding-style.html

-  http://man.openbsd.org/style

        对于GNU编码风格,请在以下调用中使用“indent”:

                indent -nut -nfc1 file_for_submission.c

        从历史上看,FRR使用的是固定宽度积分类型,这些类型在任何标准中都不存在,但在某些时候由大多数平台定义。官方并不保证这些类型的存在。因此,在为FRR贡献新代码时,请使用C99标准中引入的固定宽度积分类型。如果您需要转换大量代码以使用正确的类型,那么:file:`tools/convert-fixedwidth.sh`中有一个shell脚本,它将执行必要的更换。

        FRR还使用未命名的结构字段,这些字段通过`-fms扩展``启用(参见。https://gcc.gnu.org/onlinedocs/gcc/unnamed-fields.html)。在上下文适当的情况下,可以/应该使用以下两种模式:

A. 异常:

        FRR项目代码来自多种来源,因此存在一些风格上的例外。他们在这里按部门组织。

对于 ``master``:

BSD编码风格适用于:

        ``ldpd/``

``babeld``大致使用以下样式:

  1. K&R样式大括号
  2. 缩进为4个空格
  3. 函数返回类型在它们自己的行上

对于``stable/3.0`` 和 ``stable/2.0``:

GNU编码风格适用于以下部分:

  1. ``lib/``
  2. ``zebra/``
  3. ``bgpd/``
  4. ``ospfd/``
  5. ``ospf6d/``
  6. ``isisd/``
  7. ``ripd/``
  8. ``ripngd/``
  9. ``vtysh/``

BSD编码风格适用于:

        ``ldpd/``

        7.6.2 Python 代码

        使用`black设置所有Python代码的格式<https://github.com/psf/black>`_。

                python3 -m black <file.py>

        在提交之前,在您修改的任何Python文件上运行此操作。

        FRR的Python代码已被格式化为黑色19.10b版本。

        7.6.3 YANG

        FRR使用YANG为其北向接口定义数据模型。YANG模型应该遵循IETF标准模型所使用的约定。从实用的角度来看,这与“libyang”项目中包含的“yanglint”工具产生的输出相对应,FRR使用该工具来解析和验证YANG模型。您应该对您编写的所有YANG文档运行以下命令:

                yanglint -f yang <model>

        此命令的输出应与输入文件相同。唯一的例外是评论``yangliint“”不支持评论,并将从其输出中删除这些评论。您可以在YANG文档中包含注释,但它们应该适当缩进(使用空格)。在可能的情况下,应避免发表评论,而采用适当的“说明”语句。

        简而言之,您的输入文件和“yangliint”的输出之间的差异应该为空或仅包含注释。

        7.6.4 特殊例外情况

        大多数情况下,应该更正checkpatch错误。偶尔,作为一个团队,维护人员会决定忽略某些风格问题。通常情况下,这是因为如果没有大量不相关的代码更改,就不可能纠正问题。当出现异常时,如果它不太可能再次出现,并且不保证更新checkpatch,则在此处进行记录。

        7.7 配置项类型

        整个部分基本上只是为了避免对用户进行不必要的配置。与其说是规则,不如说是一系列结论,旨在帮助运营商使用FRR。

        FRR的几乎每一个功能都有自己的一组开关和选项。有几个阶段可以应用配置。按照偏好的顺序,这些是:

  1. 在配置/运行时,通过YANG.

   这是所有FRR旋钮的首选方式。并不是所有的守护进程和功能都是完全YANG化的,所以在某些情况下,新功能不能依赖于YANG接口。如果守护进程已经实现了YANG接口(甚至是部分接口),则必须通过YANG模型实现新的CLI选项。

   (警告:与本节中的其他内容不同的是,在YANGified守护进程中(甚至部分!)为新的CLI选项实现和使用YANG接口是一项艰巨的要求。)

        2. 在配置/运行时,通过CLI。

  所有常规配置的“good old”方式。与YANG相比,用户更容易实现自动化。

        3. 在启动时,通过加载额外的模块。

   如果某个功能引入了对其他库(如libsnmp、rtrlib等)的依赖,这是封装依赖的最佳方式。有了一个单独的模块,分发版就可以创建一个具有额外依赖性的单独包,因此FRR仍然可以在不引入所有内容的情况下安装。

   如果一个功能很大并且隔离得相当好,那么模块也可能是合适的。减少运行代码的数量是一个安全优势,因此即使没有新的外部依赖项,模块也会很有用。

   虽然模块目前无法在运行时加载,但这是一个折衷决定,允许模块更改/扩展在运行时很难(重新)调整的代码。如果存在模块运行时(卸载)加载的情况,则绝对可以重新评估这种折衷。

        4. 在启动时,使用命令行选项。

   此接口仅适用于在FRR启动初期(即加载配置之前)具有效果的选项。任何影响配置负载本身的东西都应该在这里,以及更改FRR运行环境的选项。

   如果可在运行时更改可调项,则只有在加载配置之前配置的值有效的情况下,命令行选项才是可接受的(例如,zebra在加载配置前从内核读取路由,因此netlink缓冲区大小是一个合适的命令行选项。)

        5. 在编译时,使用`` ./configure “”选项。

   这是对可调值的最后一个绝对偏好,因为分发需要为用户做出决定和/或用户需要重建FRR以更改选项。

  “good”的配置选项可以做以下三件事之一:

  • 设置特定于分发的参数,最突出的是所有路径选项。文件系统布局是一种分发/打包选择,因此用户希望永远不需要调整这些布局。
  • 更改工具链行为,例如检测、警告、优化和清理程序。
  • 启用/禁用构建的某些部分,尤其是当它们需要额外的依赖项时。能够只构建FRR的一部分,或者不构建一些库,这是很有用的**这些选项的唯一效果是在生成结果中添加或删除文件。**如果此类别中的旋钮导致相同的二进制文件存在于不同的变体中,则可能是错误实现的!

    最后一条准则当前被几个配置选项忽略``vtysh“”通常取决于已启用守护程序的整个列表,而“--enable-bgp-vnc”和“--enableospfapi”等选项会在内部更改守护程序。与其说这是“规则”,不如说这是一种“理想”。

        每当添加新旋钮时,请尽可能地在上面的列表中向上移动。尤其是``/configure“”标志通常是“简单的出路”,但应尽可能避免。在较小程度上,这同样适用于命令行选项。

        7.8 编译时条件代码

        许多用户通过第三方来源的二进制包访问FRR;编译时代码将包含/排除交给包维护人员。在编译时使代码成为条件代码之前,请仔细考虑,因为这会增加回归测试、维护负担和用户困惑。特别是,请避免无端地“--enable-…”切换到配置脚本——通常,代码应该是高质量的,并且处于工作状态,或者根本不应该处于FRR中。

        当代码必须是编译时有条件的时,请尝试让编译器将其设为有条件的,而不是C预处理器,这样即使被禁用,编译器仍会对其进行检查。例如

        请注意,前一种方法需要确保定义“SOME_SYMBOL”(注意您的“AC_DEFINE”)。

        7.9 调试代码中的保护程序

        调试语句是一种重要的方法,允许开发人员在代码发布后修复代码中发现的问题。这里需要注意的是,开发人员必须记住,人们将以原始实现者意想不到的规模和方式使用代码。因此,必须以可以关闭的方式保护**调试。FRR能够从CLI打开/关闭调试,预计开发人员将使用此约定来控制其调试。

        7.10 自定义语法,如块宏

        FRR使用一些宏,它们的行为类似于“for”或“if”C关键字。这些宏遵循以下模式:

  1. 循环样式的宏名为`frr_each_*`(和`frr_etch``)
  2. 单次运行的宏名为``frr_with_*``
  3. 为了避免混淆,“frrwith_*”宏必须始终使用“{…}”块,即使该块只包含一条语句。假定“frr_each”结构足够众所周知,可以使用正常的“for”规则。
  4. “break”、“return”和“goto”都能正常工作。对于循环样式的宏,“continue”也能正常工作。

        “each”和“with”关键字都受到提供这些结构的其他(更高级的)编程语言的启发。

        还有一些较旧的迭代宏,例如“ALL_LIST_ELEMENTS”和“FOREACH_AFI_SAFI”。在某些情况下,这些宏***不满足上述模式(例如,“break”在“FOREACH_AFI_SAFI”中不起作用,因为它扩展到2个嵌套循环。)

        7.11 静态分析和Sanitizers

        Clang/LLVM和GCC提供了各种工具,可用于帮助查找FRR中的错误。

        clang-analyze

        这是一个静态分析器,它扫描源代码,寻找可能是bug的模式。作为CI的一部分,该工具将在拉取请求时自动运行,并且新的静态分析警告将放置在CI结果中。FRR的目标是绝对零静态分析误差。虽然该项目还没有完全实现,但引入新的静态分析错误的代码不太可能被合并。

        AddressSanitizer

        这是一个出色的工具,它提供了用于检测内存错误的运行时检测。作为CI的一部分,FRR是使用此仪器构建的,并通过一系列测试来寻找任何结果。鼓励在提交之前使用此工具测试您自己的代码。您可以通过以下方式启用它:

                --enable-address-sanitizer

      ThreadSanitizer

        与AddressSanitizer类似,此工具提供用于检测数据竞赛的运行时检测。如果您正在处理多线程代码或围绕多线程代码工作,强烈建议您启用此指令进行广泛的测试。您可以通过以下方式启用它:

                --enable-thread-sanitizer

       MemorySanitizer

        与AddressSanitizer类似,该工具提供了用于检测未初始化堆内存使用情况的运行时检测。鼓励在提交之前使用此工具测试您自己的代码。您可以通过以下方式启用它:

                --enable-memory-sanitizer

        自3.4起,Clang/LLVM工具链中提供了上述所有工具。AddressSanitizer和ThreadManitizer在GCC的最新版本中可用,但不再主动维护。MemoryManitizer在GCC中不可用。  不同的Sanitizers大多彼此不兼容。有关详细信息,请参阅GCC/LLVM文档。

frr-format plugin

   这是一个与FRR一起提供的GCC插件,它对“%pFX”样式的printfrr扩展进行扩展类型检查。要使用此插件,

   安装GCC插件开发文件, e.g.::

                apt-get install gcc-10-plugin-dev

   在运行“configure”之前,请使用以下代码编译插件:

                make -C tools/gcc-plugins CXX=g++-10

            (将GCC版本编辑为您正在使用的版本,它应该适用于GCC 9或更新版本。)

        在此之后,插件应该由`configure``自动拾取。该插件不会经常更改,因此您可以在不同FRR分支的工作中保留它。在“git clean-x”之后,将需要再次运行“make”行。您也可以在“configure”行中添加“--withfrr format”,以确保使用插件,否则,如果设置不正确,它可能会被忽略。

   注意: 请勿为软件包/发布版本启用此插件。它仅适用于开发人员/调试版本。由于它会修改编译器,因此可能会导致可执行文件的静默损坏。 使用该插件还将“PRI[udx]64”的字符串从系统值更改为“%L[udx]]”(通常为“%L[udx]”或“%L[idx]]”)

        此外,使用Coverity定期扫描FRR码库。不幸的是,Coverity无法处理扫描拉取请求,但在代码合并后,它会发送一封电子邮件,通知具有Coverity访问权限的项目成员新引入的缺陷。

        7.12 执行未安装的动态二进制文件

        由于FRR使用GNU自动工具构建系统,它继承了它的缺点。要在“valgrind”、“gdb”或“strace”等包装器下直接从构建树执行二进制文件,请使用:

                   ./libtool --mode=execute valgrind [--valgrind-opts] zebra/zebra [--zebra-opts]

        根据需要更换valgrind/zebra时。“libtool”脚本位于“”之后的生成目录的根目录中/configure’已完成。其目的是正确设置“LD_LIBRARY_PATH”,以便使用构建树中的库。(在某些系统上,PATH中也提供了“libtool”,但情况并非总是如此。)

        7.13 CLI更改

        CLI是一头复杂而丑陋的野兽。对CLI的添加或更改应使用DEFPY尽可能多地封装一个设置。此外,当新的DEFPY添加到系统中时,应为新命令提供文档。

        7.14 向后兼容性

        一般来说,对CLI和lib/目录中的代码的更改应该以向后兼容的方式进行。这意味着应避免纯粹风格上的更改,例如,在没有任何功能更改的情况下重命名现有宏或库函数名。当向公共函数添加新参数时,最好考虑是否也应该以向后兼容的方式进行,例如,除了添加新形式之外,还保留旧形式。

        这并不是说应该避免对CLI和通用代码进行微小甚至重大的功能更改,而是应该权衡从更改中获得的好处与现有代码增加的成本/复杂性。此外,在进行此类更改时,尽可能在不引入维护开销/成本的情况下保持兼容性是很好的。同样重要的是要记住,现有代码包括可能驻留在私有存储库中的代码(尚未提交)或尚未从Quagga迁移到FRR的代码。

        也就是说,当出现以下情况之一时,可以(也应该)取消兼容性措施:

  1. 它们会成为一个巨大的负担,例如当数据结构发生变化,兼容性度量需要一个复杂的适应层或变得完全不可能时
  2. 某些时间(取决于具体情况)已经过去,因此兼容性宽限期被视为已过期。

        对于CLI命令,弃用期为1年。在任何情况下,兼容性部件都应标记有编译器/预处理器注释,以便在编译时打印警告,指向适当的更新路径。如果使用兼容位,“-Werror”构建应该会失败。为了避免已发布代码中的编译问题,必须在非开发分支中忽略此类编译器/预处理器注释。例如:

        最好在进行不向后兼容的代码更改的同时更新shell脚本:file:`tools/fifix-up-deprecated.py`,或者应该引入一个替代脚本来更新代码以匹配更改。更新脚本时,不需要保留不推荐使用的代码。请注意,这不适用于用户界面更改,仅适用于内部代码、宏和库。

        7.15 Miscellaneous

        如果有疑问,请遵循Linux内核风格指南中的指导原则,或询问开发邮件列表/公共Slack实例。

        7.15.1 JSON输出

        FRR中新的JSON输出需要有模式支持,特别是YANG模型。添加新的JSON时,首先在FRR或标准模型(例如IETF)中搜索现有的YANG模型,并将该模型用作任何JSON结构的基础,特别是关键字名称和规范值格式的基础。

        如果不存在支持JSON的YANG模型,则需要添加或创建一个FRR YANG模型来支持JSON格式。

  1. 所有JSON键都是“基于camelBased”,不带空格。YANG模块几乎总是使用“kebab大小写”(即,所有小写字母都用连字符分隔单词),因此这些标识符需要通过删除连字符(或符号)并将以下字母大写来映射到“camelCase”,例如“router id”变为“routerId”
  2. 如果没有可显示的内容,则输出JSON的命令应生成“{}”
  3. 通常,JSON命令包括一个“JSON”关键字,通常位于CLI命令的末尾(例如,“show ip ospf JSON”)

        7.15.2 常量的使用

        请考虑在可能的情况下使用“const”:这是一个有用的提示,可以提示调用方有关api副作用的限制,并且可以在涉及“const“对象的路径中使用api。如果您遇到的现有api*可能是“const”,请考虑在您自己的pull请求中包含更改。

        7.15.3 有关特定警告的帮助

        FRR的配置脚本启用了一整批额外的警告,其中一些警告在如何修复方面可能并不明显。以下是关于具体警告的一些注意事项:

  • * ``-Wstrict原型“”:您可能只是忘记了一个没有参数的函数声明中的“void”,即“static void foo(){…}”而不是“static void foo(void){.}”。

  (如果没有“void”,在C中,它是一个具有*个未指定*个参数(以及varargs调用约定)的函数。这与C++有一个显著的区别,在C++中,“void”是可选的,空的参数列表意味着没有参数。)

* ``frr格式插件中的“strict match required”``:检查您是否在printf参数列表中使用强制转换。frr格式插件无法访问诸如“printfrr(…,(uint64_t)something,…)”之类的类型转换的正确完整类型信息并且将打印不正确的警告,特别是在涉及“uint64_t”、“size_t”或“ptrdiff_t”的情况下。问题不是由完全相同类型的变量或函数返回值触发的(没有强制转换)。

        由于这些情况非常罕见,社区的共识是,即使代码可能是正确的,也要围绕警告进行工作。如果您遇到这种情况,您的选择是:

  1. 尝试完全避免强制转换,可能使用不同的printf格式说明符(例如“%lu”而不是“%zu”或“PRIu64”).
  2. 修复正在打印的函数/变量/结构成员的类型
  3. 创建一个具有值的临时变量,并在没有强制转换的情况下打印该变量(这是最后的手段,到目前为止在任何地方都没有必要)

八、文档系统

        FRR使用Sphinx+RST作为其文档系统。您当前正在阅读的文档由Sphinx从RST源生成,位于:file:`doc/developer/workflow.RST`。文档结构如下:

        除了:file:`doc/fiths'和:file:` doc/extra`之外,这些目录中的每一个都包含一个Sphinx生成的Makefile和配置脚本:file:'conf.py',用于设置各种文档参数。makefile可以用于各种目标;在这些目录中的任何一个目录中调用“make-help”以获取可用输出格式的列表。为了方便起见,有一个顶级文件:“Makefile.am”,它分别为开发人员文档和用户文档的PDF和HTML文档提供目标。该makefile还负责构建包含分发版本的手册页。

        缩进和样式应遵循现有约定:

  1. 3个空格用于指令下的缩进
  2. 交叉引用只能包含小写字母数字字符和连字符('-')
  3. 尽可能换行到80个字符

        标题级别的字符应遵循Python文档指南:

  1.  ``#`` with overline, for parts
  2.  ``*`` with overline, for chapters
  3.  ``=``, for sections
  4.  ``-``, for subsections
  5.  ``^``, for subsubsections
  6.  ``"``, for paragraphs

        进行更改后,请确保您可以在没有警告的情况下调用“make latexpdf”和“make html”。

        文件目前不完整,需要关爱。如果您发现交叉引用、图形、死超链接、样式问题或任何其他肮脏之处,我们很乐意接受文档补丁。

   要构建文档,请确保您安装了最新版本的“Sphinx”<http://www.sphinx-doc.org/en/stable/install.html>`_。如果你想构建LaTeX或PDF文档,你还需要安装完整的LaTeX发行版。

        8.1 代码

        FRR是一个庞大而复杂的软件项目,由许多不同的人在很长一段时间内开发。如果没有足够的文档,就很难理解代码段、API和其他接口。为了保持项目的健康和可维护性,您应该尽一切努力记录您的代码,以便其他人能够理解它的作用,而无需仔细阅读代码本身。

        贡献者应遵循的一些具体准则是:

  1.         1. 头文件中公开的函数在头文件中的签名上方应该有描述性注释。函数注释至少应包含有关返回值、参数和函数用途的一般摘要的信息。如果参数值的用途(非常)明显,则可以省略参数值的文档。
    1.         2. 函数注释必须遵循内核样式指南中列出的多行注释的样式。

         函数注释应明确参数和返回值的用途。

  1. 如果静态函数的作用不是很明显,那么它们应该具有与上面相同形式的描述性注释。在决定是否有必要发表评论时,要运用良好的工程判断。如果您不确定,请记录您的代码。
  2. 全局变量,无论是否静态,都应该有一个描述其使用的注释。
  3. **对于lib/中的新代码,这些准则是硬性要求。**

        如果您对《开发人员手册》中涵盖的代码库部分进行了重大更改,添加了一个主要的子系统或功能,或者对代码库中一些未记录或记录不足的部分进行了神秘的掌握,请记录您的工作,以便其他人受益。如果您添加了一个主要功能或引入了一个新的API,请在开发人员手册中尽您所能记录架构和API,并在选择放置位置时使用良好的判断。

        最后,如果您遇到一些未记录的代码,并想超越它,请记录它!我们绝对感谢并接受记录以前未记录代码的补丁程序。

        8.2 用户

        如果您提供的代码添加了重要的用户可见功能,请在:file:`doc/user`中记录如何使用它。在选择放置文档的位置时要有良好的判断力。例如,关于如何使用新BGP草案的实现的说明应在BGP章节中,而不是它自己的章节。如果您正在添加一个新的协议守护程序,请创建一个新章节。

        8.3 FRR特殊标记

        FRR对Sphinx标记进行了一些自定义,这些自定义大大有助于使文档更易于使用、编写和维护。

        8.3.1 CLI命令

        记录CLI时,请使用`..clicmd::``指令。此指令将自动格式化命令并生成索引条目。例如,命令:clicmd:'show pony'的文档如下:

        以这种方式记录时,CLI命令可以与``:clicmd:``内联标记交叉引用,如下所示:

        这对于想要快速提醒自己特定命令的作用的用户非常有帮助。

        当记录具有“no”形式的cli时,请不要包括“no”格式。即“no show pony”不会记录在任何地方。由于大多数命令都有“no”形式,用户应该能够推断出这些形式,或者从vtysh的补全中获得帮助。

        当记录具有许多可能变体的命令时,只需简要记录单个命令,而不是枚举每个可能的变体。例如,对于`show pony[foo|bar]``,不要:

        8.3.2 配置代码段

        放置示例配置块时,请使用``.. code-block:: ``指令,并指定`frr``作为突出显示语言,如下例所示。这将告诉Sphinx使用自定义Pygments-lexer来突出显示FRR配置语法。


  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!感谢提问。下面是有关 K210 学习笔记五中串口通信的一些内容: 在 K210 开发板上,串口是一种常见的通信接口,用于将数据从一个设备传输到另一个设备。串口通信通常使用 UART (Universal Asynchronous Receiver/Transmitter) 协议。 要在 K210 上进行串口通信,首先需要使用两个引脚:一个用于接收数据(RX),一个用于发送数据(TX)。这些引脚可以通过 GPIO 端口与外部设备连接。 在 K210 的开发环境中,可以使用 MaixPy 或者 Kendryte Standalone SDK 进行串口编程。 在 MaixPy 中,可以使用 `uart` 模块来进行串口通信。例如,要初始化一个串口对象并设置波特率为 115200,可以使用以下代码: ```python from machine import UART uart = UART(UART.UART1, 115200) ``` 然后,可以使用 `uart.write()` 函数发送数据,使用 `uart.read()` 函数接收数据。例如: ```python uart.write("Hello, world!\n") data = uart.read(10) ``` 在 Kendryte Standalone SDK 中,可以使用 `uart.h` 头文件中的函数来进行串口通信。例如,要初始化一个串口对象并设置波特率为 115200,可以使用以下代码: ```c #include "uart.h" uart_init(UART_DEVICE_1, 115200); ``` 然后,可以使用 `uart_send_data()` 函数发送数据,使用 `uart_receive_data()` 函数接收数据。例如: ```c uart_send_data(UART_DEVICE_1, "Hello, world!\n", 14); char buffer[10]; uart_receive_data(UART_DEVICE_1, buffer, 10); ``` 以上是关于 K210 学习笔记五中串口通信的简要介绍。如果你有更具体的问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值