board coding standard.docx
《board coding standard.docx》由会员分享,可在线阅读,更多相关《board coding standard.docx(18页珍藏版)》请在冰豆网上搜索。
boardcodingstandard
软件编程规范单板分则
(DOC-ID/IPD-CMMV3.0/forinternaluseonly)
(文档编号/IPD-CMMV3.0/仅供内部使用)
Preparedby
拟制:
Date
日期:
yyyy-mm-dd
Reviewedby
审核:
Date
日期:
yyyy-mm-dd
Approvedby
批准:
Date
日期:
yyyy-mm-dd
HuaweiTechnologiesCo.,Ltd.
华为技术有限公司
Allrightsreserved
版权所有XX
单板软件编程规范
(第一版)
本规范是在公司颁布《软件编程规范总则》(以下称《总则》)的基础上针对单板软件编程的特点,对单板软件的编程做了更加明确的规定。
本规范按照《总则》的编排顺序,分为:
排版、注释、标识符命名、变量使用、代码可测性、程序效率、质量保证、代码编译、单元测试、程序版本与维护。
参照的《软件编程归规范总则》颁布时间为:
1999年2月11日,版本为:
1.01。
本规范采用和《软件编程规范总则》一样的术语描述:
★规则:
编程时强制必须遵守的原则。
★建议:
编程时必须加以考虑的原则。
★说明:
对此规则或建议进行必要的解释。
1示例:
对此规则或建议从正、反两个方面给出例子。
1排版
规则1-1:
参见《总则》规则1-1。
规则1-2:
参见《总则》规则1-2。
规则1-3:
参见《总则》规则1-3。
规则1-4:
参见《总则》规则1-4。
规则1-5:
参见《总则》规则1-5。
规则1-6:
参见《总则》规则1-6。
规则1-7:
参见《总则》规则1-7。
规则1-8:
参见《总则》规则1-8。
规则1-9:
参见《总则》规则1-9。
规则1-10:
参见《总则》规则1-10。
规则1-11:
参见《总则》规则1-11。
规则1-12:
不同类型的操作符混合使用时,即使实现优先级与实际需要相符,也要使用括号隔离之,以便代码更加清晰。
示例:
如本来是正确的代码:
if(year%4==0year%100!
=0&&year%400==0)
如果加上括号,则更清晰:
If(((year%4)==(year%100)!
=0)&&((year%400)==0))
规则1-13:
对于使用到的预编译宏,要在文件的适当地方加以说明,对于连续多行的宏,在书写上要采用缩进的格式。
示例:
下面的例子使阅读清晰方便
#ifdef_BORLANDC_
#defineFARfar
#defineNEARnear
#ifdefOS_DEBUG
#defineTIMER_DEBUGTRUE
#defineMEM_DEBUGTRUE
#undefXRAY
#endif
#else
#defineFAR
#defineNEAR
#endif
规则1-14:
对于夹在代码中的编译开关,在书写格式上应当和源代码一样进行缩排。
说明:
可使程序排版整齐,方便编译开关的阅读与理解
示例:
...
lpPrim=(LPTL2L1PRIM)GetMsg(&queL2L1);
If(lpPrim==NULL)
{
#ifOS_DEBUG
printf("QueueL2->L1isempty!
");
#endif
return;
}
...
建议1-1:
参见《总则》建议1-1。
2注释
规则2-1:
参见《总则》规则2-1。
规则2-2:
参见《总则》规则2-2。
规则2-3:
参见《总则》规则2-3。
规则2-4:
参见《总则》规则2-4。
规则2-5:
参见《总则》规则2-5。
规则2-6:
参见《总则》规则2-6。
规则2-7:
参见《总则》规则2-7。
规则2-8:
参见《总则》规则2-8。
规则2-9:
参见《总则》规则2-9。
规则2-10:
参见《总则》规则2-10。
规则2-11:
参见《总则》规则2-11。
规则2-12:
参见《总则》规则2-12。
规则2-13:
参见《总则》规则2-13。
规则2-14:
参见《总则》规则2-14。
规则2-15:
参见《总则》规则2-15。
规则2-16:
对使用到的物理寄存器的各比特位或字段的含义,应给出明确的注释。
说明:
在对寄存器进行初始化之前,要首先彻底弄清楚它们的含义,并且给出明确的注释。
这样会对后续的初始化工作非常有利,并且可以防止在较长的时间之后在来看这些寄存器时记不清楚,更可以方便接手该项工作的新的程序员。
示例:
struct_SIMODE
{
WORDSMC2:
1;/*SMC2Connection(NMSIorTDM)*/
WORDSMC2CS:
3;/*SMC2ClockSource(NMSImode)*/
WORDSDMb:
2;/*SIDiagnosticModeforTDMB*/
WORDRFSDb:
2;/*ReceiveFrameSyncDelayforTDMB*/
WORDDSCb:
1;/*Double-SpeedClockforTDMB*/
WORDCRTb:
1;/*CommonReceiveandTransmitPinsforTDMB*/
WORDSTZb:
1;/*SetL1TXDxtoZeroforTDMB*/
WORDCeb:
1;/*ClockEdgeforTDMB*/
WORDFeb:
1;/*FrameSyncEdgeforTDMB*/
WORDGmb:
1;/*GrantModeforTDMB*/
WORDTFSDb:
2;/*TransmitFrameSyncDelayforTSMB*/
}
规则2-17:
在初始化物理寄存器时,要对各寄存器的初始值的确切含义给出明确注释。
说明:
初始化寄存器的过程是确定硬件工作模式的过程,所以要对此时定义的所有寄存器值给出明确的注释,这将给后面的维护工作带来极大的方便。
示例:
voidInitTSA(void)
{
......
simode.SIMODE.SMC2=0;/*NMSImode*/
simode.SIMODE.SMC2CS=1;/*useBRG2,BAUD=9600*/
simode.SIMODE.SDMa=0;/*TDMANormaloperation*/
simode.SIMODE.RFSDa=0;/*Notbitdelay*/
simode.SIMODE.DSCa=0;/*thechannelclockisequeal*/
/*tothedataclock*/
simode.SIMODE.CRTa=1;/*Commonpins*/
simode.SIMODE.STZa=0;/*Normaloperation*/
simode.SIMODE.CEa=0;/*Thedataistransmittedonthe*//*risingedgeoftheclockand*/
/*receivedonthefallingedge*/
......
}
建议2-1:
参见《总则》建议2-1。
建议2-2:
参见《总则》建议2-2。
建议2-3:
参见《总则》建议2-3。
建议2-4:
参见《总则》建议2-4。
建议2-5:
参见《总则》建议2-5。
建议2-6:
参见《总则》建议2-6。
3标识符命名
规则3-1:
参见《总则》规则3-1。
规则3-2:
参见《总则》规则3-2。
规则3-3:
参见《总则》规则3-3。
规则3-4:
参见《总则》规则3-4。
规则3-5:
参见《总则》规则3-5。
在此基础上,规定单板软件统一采用大小写混排的方式,而不采用小写加下划线的方式。
示例:
Add_User(错误)
AddUser(正确)
规则3-6:
函数命名应能体现该函数完成的功能,关键部分应采用完整的单词,辅助部分若太长可采用缩写,缩写应符合英文的规范。
示例:
ShowPoints
CtrlDestBoard
SendResetMsg
规则3-7:
变量的命名规则采用匈牙利命名规则。
变量的第一个或前两个字母小写,标识其数据类型,其后每个词的第一个字母大写。
类型前缀如下:
前缀
含义
前缀
含义
a
数组
np
短指针
b
BOOL
p
指针
by
BYTE
l
LONG
c
char
lp
长指针
cb
字节记数
s
串
cx,cy
短型(x,y长度的记数)
sz
以零结尾的串
dw
DWORD
tm
文本
fn
函数
w
WORD
h
HANDLE
x,y
短型
i
int
g
全局变量
n
shortint
uc
usignedchar
示例:
iCurrentValue
ucTransitionCount
规则3-8:
类型的定义请统一使用BYTE、INT、WORD、DWORD、LPWORD、VOID、FAR、NEAR等写法,避免使用char、long、void、far、near等小写格式,不要使用_UC、_US、_UL等以前一些人的习惯写法。
规则3-9:
结构的定义有两个名称,一个是该结构的类型名,一个是变量名。
按照C语言的语法,这两个名称都是可选的,但二者必有其一。
我们要求写类型名,类型名以tag做前缀。
示例:
structtagDLFsmType
{
WORDwEFAddr;
BYTEbySccNum;
BYTEbyTEI;
BYTEbyCES;
BYTEbyL2Statues;
BYTEbyVS;
BYTEbyVR;
BYTEbyVA;
};
structtagDLFsmTypeveDLFSM[MAX_TER_NUM];
规则3-10:
联合的命名规则和结构相同
示例:
UniontagMyExample
{
INTiInterger;
LONGlLongInt;
}myExample;
typedefuniontagMyExample
{
INTiInteger;
LONGlLongInt;
}MyExample,*pMyExample,FAR*lpMyExample;
建议3-1:
参见《总则》建议3-1。
建议3-2:
参见《总则》建议3-2。
建议3-3:
参见《总则》建议3-3。
建议3-4:
参见《总则》建议3-4。
4可读性
规则4-1:
参见《总则》规则4-1。
规则4-2:
参见《总则》规则4-2。
建议4-1:
参见《总则》建议4-1。
建议4-2:
参见《总则》建议4-2。
5变量
规则5-1:
参见《总则》规则5-1。
规则5-2:
参见《总则》规则5-2。
规则5-3:
参见《总则》规则5-3。
规则5-4:
参见《总则》规则5-4。
规则5-5:
参见《总则》规则5-5。
规则5-6:
参见《总则》规则5-6。
规则5-7:
在给变量赋值时,不要将数据类型宽度大于它的变量赋给它,当然也不要将超过其最大值的常量赋给它。
说明:
这样做会使变量实际被赋的值与原来不符。
示例:
......
charcDst;
intiSrc;
iSrc=500;
cDst=iSrc;/*cDst得到了不正确的值*/
......
规则5-8:
使用局部变量不要超过其有效作用范围
说明:
局部变量只在其所在的函数内被定义之后的范围内有效,不能将其象全局变量一样使用。
尤其要避免在作用域之外使用局部变量的地址。
建议5-1:
参见《总则》建议5-1。
建议5-2:
参见《总则》建议5-2。
建议5-3:
参见《总则》建议5-3。
建议5-4:
参见《总则》建议5-4。
建议5-5:
参见《总则》建议5-5。
建议5-6:
参见《总则》建议5-6。
建议5-7:
参见《总则》建议5-7。
建议5-8:
参见《总则》建议5-8。
建议5-9:
参见《总则》建议5-9。
建议5-10:
参见《总则》建议5-10。
建议5-11:
参见《总则》建议5-11。
建议5-12:
参见《总则》建议5-12。
建议5-13:
参见《总则》建议5-13。
建议5-14:
参见《总则》建议5-14。
说明:
由于不同类型的编译器会对相同的数据类型有不同长度的定义,例如HighC中无符号整形数为32位,而在BC中无符号整形数为16位,所以我们这里可以抛开编译器,根据实际长度对自定义数据类型的命名作出明确的规定。
示例:
8位无符号整型数(字符型):
BYTE
16位无符号整型数:
WORD
32位无符号整型数:
DWORD
8位有符号整型数(字符型):
CHAR
16位有符号整型数:
INT
32位有符号整型数:
LONG
建议5-15:
参见《总则》建议5-15。
6函数、过程
规则6-1:
参见《总则》规则6-1。
规则6-2:
参见《总则》规则6-2。
规则6-3:
参见《总则》规则6-3。
规则6-4:
参见《总则》规则6-4。
建议6-1:
参见《总则》建议6-1。
建议6-2:
参见《总则》建议6-2。
建议6-3:
参见《总则》建议6-3。
建议6-4:
参见《总则》建议6-4。
建议6-5:
参见《总则》建议6-5。
建议6-6:
参见《总则》建议6-6。
建议6-7:
参见《总则》建议6-7。
建议6-8:
参见《总则》建议6-8。
建议6-9:
参见《总则》建议6-9。
建议6-10:
参见《总则》建议6-10。
说明:
考虑到单板软件对效率的要求较高,不宜在正式版本中保留过多的输入参数有效性检查,建议把这些检查代码放在调试版本中,最好用断言来实现。
建议6-11:
参见《总则》建议6-11。
建议6-12:
参见《总则》建议6-12。
建议6-13:
参见《总则》建议6-13。
建议6-14:
参见《总则》建议6-14。
建议6-15:
参见《总则》建议6-15。
建议6-16:
参见《总则》建议6-16。
建议6-17:
参见《总则》建议6-17。
建议6-18:
参见《总则》建议6-18。
建议6-19:
参见《总则》建议6-19。
建议6-20:
参见《总则》建议6-20。
建议6-21:
参见《总则》建议6-21。
建议6-22:
参见《总则》建议6-22。
建议6-23:
参见《总则》建议6-23。
建议6-24:
参见《总则》建议6-24。
建议6-25:
参见《总则》建议6-25。
建议6-26:
参见《总则》建议6-26。
建议6-27:
参见《总则》建议6-27。
建议6-28:
参见《总则》建议6-28。
建议6-29:
参见《总则》建议6-29。
建议6-30:
如果条件允许,对于有返回值的函数,在返回前对返回值做合法性检查。
7可测性
规则7-1:
参见《总则》规则7-1。
规则7-2:
参见《总则》规则7-2。
规则7-3:
参见《总则》规则7-3。
规则7-4:
参见《总则》规则7-4。
规则7-5:
参见《总则》规则7-5。
规则7-6:
参见《总则》规则7-6。
规则7-7:
参见《总则》规则7-7。
规则7-8:
参见《总则》规则7-8。
规则7-9:
参见《总则》规则7-9。
规则7-10:
参见《总则》规则7-10。
规则7-11:
参见《总则》规则7-11。
规则7-12:
参见《总则》规则7-12。
规则7-13:
参见《总则》规则7-13。
规则7-14:
参见《总则》规则7-14。
规则7-15:
参见《总则》规则7-15。
8程序效率
规则8-1:
参见《总则》规则8-1。
规则8-2:
参见《总则》规则8-2。
规则8-3:
参见《总则》规则8-3。
规则8-4:
参见《总则》规则8-4。
规则8-5:
参见《总则》规则8-5。
规则8-6:
去除程序中虽然执行但没有实际意义,或永远不会被执行并且也没有任何意义的“垃圾代码”;去除程序中没有使用的变量,尤其是全局变量。
因为这些内容除了浪费程序空间和数据空间外没有任何意义。
规则8-7:
为了避免头文件被重复编译,应为头文件加上条件编译语句。
说明:
当一个头文件被多个C文件引用时,会被多次编译,这是没有必要的,甚至会引起许多告警信息。
示例:
#ifdefHEADFILE
#defineHEADFILE
.
.
.
#endif
规则8-8:
要提高程序的时间效率,应从调用最频繁的函数入手进行优化,这里如果有冗余代码,将对系统的性能有很大影响。
建议8-1:
参见《建议》建议8-1。
建议8-2:
参见《建议》建议8-2。
建议8-3:
参见《建议》建议8-3。
建议8-4:
参见《建议》建议8-4。
建议8-5:
参见《建议》建议8-5。
建议8-6:
参见《建议》建议8-6。
建议8-7:
参见《建议》建议8-7。
建议8-8:
参见《建议》建议8-8。
建议8-9:
参见《建议》建议8-9。
建议8-10:
参见《建议》建议8-10。
建议8-11:
参见《建议》建议8-11。
9质量保证
规则9-1:
参见《总则》规则9-1。
规则9-2:
由于单板软件对于实时性要求很高,所以程序效率很重要,对《总则》中的代码质量保证优先原则做如下调整。
(1)正确性,指程序要实现涉及要求的功能。
(2)稳定性、安全性,指程序稳定、可靠、安全。
(3)全局效率,指软件系统的整体效率。
(4)局部效率,指某个模块/子模块/函数本身的效率。
(5)可测试性,指程序要具有良好的可测试性。
(6)规范/可读性,指程序书写风格、命名规则等要符合规范。
(7)个人表达方式/个人方便性,指个人编程习惯。
规则9-3:
参见《总则》规则9-3。
规则9-4:
参见《总则》规则9-4。
规则9-5:
参见《总则》规则9-5。
规则9-6:
参见《总则》规则9-6。
规则9-7:
参见《总则》规则9-7。
规则9-8:
参见《总则》规则9-8。
规则9-9:
参见《总则》规则9-9。
规则9-10:
参见《总则》规则9-10。
规则9-11:
参见《总则》规则9-11。
规则9-12:
参见《总则》规则9-12。
规则9-13:
参见《总则》规则9-13。
规则9-14:
参见《总则》规则9-14。
规则9-15:
参见《总则》规则9-15。
规则9-16:
参见《总则》规则9-16。
说明:
在这里进一步明确规定if语句必须有else分支,switch语句必须有default分支。
规则9-17:
在变量和常量之间进行“等于”判断时,把常量写在左边,变量写在右边。
说明:
可以避免误把“==”写成“=”时变量被赋与了不该赋的值。
示例:
......
If(MAX_VALUE==iCurrentValue)
.......
建议9-1:
参见《总则》建议9-1。
建议9-2:
参见《总则》建议9-2。
建议9-3:
参见《总则》建议9-3。
建议9-4:
参见《总则》建议9-4。
建议9-5:
参见《总则》建议9-5。
建议9-6:
参见《总则》建议9-6。
建议9-7:
参见《总则》建议9-7。
建议9-8:
参见《总则》建议9-8。
建议9-9:
参见《总则》建议9-9。
说明:
对于单板软件而言就是要通过指示灯和向主机上报足够信息来表达单板内部运行状况。
指示灯的使用要按照相关的设计规范和使用惯例来做,向主机上报的信息的格式也要满足维护的需求并符合相关的在线测试规范。
建议9-10:
参见《总则》建议9-10。
建议9-11:
参见《总则》建议9-11。
说明:
单板软件中可能不存在写硬盘、删数据等操作,但对其它一些具有危害性的操作代码也要仔细考虑,如修改RAM中的程序、数据、非法操作硬件等,以提高系统的安全性。
建议9-12:
参见《总则》建议9-12。
说明:
单板软件有可能还会使用到第三方提供的操作系统,无论是操作系统、开发工具包还是控件,除遵从《总则》建议9-12中的几点要求外,还要注意使用统一的接口对子系统进行封装,提高程序的可移植性;在封装层中加入调试程序,便于定位调用子系统时发生的问题。
建议9-13:
参见《总则》建议9-13。
10代码编辑、编译、审查
规则10-1:
参见《总则》规则10-1。
规则10-2:
参见《总则》规则10-2。
规则10-3:
参见《总则》规则10-3。
规则10-4:
参见《总则》规则10-4。
规则10-5:
使用代码审查工具(如C语言用PC-LINT)对源程序检查。
建议10-1:
参见《总则》建议10-1。
建议10-2:
参见《总则》建议10-2。
建议10-3:
参见《总则》建议10-3。
建议10-4:
参见《总则》建议10-4。
建议10-5:
参见《总则》建议10-5。
建议10-6:
参见《总则》建议10-7。
11与硬件有关的操作
规则11-1:
可兼容多种硬件版本的单板软件在开工前要先读硬件的版本,根据不同的硬件版本运行相应的程序。
说明:
不同的硬件版本可能对软件有不同的要求,如果不读版本往往会导致系统无法开工等问题。
规则11-2:
在单板开工前,要根据读到的硬件版本的具体情况来初始化片内寄存器和外围接口芯片,在做这些初始化时要注意前后次序要正确。
说明:
未做初始化或因前后次序不对而导致的前后次序无效,会引起单板不开工或工作不正常。
规则11-3:
在单板开工前,要对片内、片外内存做必要的检测,在确认内存正确后还要对内存做初始化,也就是所谓的“清内存”。
规则11-4:
看门狗(WDT)的定义和使用要小心谨慎。
说明:
WDT时长的确定不要过分信任习惯用法,一定要亲自去测试,得到系统正常运行和最忙碌时的循环周期,不要出现因WDT时长过短而导致系统在正常运行时复位。
刷新WDT的位置要是确定的,不要在中断中刷新WDT。
规则11-5:
中断服务程序是影响系统实时性的关键部分,所以应该尽可能短,可以不在中断服务程序中做的事情一定要拿到外面来做,保证中断能及时退出。
规则11-6:
在中断服务程序中调用的函数应该具有可重入的特性,中断服务程序修改的全局变量应该用信号量来保护。