嵌入式编程规范及注意事项

article/2025/10/30 16:39:12

嵌入式系统已经在各行各业中得到了广泛的应用,随着人们的生活向信息化,智能化的发展,嵌入式技术将彻底融入到我们的生活,在我们的生活当中扮演越来越重要的角色。对于嵌入式系统来讲,嵌入式软件相当于嵌入式系统的灵魂,整个嵌入式系统如何工作,都是由嵌入式软件来控制的。如何编写高质量,高效率的嵌入式软件在实际项目开发过程中变的越来越重要。本文针对嵌入式软件的特点,从嵌入式软件编程规范和注意事项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。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。(点击找小助理领取)

 


http://chatgpt.dhexx.cn/article/VshItlE6.shtml

相关文章

嵌入式编程学习路线图-精心总结

大家好&#xff01;我是木荣君&#xff0c;今天给大家分享一下嵌入式软件开发学习路线图。这是我按照自己最开始学习嵌入式的时候的学习路线&#xff0c;并且结合自己在多年开发工作中所涉及的知识精心总结的嵌入式软件开发思维导图。这是木荣君精心总结的&#xff0c;花费了不…

嵌入式软件编程模式

文章目录 嵌入式软件编程模式基于周期调用的运行模式基于中断的前后台运行模式基于事件队列的运行模式带时间信息的事件队列运行模式周期任务运行框架 整理自&#xff1a;《AI嵌入式系统&#xff1a;算法优化与实现》 本章介绍嵌入式软件编程模式和通用软件优化方案。嵌入式软件…

其实嵌入式编程还是很难很复杂的

关注、星标公众号&#xff0c;直达精彩内容 来源&#xff1a;coolbacon 能从PC机器编程去看嵌入式问题&#xff0c;那是第一步&#xff1b;学会用嵌入式编程思想&#xff0c;那是第二步&#xff1b;用PC的思想和嵌入式的思想结合在一起&#xff0c;应用于实际的项目&#xff0c…

嵌入式开发常用技巧及编程知识

嵌入式开发常用技巧及C/C知识 引言查询程序占据的内存大static 静态变量介绍static在函数中的用法 ‘##’连接符断言函数宏定义与条件变量#if...#else...#endif选择是否使用串口调试 memcpy函数void 指针指针大小 字符串小写转大写字符串大写转小写字符串命令处理将某几位清0&a…

嵌入式程序编写方法与规范

嵌入式程序编写方法与规范 前言 本文主要讲解嵌入式单片机程序的编写方法以及编写规范&#xff0c;以MSP430单片机作为例子&#xff0c;无论是51,AVR还是STM32单片机都同样适用&#xff0c;本文对C语言各种语法各种关键字进行详细解释&#xff0c;对操作物理地址的方法进行剖析…

嵌入式系统C语言编程基础

目录 关于本环节前言专栏为什么进行本环节 小测验解答 C语言复习1.循环与分支2.作用域与存储类3.内存与指针指针 4.位操作(1)位操作的用途(2)位运算符(3)用法&#xff1a;掩码(4)用法&#xff1a;打开位、关闭位、转置位(5)用法&#xff1a;查看某一位的值(6)用法&#xff1a;移…

密码学学习笔记三:同余定理

同余定理 我们在《密码学学习笔记二&#xff1a;RSA加密法》里面提到过同余&#xff0c;此处把同余作为补充知识&#xff0c;单独写一篇文章讲解一下。 同余定理是数论中的重要概念。给定一个正整数m&#xff0c;如果两个整数a和b满足&#xff08;a-b&#xff09;能够被m整除&a…

简单理解-同余定理

本文章仅用于笔记。部分知识点来源于网络&#xff0c;授权请联系作者&#xff08;947043511qq.com&#xff09;。 直接抛出自己的理解&#xff1a; 2个不同的整数a、b&#xff0c;被一个整数m相除时&#xff0c;得到相同的余数&#xff0c;那么我就可以称a、b同余。 因为a、b同…

以太坊EVM源码注释之执行流程

以太坊EVM源码分析之执行流程 业务流程概述 EVM是用来执行智能合约的。输入一笔交易&#xff0c;内部会将之转换成一个Message对象&#xff0c;传入 EVM 执行。在合约中&#xff0c;msg 全局变量记录了附带当前合约的交易的信息&#xff0c;可能是为了一致&#xff0c;这里也…

【密码学探秘】EVM链和并行执行交易

概述 在web3.0世界中&#xff0c;交易的处理性能一直是公链面临的一大技术挑战&#xff0c;如何在不降低安全性和去中心化程度的前提下显著的提升区块链交易的TPS无疑成为众多公链技术专家追逐的目标。以Solana、Aptos为代表的新一代公链的出现更是吹响了通过并行执行交易来攻…

MATLAB计算EVM函数

function [rmsEVM,maxEVM,pctEVM,numSym] EVMcalculate(RxSig,TxSig)%RxSig为接收信号解调后复基带信号&#xff1b;TxSig是发射信号的复基带信号。 %计算接收信号EVM和画星座图 %RxSig,TxSig长度要一样&#xff1b; evm comm.EVM(‘MaximumEVMOutputPort’,true,… ‘XPerce…

通信算法之149:EVM测量

1.星座图 h scatterplot(sqrt(sps)*txSig(sps*span1:end-sps*span),sps,offset); hold on scatterplot(rxSigFilt(span1:end-span),n,offset,bx,h) scatterplot(dataMod,n,offset,r,h) legend(Transmit Signal,Received Signal,Ideal,location,best) 2. 眼图 Eye Diagram D…

以太坊虚拟机 EVM(2)Solidity运行原理

作者&#xff1a;储雨知&#xff5c;FISCO BCOS 核心开发者 引 言 作为一门面向智能合约的语言&#xff0c;Solidity与其他经典语言既有差异也有相似之处。 一方面&#xff0c;服务于区块链的属性使其与其他语言存在差异。例如&#xff0c;合约的部署与调用均要经过区块链网…

IMA/EVM完整性检测代码分析

IMA/EVM完整性检测 IMA&#xff08;Integrity Measurement Architecture&#xff09;是一个内核安全子系统&#xff0c;用于检测文件或数据的完整性和安全性。IMA的hook机制指的是内核接口钩子&#xff08;kernel interface hooks&#xff09;&#xff0c;用于向IMA注册和实现…

为何Cable Loss没补好 EVM会变差

当EVM不好 或是灵敏度不好时 先别急着找硬件问题 先检查Cable Loss 先说结论 先谈谈标题 为何Cable Loss没补好 EVM会变差 多数射频功放输出 会接一个耦合器 将输出功率 耦合到收发器 用意是校正时 侦测输出功率的正确性与否 假设天线头为20dBm Cable loss为5dB 假设天线头…

TI毫米波级联雷达评估板 MMWCAS-DSP-EVM 和MMWCAS-RF-EVM

1. 前言 本文主要是TI的MMWCAS-DSP-EVM 和MMWCAS-RF-EVM 两块评估板的一些使用心得和毫米波雷达的学习总结。 2. 相关原理 毫米波(mmWave)是一类使用短波长电磁波的特殊雷达技术。通过捕捉反射的信号&#xff0c;雷达系统可以确定物体的距离、速度和角度。毫米波雷达可发射波…

DCA1000EVM使用指南

DCA1000EVM使用指南 一、开发环境 1、硬件 AWR1243/xWR1443/xWR1642BOOST&#xff08;本文以IWR1642BOOST为例&#xff09;DCA1000EVM5V/2.5A&#xff08;电流要求不小于2.5A&#xff09;电源适配器1个或2个 micro USB线2条RJ45网线1根60引脚Samtec连接线&#xff08;DCA100…

EVM误差矢量幅度

EVM误差矢量幅度是衡量调制精度的一个主要指标&#xff0c;镜像频率的抑制度对EVM的影响取决于镜像频率的抑制度&#xff0c;一般镜像频率抑制度达到31dBc时&#xff0c;对EVM的影响约为5%。镜像频率对信号的影响是因为镜像频率的信号带宽与所需信号的带宽一样&#xff0c;而无…

区块链 以太坊 虚拟机 EVM 详解

一、虚拟机 虚拟机用来 执行以太坊上的交易&#xff0c;更改以太坊状态。 交易分两种&#xff1a; 普通交易智能合约交易。 在执行交易时需要支付油费。 智能合约之间的调用有四种方式。 二、以太坊虚拟机 以太坊虚拟机&#xff0c;简称 EVM&#xff0c;是用来执行以太坊…

以太坊EVM智能合约中的数据存储

目录 EVM基本信息 数据管理 Stack Args Memory Storage 固定长度的值 动态长度数组 Mappings 复杂类型的组合 总结 EVM基本信息 以太坊是一种基于栈的虚拟机&#xff0c;基于栈的虚拟机数据的存取为先进先出&#xff0c;在后面介绍EVM指令的时候会看到这个特性。同时基…