用户工具

站点工具


knowledge:3d_print:2023052301

编码标准

当你在写与 Marlin 相关的代码时,请遵循以下规范。提交的代码若不接近当前的代码风格,那么会被要求更改。你的代码审核人员应该指出哪里需要被更改。

编码风格

缩进

缩进对于可读性与可维护性起着至关重要的作用,并且能让一些普通文本编辑器(TextMate,Sublime 等)正确地按照代码层级折叠代码。

  • 使用两个空格作为缩进,注意不要使用 <tab> 键,<tab> 会将你拉入无尽的深渊。
  • 使用所有的块元素包括 #if 及其他的预处理语句应该增加它的缩进:
    void myFunction() {
      if (myCondition == 0) {
        #ifdef PETER_PARKER
          slingWeb(100);
        #else
          findPhoneBooth();
        #endif
      }
    }

括号风格

Marlin 使用的括号风格有以下目的:

  • 在开始行的末尾显示已折叠的代码块:{ (…)
  • 保证代码的连续性以及形成统一的代码风格
  • 使在屏幕上显示代码的行数最大化

倘若垂直的缩进空格让代码的可读性更强,那么增加一个空行比使用不同的括号风格更好:

  • 来源于古老的“一个真正的括号风格”
  • 在行末写一个左括号:if (a == 1) {
  • 同样地,对于声明语句:void pizza(int slices) {
  • 同缩进的右括号保持垂直

“一个真正的括号风格”例子:

void my_function(void) {
  if (...) {
    ...
  }
  else {
    ...
  }
 
  switch (val) {
    case 1: SERIAL_CHAR('Q'); break;
    case 2: SERIAL_CHAR('T'); break;
  }
}

空格

  • 在控制关键字后加一个空格:if (…)while (…)do {…} while(…)switch (…) 等等。
  • sizeof() 这种类函数就不用加括号了。
  • 函数名与其参数之间不用加空格:val = myFunction(…);
  • . 操作符左右不用加空格:the_place = state→parks[echo];
  • 类型转换函数后不用加空格:old_state = (int)state;
  • 大多数二元及三元操作符要加空格:myVar = aVar + bVar * cVar; myVal = (a * b + b * c);

行末的空格

别在行末留空格。有些编辑器会在新行中自动增加缩进,从而你会活得拥有多余空格的行。 Git 会提示你那拥有多余空格的行,然后让你选择是否要去掉那些空格。但是一旦它帮你去掉了,之后的改动会很烦。

注释

注释是一个良好的习惯,但是别太沉醉于注释。永远不要在注释当中解释当前代码是如何运行的:写出一眼就能看出来工作机制的代码比这种注释要好得多,而且给很烂的代码写注释是一种浪费生命的行为。

一般情况下,注释所代表的是你的代码是干嘛的,而不是你的代码是如何工作的。在函数体中的注释应尽量的少。如果一个函数非常的复杂,你应该考虑分段地把注释写在函数中每个基本单元内。将细节代码写在函数头中,用于阐述它是干嘛以及为什么它要这么干。

  • 函数、类以等使用“D 型氧气”风格注释在 .h 文件中。
    /**
      * 这是 Marlin 中的一种比较好的多行注释。
      * 请坚持使用它。
      *
      * 这种属于类“D 型氧气”风格,一旦关键字被添加,
      * 我们便能够自动生成代码文档并且提供更多
      * 完整的开发指南.
      */
  • 当注释在 3 行以下时,使用 C++ 的 // 注释。
    // 一行或两行时
    // 应该使用这样的注释。

命名以及符号

文件名

Marlin 源代码的文件名最好使用 lowercase_with_underscores.ext(带_下划线_的小写.扩展名)这种格式。在别的地方贡献的代码应该遵守他们组织的规定。

  • C++ 源文件使用 .cpp 后缀
  • C 源文件使用 .c 后缀
  • 头文件使用 .h 后缀

目录

  • 目录名使用小写
  • 在 Marlin 1.0.x 与 1.1.x 版本中使用 平面文件布局
  • 在 Marlin 1.2.x 及以上版本中使用 分级文件布局

大写

对于 Marlin 当中的变量、数据成员、函数以及方法使用 带_下划线_的小写。对于已经使用 camelCase 驼峰命名法的就不要改动它了。Marlin 中的类使用 MyClassNamemy_class_name。核心的类使用驼峰法,普通的类使用下划线法。

  • my_function_name(int in_integer, float in_float=0.0)
  • MyClass, classMethod, classData
  • local_variable, global_variable, const_value
  • #define 定义的任何 MACRO_NAME
  • EnumeratedType

尽量使用 avr-libc 或者 Arduino 中的已捆绑的库。Marlin 中所需要编译的库应该在 package 中被引用,从而保证版本的兼容性。

语言特性

Marlin 由 C/C++ 编写,并且由 Makefile 命令或最新版的 Arduino 编译。在 1.1 版本的 Marlin 中,编译可由 Arduino IDE,Teensyduino,PlatformIO,make 以及 cmake 进行。

在更新的版本中,Marlin 不再兼容先前版本(pre-2017)的工具链。能与 Marlin 1.1.x 兼容的最旧版本的 Arduino IDE 为 1.6.8。

  • 不要使用以下的 C++ 扩展功能:
    • Exceptions (throw / catch)
    • Virtual function / classes
    • Standard Template Library (STL)
  • 请使用更加现代的 C++11:
    • constexpr 的值与函数
    • 用于检查 floatconstexpr 合法性的 static_assert(test,“error”) 函数

原生数据类型

  • 为了可移植性,建议使用 uint8_tint32_t,不建议使用 shortintlong
  • AVR 视 doublefloat 类型,因此它们的大小都为 32 位。与 double 相比较,最好使用 float 类型,除非当前的 32 位架构对于数据精度拥有更高的需求。

内存使用

  • 使用像 malloc()free()newdelete 这种动态内存分配的函数时明令禁止的!它们对于一些 32 位的程序会产生歧义。
  • 使用未限制的递归会导致内存爆炸,因此避免使用。
  • 在许多主板中内存很宝贵,所以尽量别用全局以及静态变量。
  • 使用 PSTRPROGMEM 宏来在内存中存放字符串。

减少重复

在使用宏、轻量函数等应该避免重复,例如:

#if ENABLED(FEATURE_ONE)
  const char blue = '1';
#else
  const char blue = '0';
#endif

不如:

const char blue = 
  #if ENABLED(FEATURE_ONE)
    '1'
  #else
    '0'
  #endif
;

更不如:

const char blue = TERN(FEATURE_ONE, '1', '0');

避占用更多资源地代码

  • millis() 由于比较占资源,倘若你想使用它多次,请将它放入 const millis_t var 中。
  • 提前计算数值,减少在程序运行中运算。
  • 能用乘法的别用除法。
  • 大多数冗余的代码并不会优化程序,所以用更少的代码。

#include 的最佳使用

  • 引用当前程序中的声明的头文件,这会使程序的依赖性更加直观。
  • 不要引用不被使用的 Marlin.h,当引用 MarlinConfig.hMarlinConfigPre.h 程序能够正常使用时也不要引用 Marlin.h
  • 头文件被引用的顺序:
    • 当配置需要被使用时,引用 MarlinConfig.hMarlinConfigPre.h
    • 在最外层 #if 后引用对应需要被使用的头文件。
    • 按照依赖顺序引用依赖。
    • 最后引用系统以及库的头文件,例如 <Arduio.h><inttypes.h><u8glib.h>

由 Marlin 定义的转换

预处理命令

  • #define 代替 const
  • 对于注释掉的未使用的、过时的代码,不要使用 #if / #endif
  • 使用 #if ENABLED(FEATURE_NAME) / #endif 来启用对应的功能。它可以让对应功能以外部的方式被启用。
  • 同理,使用 if DISABLED(FEATURE_NAME) / #endif 来禁用对应的功能。
  • 考虑到更佳的可阅读及可移植性,使用 #define 来避免重复的模板代码。
  • 在超过 15 行代码的 #if 语句末的 #endif 后增加标签,例如:#endif // SDSUPPORT || ULTRALCD

macros.h 中,存在很多便捷的宏。

配置测试

三元宏

检查定义的引脚

快速 I/O

便捷循环

重复

映射

字符测试

列表与数组

时间比较

通讯

数学

其他

添加新功能

一些例子

knowledge/3d_print/2023052301.txt · 最后更改: 2023/06/07 04:23 由 127.0.0.1