嵌入式系统已经在各行各业中得到了广泛的应用,随着人们的生活向信息化,智能化的发展,嵌入式技术将彻底融入到我们的生活,在我们的生活当中扮演越来越重要的角色。对于嵌入式系统来讲,嵌入式软件相当于嵌入式系统的灵魂,整个嵌入式系统如何工作,都是由嵌入式软件来控制的。如何编写高质量,高效率的嵌入式软件在实际项目开发过程中变的越来越重要。本文针对嵌入式软件的特点,从嵌入式软件编程规范和注意事项2个方面来阐述如何编写高质量的嵌入式软件。

一、 嵌入式编程规范

我们在公司进行嵌入式项目开发的时候,并不是你一个人在单打独斗,通常是一个团队在一起战斗。很多人在一起共同完成一个嵌入式项目,通常是每个成员,每个小组完成整个项目中的一个或几个模块。我们编写的代码首先是给人看的,其次才是给机器执行的,这就要求我们团队中的每个人在编写软件的时候,要遵循统一的编程规范和编码风格,提高代码的可读性和可维护性,方便团队成员之间的沟通和交流。在实际项目开发过程中,遵循统一的编程规范相当重要,同学们一定要引起足够的重视,下面我就从代码排版,代码注释,标识符命名,代码可读性和函数设计几个方面来讲解比较通用的嵌入式软件编程规范。

1. 代码排版

1) 程序块要采用缩进风格编写, 缩进的空格数为4个或一个TAB键,设置TAB键为

4个空格.

例如:

int main(int argc, char *argv[])

{

int a=900; //缩进4个空格

}

2) 相对独立的程序块之间、变量说明之后必须加空行

例如:

if (!valid_ni(ni))

{

... // program code

}

//相对独立的程序块之间加空行

repssn_ind = ssn_data[index].repssn_index;

repssn_ni = ssn_data[index].ni;

3) 较长的语句( >80字符)要分成多行书写, 长表达式要在低优先级操作符处划

分新行,操作符放在新行之首, 划分出的新行要进行适当的缩进, 使排版整齐,

语句可读。

例如:

perm_count_msg.head.len = NO7_TO_STAT_PERM_COUNT_LEN

+ STAT_SIZE_PER_FRAM * sizeof( _UL );

4) 不允许把多个短语句写在一行中,即一行只写一条语句。

例如:

rect.length = 0;

rect.width = 0;

5) if、 for、 do、 while、 case、 switch、 default等语句自占一行,且if、 for、do、

while等语句的执行语句部分无论多少都要加括号{}。

例如:

if (pUserCR == NULL) //if语句单独占一行

{ //执行语句只有1条也要加{}

return;

}

6) 程序块的分界符(如C/C++语言的大括号‘ {’和‘ }’)应各独占一行并且位

于同一列, 同时与引用它们的语句左对齐。 在函数体的开始、 类的定义、 结

构的定义、 枚举的定义以及if、 for、 do、 while、 switch、 case语句中的

程序都要采用如上的缩进方式.

例如:

for (...)

{ //{}单独占一行,与for左对齐

... // program code

}

void example_fun(void)

{

... // program code

}

2. 代码注释

1) 注释的原则是有助于对程序的阅读理解,在该加的地方都加了,注释不宜太多也不

能太少, 注释语言必须准确、易懂、简洁,防止注释的二义性.

2) 说明性文件(如头文件.h文件)头部应进行注释, 注释必须列出:版权说明、版本

号、生成日期、作者、内容、功能、 修改日志等, 头文件的注释中还应有函数功能

简要说明。

例如:

Copyright (C), 2004-2018, 华清远见教育集团.

File name: // 文件名

Author: Version: Date: // 作者、版本及完成日期

Description: // 用于详细说明此程序文件完成的主要功能,与其他模块

// 或函数的接口,输出值、取值范围、含义及参数间的控

// 制、顺序、独立或依赖等关系

Function List: // 主要函数列表,每条记录应包括函数名及功能简要说明

1. ....

History: // 修改历史记录列表,每条修改记录应包括修改日期、修改

// 者及修改内容简述

1. Date:

Author:

Modification:

2. ...

3) 源文件头部应进行注释, 列出: 版权说明、 版本号、 生成日期、 作者、 模块目的/功能、主要函数及其功能、 修改日志等.

例如:

Copyright (C), 1988-2018, 华清远见教育集团.

FileName: test.cpp

Author: Version : Date:

Description: // 模块描述

Function List: // 主要函数及其功能

1. -------

History: // 历史修改记录

David 96/10/12 1.0 build this moudle

4) 函数头部应进行注释,列出函数的功能、输入参数、输出参数、返回值等。

例如:

Function: // 函数名称

Description: // 函数功能、性能等的描述

Input: // 输入参数说明,包括每个参数的作用、取值说明及参数间关系。

Output: // 对输出参数的说明。

Return: // 函数返回值的说明

Others: // 其它说明

5) 边写代码边注释, 修改代码同时修改相应的注释, 以保证注释与代码的一致

性。 不再有用的注释要删除。

6) 注释应与其描述的代码相近, 对代码的注释应放在其上方或右方(对单条语句

的注释)相邻位置, 不可放在下面,如放于上方则需与其上面的代码用空行隔开。

3. 标识符命名

1) 标识符的命名要清晰、 明了, 有明确含义, 同时使用完整的单词或大家基本

可以理解的缩写,避免使人产生误解.

2) 对于变量命名,禁止取单个字符(如i、 j、 k...) ,建议除了要有具体含义外,

还能表明其变量类型。建议在变量前面加前缀 g表示全局变量,m表示形式参数.

例如: int gCount = 0;

3) 命名规范必须与所使用的系统风格保持一致,并在同一项目中统一,比如采用

UNIX的全小写加下划线的风格或大小写混排的方式, 不要同时使用大小写与下

划线混排的方式。

例如: char total_score =0;

4) 函数名应准确描述函数的功能,使用动宾词组为执行某操作的函数命名。

例如:

int input_record( void )

unsigned char get_current_color( void )

5) 除非必要,不要用数字或较奇怪的字符来定义标识符

6) 用正确的反义词组命名具有互斥意义的变量或相反动作的函数等

4. 代码可读性

1) 注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级

例如:不要这样写: word = high << 8 | low

而应该写成如下这样: word = (high << 8) | low

2) 避免使用不易理解的数字, 用有意义的标识来替代。 涉及物理状态或者含有物理意

义的常量,不应直接使用数字,必须用有意义的枚举或宏来代替.

例如:

#define TRUNK_IDLE 0

#define TRUNK_BUSY 1

if (Trunk[index].trunk_state == TRUNK_IDLE)

{

Trunk[index].trunk_state = TRUNK_BUSY;

... // program code

}

3) 不要使用难懂的技巧性很高的语句,除非很有必要时.

例如: 不要使用类似这样的难懂的语句 *stat_poi++ += 1; 应该分成多个语句

书写,增强代码可读性.

二、嵌入式编程中的注意事项

嵌入式软件开发和普通软件编程相比,有一些自己的特点,下面从嵌入式软件架构,中断编程,寄存器配置,浮点运算等几个方面来讲解嵌入式编程中的注意事项.

1. 嵌入式系统的软件架构

一个大型的嵌入式软件往往需要根据功能的不同划分成多个软件功能模块。

1) 模块即是一个.c文件和一个.h文件的结合,头文件(.h)中是对于该模块接口的声明;

2) 某模块提供给其它模块调用的外部函数及数据需在.h中文件中冠以extern关键字

声明;

3) 模块内的函数和全局变量需在.c文件开头冠以static关键字声明;

4) 永远不要在.h文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分

配的操作,是汇编阶段的概念;而声明则只是告诉包含该声明的模块在连接阶段从

其它模块寻找外部函数和变量

2. 中断编程

中断是嵌入式系统中重要的组成部分,但是在标准C中不包含中断。 许多编译开发商在标准C上增加了对中断的支持,提供新的关键字用于标示中断服务程序. 类似于__interrupt、#program interrupt等。当一个函数被定义为中断服务处理程序的时候,编译器会自动为该函数增加中断服务程序所需要的中断现场入栈和出栈代码。

中断服务程序需要满足如下要求:

1) 不能有返回值;

2) 不能向中断服务处理程序传递参数;

3) 中断服务处理程序应该尽可能的短小精悍,不要包含耗时的代码

3. 寄存器配置

嵌入式软件是面向硬件底层的软件,我们在对硬件进行编程时,通常是通过配置硬件相关的寄存器来实现的。在配置寄存器时,通常我们只需要配置寄存器的1位或几位,对于其他不需要配置的位,我们要保持不变,不要更改我们不需要配置的位。

例如:我们希望配置寄存器的 GPIOADAT 的第 1位 为 1

我们不能这样写成这样:

GPIOADAT = 0x02; //将其他位设置为 0

而应该写成这样:

GPIOADAT |= 0x02; //保证其他位不变

4. 浮点运算

大多数低档次的单片机都是不支持浮点运算的,因此在实际使用过程中也很少用到,因此为了降低成本,一般都去掉了浮点运算模块,这就带来了一个问题,如果万一要用到浮点运算怎么办?我们可以采用的是“定点”的方法来解决这个问题,就是直接放大10的N次方倍进行整数的计算,可以得出近似值,因此为了不增加不必要的麻烦,应该总是尽量避免使用浮点运算,一般情况也是可以避免的。

5. volatile 关键字的使用

嵌入式开发过程中,在定义硬件寄存器的时候,需要使用volatile关键字。 volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。 如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值。

例如: #define GPIO_DATA (*(volatile unsigned int *)0x90002000)

以上就是我今天要给同学们讲解的嵌入式软件编程规范和注意事项,希望同学们在实际的嵌入式项目开发过程中严格遵循嵌入式软件编程规范和注意事项,开发出高质量,稳定,可靠,维护性高的嵌入式软件。

嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!

无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。(点击找小助理领取)

嵌入式编程规范及注意事项相关推荐

  1. 嵌入式编程规范与原则

    嵌入式编程原则和规范 编程规范 编程原则 编程思想 架构思想 IDA分层思想 函数编写原则 模板示例 编程规范 1.文件名尽可能以模块名命名,统一小写(根据个人风格调整).如led模块led.c.le ...

  2. 嵌入式C语言编程规范(个人规约)

    0规范制定说明 0.1箴言 技术人员设计程序的首要目的是用于技术人员沟通和交流,其次才是用于机器执行.程序的生命力在于用户使用,程序的成长在于后期的维护及根据用户需求更新和升级功能.如果你的程序只能由 ...

  3. 嵌入式C语言编程规范

    前言 代码首先是给人看的,其次才是给机器执行的,因此一般情况下代码的可读性优先于性能,只有确定性能是瓶颈时,才需要主动优化. 可读性高的代码应当是易于理解并且易于实现的,代码越长越难看懂,可能出错的地 ...

  4. 嵌入式Linux入门12:编程规范

    作为一名软件工程师,日常与代码打交道,免不了接触到编程规范.而编程规范,可谓是各式各样,不同系统有不同风格,不同公司有不同风格.就笔者经历而言,在学生年代学习单片机编程时已经开始建立自己的" ...

  5. 嵌入式编程之模块化编程

    原文出处:http://blog.csdn.net/wanruoqingkong/article/details/24286625 当你在一个项目小组做一个相对较复杂的工程时,意味着你不再独自单干.你 ...

  6. 华为c语言编程规范_C语言编程规范

    一.简介 代码编写规则应该在建立一个工程项目之前,应该贯穿整个项目的始终,以保证代码的一致性.采用标准的代码编写惯例,可以大大简化项目的维护负担.采用一种好的风格,以达到以下目的:可移植性.连贯.整洁 ...

  7. C语言编程规范 学习笔记

    C语言编程规范 一.代码总体原则 1.清晰 2.简洁 3.选择适合的风格,与代码原有风格保持一致 二.头文件 背景 术语定义 原则 2.1 头文件中适合放置接口的声明,不适合放置实现 原则 2.2 头 ...

  8. C/C++编程规范整理

    一.基本准备工作 1.设计工程目录结构 (1)基本原则: [1]工程本身的文件.项目编译生成的中间文件放一个文件夹: [2]最终生成的目标文件单独放一个文件夹: [3]如果有工程依赖的库文件等单独放一 ...

  9. 中兴软件编程规范C/C++

    Q/ZX 深圳市中兴通讯股份有限公司企业标准 (设计技术标准) Q/ZX 04.302.1–2003      软件编程规范C/C++                               20 ...

最新文章

  1. https ssl 总结
  2. Java并发编程--ReentrantReadWriteLock
  3. 字典-变量的定义以及应用场景
  4. 数字电视制播设备间的文件交换格式
  5. Conv2d中的groups参数(分组卷积)怎么理解? 【分组卷积可以减少参数量、且不容易过拟合(类似正则化)】
  6. 开创先河!《王者荣耀国际版》成为东南亚运动会正式比赛项目
  7. html文档是哪个版本,Pro010-从零开始HTML[#010]——5分钟-HTML 文档类型版本
  8. VMware新建虚拟机(CentOS)步骤详解
  9. SK-Learn之决策树
  10. 区块链 以太坊 solidity 如何比较2个字符串相等
  11. 通过windows的超级终端连接华为交换机
  12. 智能优化及其相关算法
  13. 一个小的java作业,第一次上传CSDN,原创的
  14. vscode连接模拟器运行flutter项目
  15. 囧,现在才只QQ有远程控制
  16. os.system() 和os.popen()的区别
  17. bzoj4416 阶乘字符串 子集dp
  18. Windows上搭建安卓的JAVA开发环境(Eclipse版本)
  19. Python环境配置和安装包总结
  20. 黑鲨3怎么安装鸿蒙系统,黑鲨3 Pro机械按键详解,横握时可进行高频点击操作

热门文章

  1. Cesium加载模型两种方式
  2. App Store最新审核标准,中文版
  3. crc32校验的c语言实现
  4. [转]研究生能力自我培养手册
  5. 校园网站毕业设计,校园网站设计与实现,校园网站论文作品参考
  6. 【图分析】Centrality
  7. javaswing员工工资系统java swing mysql 员工工资管理系统源码和导入文档(1014)
  8. 如何将 DAT 转换为 MP4
  9. 员工寄件管理流程设计
  10. Swift - JSON