0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

嵌入式实时操作系统AliOS Things的编码风格介绍

工程师进阶笔记 来源:阿里云 2023-06-07 09:20 次阅读

1. 前言

本文是AliOS Things提供的一套C语言代码规范,适用的对象为符合C99标准的C语言工程。

2. 命名

本节内容均为建议,不作强制要求。

2.1. 总则

各种命名均使用英文单词及其缩写,非特殊情况不能使用汉语拼音或其他语言。

2.2. 文件命名

文件名全部使用小写字母,用_连接。源文件使用.c后缀。头文件使用.h后缀。

2.3. 类型命名

2.3.1. 简单类型命名

使用typedef自定义的简单类型命名全部使用小写字母,用_连接,以_t结尾。例如:

typedefint32_taos_status_t;

2.3.2. 结构体和联合体命名

结构体和联合体类型命名全部使用小写字母,用_连接。建议使用typedef定义一个整体的名字,以_t结尾。例如:

typedefstructaos_list_node{
structaos_list_node*prev;
structaos_list_node*next;
}aos_list_node_t;

staticaos_list_node_tlist_node;

2.3.3. 枚举命名

枚举类型命名全部使用小写字母,用_连接。建议使用typedef定义一个整体的名字,以_t结尾。枚举值命名全部使用大写字母,用_连接,包含表示类型的前缀。例如:

typedefenumaos_socket_stage{
AOS_SOCK_STG_DISCONNECTED,
AOS_SOCK_STG_CONNECTED,
}aos_socket_stage_t;

staticaos_socket_stage_tsock_stage=AOS_SOCK_STG_DISCONNECTED;

2.4. 变量命名

变量命名全部使用小写字母,用_连接。数组名称尽量使用复数名词。例如:

cfg_file_tcfg_files[NUM_CFG_FILES];

表示数目的变量名称使用num(number的缩写)加复数名词。例如:

unsignedintnum_files;

表示序号的变量名称使用单数名词加num或index或idx(index的缩写)。例如:

unsignedintfile_num;
unsignedintfile_index;

2.5. 函数命名

函数命名全部使用小写字母,用_连接。

2.6. 宏命名

一般的宏命名全部使用大写字母,用_连接。例如:

#defineAOS_STRING_MAX_LEN127

模拟函数使用方式的宏的命名规则与函数相同。例如:

#defineaos_dev_set_id(dev,x)
do{
(dev)->id=(x);
}while(0)

2.7. 前缀

为防止命名空间污染,公用组件中的非static函数、非static全局变量、全局类型、全局宏的命名应带有前缀。例如(假设前缀为aos):

voidaos_cfg_file_close(intfd);
externchar**aos_process_argv;
typedefstructaos_list_nodeaos_list_node_t;
#defineAOS_STRING_MAX_LEN127

3. 格式

3.1. 文本格式

源文件、头文件、Makefile等文本文件一律采用UTF-8 without BOM编码,采用Unix风格换行格式。文本文件末尾应有且只有一个换行符,即末尾应有且只有一个空行。

3.2. 行长度

每行字符数原则上不超过120。包含长路径的#include语句、头文件#define保护可以无视此规则。

3.2.1. 表达式换行

较长的表达式可在运算符处换行,换行处的运算符属于旧行,新行对齐到旧行中的相同逻辑层级。例如:

voidfoo(void)
{
if((aos_list_next(list_node)!=&list_head&&!priv)||
!(strcmp(symbol,default_symbol)&&blahblahblahblahblahblah()&&
meomeomeomeomeomeomeomeomeomeomeomeomeomeomeomeo(NULL))){
/*...*/
}
}

3.2.2. 函数换行

较长的函数定义、声明可在返回值类型和函数名称之间换行。若返回值为指针类型,*属于新行。例如:

staticunsignedlong
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah(void);
staticconstmanager_priv_t
*blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah(intindex);

较长的函数定义、声明、调用可在参数列表中间换行,参数列表中间换行后新行应缩进至旧行第一个参数处。例如:

voidblahblahblahblahblahblahblahblahblah(manager_priv_t*priv,intindex,
constchar*proc_name);

voidfoo(void)
{
blahblahblahblahblahblahblahblahblahblah(get_manager_priv(manager),0,
"meomeomeomeomeomeomeomeo");
}

3.2.3. 字符串换行

较长的字符串可在空格处换行,一般情况下换行处的空格属于旧行。例如:

voidfoo(void)
{
printf("TheGNUoperatingsystemconsistsofGNUpackages"
"(programsspecificallyreleasedbytheGNUProject)"
"aswellasfreesoftwarereleasedbythirdparties.
");
}

3.3. 缩进

使用空格缩进,每次4个空格。全文不应出现制表符(tab)。例如:

voidfoo(unsignedintnbr_processes)
{
unsignedinti;

while(i< nbr_processes) {
        const char *name;
        /* ... */
    }
}

宏定义、行尾注释、结构体、联合体、枚举等内部可缩进实现多行对齐,但不作强制要求。若有缩进,应对齐到4的整数倍。例如:

/*此处数字0缩进32个字符,即位于第33列。*/
#defineSTAGE_UPDATE_CONTINUE0
#defineSTAGE_UPDATE_COMPLETE1

/*合法*/
#defineEVENT_RX_FULL(1U<< 0)
#define EVENT_TX_EMPTY (1U << 1)

typdef enum socket_stage {
    /* 此处等号缩进32个字符,即位于第33列。 */
    SOCK_STG_DISCONNECTED       = 0,
    SOCK_STG_CONNECTED          = 1,
} socket_stage_t;

/* 此处反斜杠缩进40个字符,即位于第41列。 */
#define aos_dev_set_flags(dev, x)       
    do {                                
        (dev)->flags=(x);
}while(0)

/*合法*/
#defineaos_dev_set_ops(dev,x)
do{
(dev)->ops=(x);
}while(0)

/*此处注释缩进24个字符,即位于第25列。*/
foo(NULL);/*abc*/
blahblahblahblahblah();/*xyz*/

/*合法*/
foofoofoo();/*abc*/
foofoo();/*xyz*/

分行定义的宏,第二行起应缩进一次。例如:

#defineaos_dev_set_id(dev,x)
do{
(dev)->id=(x);
}while(0)

switch块中的case语句和default语句与switch语句缩进层级相同。例如:

switch(stage){
caseSOCK_STG_DISCONNECTED:
foo();
break;
caseSOCK_STG_CONNECTED:
sock->connected=1;
break;
default:
break;
}

3.4. 花括号

函数体的左花括号另起一行;其他情况下左花括号不另起一行。一般情况下左花括号后续内容另起一行;宏定义中、数组、结构体、联合体初始化时若花括号中内容较短则左花括号后续内容可以不另起一行。一般情况下右花括号另起一行;宏定义中、数组、结构体、联合体初始化时若花括号中内容较短则右花括号可以不另起一行。右花括号与后续内容组合成一行。例如:

typedefstructmanager_priv{
intindex;
void*data;
}manager_priv_t;

#defineset_manager_index(x,idx)do{(x)->priv->index=(idx);}while(0)

#ifdef__cplusplus
extern"C"{
#endif

voidfoo(void)
{
inti=0;

/*...*/

if(i==0){
/*...*/
}else{
/*...*/
}
}

manager_priv_tpriv={0,NULL,};

#ifdef__cplusplus
}
#endif

3.5. 空格

行尾不应有空格。三元操作符和二元操作符(获取成员的.和->操作符除外)前后留有空格。例如:

x=a?b:c;
v=w*x+y/z;
len=x.length;
priv=proc->priv;

一元操作符与参数之间不留空格。例如:

x=*p;
p=&x;
i++;
j=--i;

逗号右侧若有内容,逗号与右侧内容之间应有空格。例如:

voidfoo(intx,inty);

分号右侧若有内容(右圆括号或另外一个分号除外),分号与右侧内容之间应有空格。例如:

for(i=0;i< strlen(str);) {
    for (;;) {
        /* ... */
    }
}

圆括号内部内容与圆括号之间不留空格。例如:

len=strlen(name);

for(i=0;i< count; i++) {
    /* ... */
}

圆括号与左侧关键字之间应有空格。例如:

while(1){
/*...*/
}

if(i==0){
/*...*/
}

圆括号与左侧函数名之间不留空格。例如:

intload_file(constchar*name)
{
foo(0);
/*...*/
}

类型转换中的圆括号与右侧内容之间不留空格。例如:

manager_priv_t*priv=(manager_priv_t*)p;

方括号与左侧内容、内部内容之间不留空格。例如:

c=name[i];

左花括号左侧或右侧若有内容,左右内容与左花括号之间应有空格。右花括号左侧若有内容,左侧内容与右花括号之间应有空格;右花括号右侧若有内容(分号、逗号除外),右侧内容与右花括号之间应有空格。例如:

#defineset_manager_index(x,idx)do{(x)->priv->index=(idx);}while(0)

manager_priv_tpriv={0,NULL,};

分行定义的宏,与左侧内容之间应有空格。例如:

#defineset_manager_index(x,idx)
do{
(x)->priv->index=(idx);
}while(0)

3.6. 指针

指针声明或定义时,*应靠近变量名称。*与修饰符之间应有空格。例如:

int*p;
constchar*name;
void*constptr;
void(*func)(void*arg);

3.7. 数值常量

十六进制数字A~F使用大写形式。表示二进制的前缀0b和表示十六进制的0x使用小写形式。后缀U和L使用大写形式。后缀f使用小写形式。表示幂的e和p使用小写形式。例如:

unsignedintb=0b0101;
unsignedintx=0xABCDEF;
unsignedintu=0U;
longintl=0L;
unsignedlongintul=0UL;
floatf=1.0f;
longdoubleld=1.0L;
doubledd=-1.5e-5;
doublexd=0xA.Bp12;

3.8. 注释

使用C90风格的/* */,不使用C++风格的//。/*或*/与注释正文之间应有空格。行尾的注释和代码之间应有空格。完整语句注意首字母大写和标点符号,简单词组可以不使用标点。注意区分中英文标点。TODO:使用特定注释格式可利用doxygen等自动化工具生成文档。例如:

/*
*ThissourcefileispartofAliOSThings.
*ZhangSan
*2021.07.01
*/

/*ZhangSan
*2021.07.01*/

/*ThispointermustNOTbeNULL.*/

/*connecting*/

4. 头文件

4.1. 路径

为避免与第三方库的头文件命名冲突,公用组件的头文件应存放于子目录中,引用时路径包含子目录名称。例如:

#include

4.2. 引号和尖括号

只有包含与本源文件处于同路径中的头文件时使用引号,其他情况均使用尖括号。例如:

#include
#include"my_demo.h"

4.3. 包含次序

包含头文件的次序如下:|次序 |种类| |-:- |:-| |1 |C语言标准库头文件和工具链头文件| |2 |公用组件的头文件| |3 |本工程头文件|

例如:

#include
#include
#include
#include
#include"my_demo.h"

4.4. 保护

所有头文件都应该使用#define保护来防止被重复包含。相关宏命名格式是PATH_FILE_H。例如,头文件aos/common.h可按如下方法保护:

#ifndefAOS_COMMON_H
#defineAOS_COMMON_H

/*全部内容*/

#endif/*AOS_COMMON_H*/

4.5. 函数、变量声明

头文件中的函数声明不使用extern关键字。头文件中的全局变量声明使用extern关键字。例如:

voidaos_cfg_file_close(intfd);
externchar**aos_process_argv;

4.6. extern "C"关键字

公用头文件中声明的函数和全局变量应该使用extern "C"关键字修饰。#include不应使用extern "C"关键字修饰。#define、类型定义不作要求,可酌情考虑。例如:

#ifndefAOS_COMMON_H
#defineAOS_COMMON_H

#include

#defineAOS_STRING_MAX_LEN127
#defineAOS_LSTRING_MAX_LEN511

typedefstructaos_tm{
unsignedintsec;
unsignedintmin;
unsignedinthour;
unsignedintmday;
unsignedintmon;
unsignedintyear;
}aos_tm_t;

#ifdef__cplusplus
extern"C"{
#endif

externcharaos_process_symbol[AOS_STRING_MAX_LEN+1];

voidaos_start(void);

#ifdef__cplusplus
}
#endif

#endif/*AOS_COMMON_H*/

5. 其他注意事项

只在本编译单元使用的函数、全局变量应使用static修饰符。在不影响功能的前提下,指针类型的函数参数尽量使用const修饰符。自增、自减运算符单独使用时采用后置形式。数组、结构体初始化列表、枚举类型定义中的最后一个成员之后应有逗号。例如:

intoffsets[]={
0,
1,
};

来源:https://help.aliyun.com/document_detail/311306.html






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式系统
    +关注

    关注

    41

    文章

    3564

    浏览量

    129215
  • C语言
    +关注

    关注

    180

    文章

    7597

    浏览量

    136148
  • BOM
    BOM
    +关注

    关注

    5

    文章

    252

    浏览量

    40136
  • UTF-8
    +关注

    关注

    0

    文章

    13

    浏览量

    7842

原文标题:嵌入式实时操作系统 AliOS Things 的编码风格

文章出处:【微信号:工程师进阶笔记,微信公众号:工程师进阶笔记】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    使用STM32快速开发AliOS Things硬件与软件环境

    AliOS ThingsAliOS 家族旗下的、面向 IoT 领域的、轻量级物联网嵌入式操作系统
    的头像 发表于 01-22 09:17 1.8w次阅读

    AliOS Things lorawanapp应用介绍

    ThingsAliOS 家族旗下的、面向 IoT 领域的、轻量级物联网嵌入式操作系统。文本旨在给大家示范一下其中的lorawanapp的示例,完成一个LoRaWAN网络的构建和
    发表于 01-22 16:43

    AliOS Things 持续集成(CI)系统介绍

    与一般的CI系统不同,AliOS Things的功能验证是需要运行在多种多样的嵌入式芯片中的,这里需要解决的难题是:如何屏蔽多样化嵌入式
    发表于 01-26 15:34

    介绍14种主流的RTOS操作系统

    、NuttX,而国产的嵌入式操作系统包括都江堰操作系统(djyos)、Alios Things、Huawei LiteOS、RT-Threa
    发表于 10-27 07:28

    介绍十四种嵌入式操作系统的特点

    都江堰操作系统(djyos)、Alios Things、Huawei LiteOS、RT-Thread、SylixOS。下面分别介绍这十四种种嵌入式
    发表于 10-27 09:15

    主流的14种嵌入式操作系统的特点

    、NuttX,而国产的嵌入式操作系统包括都江堰操作系统(djyos)、Alios Things、Huawei LiteOS、RT-Threa
    发表于 12-14 06:57

    主流的嵌入式操作系统有哪些?

    、NuttX,而国产的嵌入式操作系统包括都江堰操作系统(djyos)、Alios Things、Huawei LiteOS、RT-Threa
    发表于 12-27 07:27

    嵌入式实时操作系统教程

    嵌入式实时操作系统教程:以VRTX为对象详细介绍嵌入式实时
    发表于 04-19 21:55 44次下载
    <b class='flag-5'>嵌入式</b><b class='flag-5'>实时</b><b class='flag-5'>操作系统</b>教程

    嵌入式操作系统有哪些?

    嵌入式操作系统有哪些? 下面介绍国外和国内常用的实时操作系统。1. 国外著名的实时
    发表于 06-17 00:32 1.3w次阅读

    实时操作系统用于嵌入式应用系统的设计

    概述了嵌入式系统的开发工具实时操作系统的特点和核心内容;分析了在利用实时操作系统进行
    发表于 10-10 15:23 42次下载
    <b class='flag-5'>实时</b><b class='flag-5'>操作系统</b>用于<b class='flag-5'>嵌入式</b>应用<b class='flag-5'>系统</b>的设计

    米尔科技嵌入式实时操作系统介绍

    嵌入式实时操作系统μC/OS-Ⅱ经典实例:基于STM32处理器》紧紧围绕“μC/OS-Ⅱ系统设计”这一主题,立足实践解析了嵌入式
    的头像 发表于 11-25 09:02 2293次阅读
    米尔科技<b class='flag-5'>嵌入式</b><b class='flag-5'>实时</b><b class='flag-5'>操作系统</b><b class='flag-5'>介绍</b>

    嵌入式实时操作系统的应用详细教程说明

    本文档的主要内容详细介绍的是嵌入式实时操作系统的应用详细教程说明包括了:1 嵌入式系统
    发表于 12-05 08:00 2次下载
    <b class='flag-5'>嵌入式</b><b class='flag-5'>实时</b><b class='flag-5'>操作系统</b>的应用详细教程说明

    详解目前主流的嵌入式操作系统(RTOS)操作系统

    、NuttX,而国产的嵌入式操作系统包括都江堰操作系统(djyos)、Alios Things、Huawei LiteOS、RT-Threa
    发表于 10-20 12:36 15次下载
    详解目前主流的<b class='flag-5'>嵌入式</b><b class='flag-5'>操作系统</b>(RTOS)<b class='flag-5'>操作系统</b>

    嵌入式实时操作系统

    都江堰操作系统(djyos)、Alios Things、Huawei LiteOS、RT-Thread、SylixOS。下面分别介绍这十四种种嵌入式
    发表于 10-20 14:05 17次下载
    <b class='flag-5'>嵌入式</b><b class='flag-5'>实时</b><b class='flag-5'>操作系统</b>

    嵌入式操作系统

    嵌入式操作系统一、嵌入式操作系统概述1.1 嵌入式操作系统的特点1.2
    发表于 11-03 18:36 46次下载
    <b class='flag-5'>嵌入式</b><b class='flag-5'>操作系统</b>