EmbedWay DPI-SDK编写规范
1. 引言
EmbedWay DPI-SDK编写规范规定了软件编写的基本规则,主要目的是多人之间能协同编写EmbedWay DPI的SDK,形成一致的代码编写风格,从而能更好的支持SDK用户。
目的
文档目的是为了规范软件代码的编写,消除代码歧义,增强不同团队的交流,便于代码的继承、管理和版本控制,并能够对未来的SDK用户形成更好的支持。
范围
文档中定义了用户引用头文件的代码风格,命令规范、注释风格等,对于库实现的源代码,除了遵守该文档以外,应该遵从Embedway软件代码规范。
定义和缩略语
定义
缩略语   
参考资料
Embedway软件代码规范
2. 文件命名及存放
文件命名方式采用固定前缀_功能说明的方式,固定前缀为ewx,功能说明应该能体现该库的功能的说明性文字,可能由多个单词组成,比如:ewx_thread.h ewx_hash_table.h,所有的.c和.h存放在lib_ewx目录下。
3. 头文件
开始
头文件是被其他文件包含,并且被c的预处理器编译的文件,在头文件中应该包含数据结构的定义、全局变量的声明以及对外函数的声明,头文件名称和真正处理的c文件相同,后缀为.h;
为了防止多次include出现重复定义,头文件总是以#ifndef 宏开始,宏以两个下划线开头,紧接着是文件名,最后以两个下划线结束,如ewx_hash_table.件:
#ifndef __EWX_HASH_TABLE_H__
#define __EWX_HASH_TABLE_H__
/*头文件内容*/
#endif
为了提高效率,常用的小函数可以定义为inline函数,放在头文件中;
应该尽量避免使用全局变量。
数据结构定义
函数名称
函数名称应该采用ewx_名称_动作的方式,比如在ewx_hash_table.h中,函数声明如下:
ewx_hash_table_init();
ewx_hash_table_search();
4. 注释
注释的目的在于说明程序,使程序更容易理解,给自己或他人在阅读程序时提供帮助,增强程序代码的可读性。在添加注释时,应该遵循以下原则:
1、注释的语言采用中文,编码采用utf-8
2、为了便于代码文档化,注释的格式应符合doxygen可识别的JavaDoc风格。
3、 注释必须含义明确,语言简明,内容有效。
4、 代码更改时,相应的注释也要及时更改,保持代码和注释的一致性。
文件注释
每一个C源文件和头文件都需要在文件的起始处加入文件注释。注释的内容应至少包括以下
几项:文件名,内容描述,作者,版本号,日期。
文件注释的格式如下所示。
/**
* @file    ......
* @brief  ......
* @version  ......
* @date  ......
*/
在上面的示例中,每个@后面都跟一个doxygen的关键字,doxygen使用关键字来识别注释的内容,使用时只需要在关键字的后面添加注释的内容即可。上面的关键字含义说明如下:
file  文件名
brief 对文件内容的描述
version 文件的版本号
date 日期,格式为yyyy-mm-dd
函数头注释
函数的注释应写在函数的定义之前,在DPI SDK编写的过程中,必须给函数分好类别,以方便检索,格式如下所示。
/** @addtogroup ......
* @ingroup ......
*/
/**
* @brief  ......
* @param  ......
* @return  ......
*/
其中各关键字说明如下:
addtogroup:加入到某个组里面,如果没有个该组,组自动被创建;
ingroup:上一级的组标识,如果该函数属于顶级分类,那么这个关键字不需要输入;
brief 对函数功能的简要描述
param 函数输入参数的说明。若函数有多个输入参数,则每个输入参数    都需要用@param单独说明。说明的内容应包括参数的作用,取值说明和参数之间的关系。
return  返回值描述,应说明返回值的用途,取值范围和对应的含义。
示例如下:
/** @addtogroup pko_function PKO函数
中文写代码软件 * @ingroup io_function io函数
* @brief 完成数据包的发送,在此之前cvmx_pko_send_packet_prepare() 必须被* 调用一次,并且传递给cvmx_pko_send_packet_prepare() *cvmx_pko_send_packet_finish()的参数必须相同
* @param port  发送的端口
* @param queue  发送的队列
* @param pko_command  PKO 命令字
* @param packet  要发送的数据包
* @param use_locking  锁类型,取值可以为:CVMX_PKO_LOCK_NONE,        *CVMX_PKO_LOCK_ATOMIC_TAG CVMX_PKO_LOCK_CMD_QUEUE
* @return  成功时返回CVMX_PKO_SUCCESS ,错误时返回错误码
*/
static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(uint64_t port,  uint64_t queue,
cvmx_pko_command_word0_t pko_command,
cvmx_buf_ptr_t packet, 
cvmx_pko_lock_t    use_locking)                                                                   
{
......
}
函数体注释
函数体的注释部分应主要说明函数的实现,这部分注释不需要被doxygen识别,应包含在 /* ..
. */ 内,不建议使用 // 注释。
对代码行的注释应写在代码的上方,并用空行与其他代码行分开,空间允许时也可以跟在代码后面,不能写在代码下方,也不要写在代码或表达式的中间。同时注释应与被注释的代码缩进对齐,示例如下:
/* 初始化,每个核都要执行 */
cvmcs_init_local();
......
1、函数内变量的注释应跟在变量的定义的右方。
2、函数体内的循环语句,以及含义不明显的分支语句应添加有效注释。
3、在程序块的结束行右方添加注释,表明程序块的结束。
数据结构注释
1、对数据结构的注释应位于数据结构的上方,格式如下:
/**
* 对数据结构的描述
*/
2、数据结构中,每个域的注释应位于域的右方,包含在/**<.....*/ 内,如需分行,则各行的注释使用缩进对齐,如下所示。
/**
* 端口状态信息
*/
typedef struct {
    uint64_t port_rate[4];          /**< 以Mbps为单位的端口速率*/
    uint64_t port_pps[4];          /**< 以pps 为单位的端口速率*/
    uint64_t port_counter[4];    /**< 端口发送的数据包计数*/
    uint64_t port_bytes[4];        /**< 端口发送的字节计数*/
} ewx_port_status_t;
全局变量,常量和宏的注释
全局变量,常量和宏的注释位置可以位于宏定义的上方或右方,变量的注释格式与数据结构的域注释类似,包含在/**<......*/ 内,若被注释的内容不需要出现在doxygen的文档中,也可以用/*......*/来包含注释。
全局变量需要有比较详细的注释,内容应包括功能说明,取值范围,使用它的函数和存取时的注意事项等。