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

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

3天内不再提示

嵌入式代码之编写规范

GReq_mcu168 来源:工程师李察 2019-04-26 15:21 次阅读

嵌入式代码编码规范,用于规范自己的代码,增强可读性,非标准规范。最好能强制自己形成良好的编码风格,有利于开发大规模程序而不显得杂乱。参考STM32固件库编码风格和FreeRTOS编码风格。

一、工程文件组织结构

新建工程文件应包含以下全部或部分文件夹:

usrSrc:用户源文件,用来存放.c文件和其他的源文件。main.c应放在这里。

usrInc:用户头文件,用来存放.h文件。

usrDoc:用户说明文档,用来存放用户在开发过程中书写的文档,一般为.txt格式。例如Readme.txt,指令说明等。

Src:引用库的源文件。

Inc:应用库的头文件。

Lib:引用的库文件。

一个工程一定要包含一个main.c文件,只用来存放main函数。其余函数的定义应在相应的.c文件中,声明在相应的.h文件中。

So can you help to prepare our suggest contents display in the page (e.g. tools intro, feature, which videos, which documents etc) to us first? We will then further discuss with Infineon if anything need to change / add.

二、源文件

文件头,文件的简介

/************************************************************************* * Copyright (c) 2018, Xiaodan * All rights reserved. * * File name : USB_Ctrl.c * Brief : USB API source code. * Introduce the main function or content of this document briefly. * Revision : 1.01 * Author : Xiaodan * Date : 2018.11.06 * Update : Introduce the difference from previous version.*************************************************************************/

必要的注释和说明

源文件应该只包含它自己的头文件,其他的头文件在他自己的头文件中包含。

源文件中只声明局部函数,全局函数在头文件中声明。

全局变量在相应的源文件中定义,在头文件中用extern声明。

类型定义在头文件中定义。

/* Includes -----------------------------------------------------------*//*only include it's own header file, the others header file included by USB_Ctrl.h*/#include "USB_Ctrl.h"/* Declaration --------------------------------------------------------*//*here are the local function declare, global fuction declare in header file.*/void delay( uint32_t n);/* Global variable ----------------------------------------------------*/

函数头

/****************************************************** * Brief : Delay n ms * Parameter : * n: the number of delay microsecond. * Return : None.*******************************************************/void delay( uint32_t n){for( i=0; i<110; i++) ;}

三、头文件

文件头,文件的简介

/************************************************************************* - Copyright (c) 2018, Xiaodan - All rights reserved. - - File name : USB_Ctrl.h - Brief : The header file of USB_Ctrl.c. - Revision : 1.01 - Author : Xiaodan - Date : 2018.11.06 - Update : Introduce the difference from previous version.*************************************************************************/

必要的注释和声明

/* Includes -----------------------------------------------------------*//* Define -------------------------------------------------------------*//* Typedef ------------------------------------------------------------*/typedef unsigned int apiStatus; //api return code/* Enume --------------------------------------------------------------*//* Extern -------------------------------------------------------------*//* Declaration --------------------------------------------------------*/

四、命名规则

参考FreeRTOS命名规则,MISRA C规范。

定义变量时尽量使用uint8_t 、uint16_t 、uint32_t等。头文件为stdint.h。

typedef signed char int8_t;typedef short int16_t;typedef int int32_t;typedef long long int64_t;typedef unsigned char uint8_t;typedef unsigned short uint16_t;typedef unsigned int uint32_t;typedef unsigned long long uint64_t;

uint32_t类型的变量使用前缀ul,这里’u’表示’unsigned’,’l’表示’long’

uint16_t类型的变量使用前缀us,这里’u’表示’unsigned’,’s’表示’short’

uint8_t类型的变量使用前缀uc,这里’u’表示’unsigned’,’c’表示’char’

枚举类型变量使用前缀e

指针类型变量在类型基础上附加前缀p,比如指向uint16_t的指针变量前缀为pus

与MISRA指南一致,char类型变量仅被允许保存ASCII字符,前缀为c

与MISRA指南一致,char *类型变量仅允许指向ASCII字符串,前缀为pc

宏定义全部使用大写,两个单词之间用下划线隔开。

具有文件作用域的对象尽量声名为static的。

全局变量加前缀’g_’。整个工程都可以用的变量,不局限于文件作用域。

五、代码风格

缩进:缩进使用制表符,一个制表符等于4个空格。

注释:注释单行不超过80列,特殊情况除外。

布局:源代码应被设计成尽可能的易于查看和阅读。

下面的代码片中,第一部分展示文件布局,第二部分展示C代码设计格式。

/* #defines, 在合理的位置添加括号. */#define A_DEFINITION ( 1 )/* * 随后是Static (文件内部的)函数原型, * 如果注释有多行,参照本条注释风格---每一行都以’*’起始. */static void prvAFunction( uint32_t ulParameter );/* 文件作用域变量(本文件内部使用),要在函数体定义之前. */static BaseType_t xMyVariable./* 每一个函数的结束都有一行破折号,破折号与下面的第一个函数之间留一行空白。*//*-----------------------------------------------------------*/void vAFunction( void ){/* 函数体在此定义,注意要用大括号括住 */}/*-----------------------------------------------------------*/static UBaseType_t prvNextFunction( void ){/* 函数体在此定义. */}/*-----------------------------------------------------------*//* * 函数名字总是占一行,包括返回类型。左括号之前没有空格左括号之后有一个空格, * 每个参数后面有一个空格,参数的命名应该具有一定的描述性. */void vAnExampleFunction( long lParameter1, unsigned short usParameter2 ){/* 变量声明没有缩进. */uint8_t ucByte;/* 代码要对齐. 大括号占独自一行. */for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ ) {/* 这里再次缩进. */ }}/* * for、while、do、if结构具有相似的模式。这些关键字和左括号之间没有空格。 * 左括号之后有一个空格,右括号前面也有一个空格,每个分号后面有一个空格。 * 每个运算符的前后各一个空格。使用圆括号明确运算符的优先级。不允许有0 * 以外的数字(魔鬼数)出现,必要时将这些数字换成能表示出数字含义的常量或 * 宏定义。 */for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ ){}while( ucByte < fileBUFFER_LENGTH ){}/* * 由于运算符优先级的复杂性,我们不能相信自己对运算符优先级时刻保持警惕 * 并能正确的使用,因此对于多个表达式运算时,使用括号明确优先级顺序 */if( ( ucByte < fileBUFFER_LENGTH ) && ( ucByte != 0U ) ){ ulResult = ( ( ulValue1 + ulValue2 ) - ulValue3 ) * ulValue4;}/* 条件表达式也要像其它代码那样对齐。*/#if( configUSE_TRACE_FACILITY == 1 ){/* 向TCB增加一个用于跟踪的计数器. */ pxNewTCB->uxTCBNumber = uxTaskNumber;}#endif/*方括号前后各留一个空格*/ucBuffer[ 0 ] = 0U;ucBuffer[ fileBUFFER_LENGTH - 1U ] = 0U;

六、编程思想

将特定功能的代码封装成函数。

七、C语言编程规则

参考MISRA

Rule1:不得使用三元操作符(? : )。

Rule2:不得残留被注释掉的废代码。

Rule3:所有标识符不超过31字符。

Rule4:不同名空间中的变量名不得相同。

例如:

typedef struct MyStruct {... } MyStruct; (违规) struct Person { char* name; ...};char name[32]; (违规)

Rule5: 不得使用char, int, float, double, long等基本类型,应该用stdint.h中定义的类型显示表示类型的大小,如uint16_t、int32_t等。

Rule6:禁止使用八进制数。(因为086U这样的常数很容易引起误解)。

Rule7:不得定义与外部作用域中某个标识符同名的对象,以避免遮盖外部作用域中的标识符。

Rule8:具有文件作用域的对象尽量声名为static的。

Rule9:自动对象(栈对象)使用前必须赋初值。

Rule10:操作符&&和||的右侧表达式不得具有副作用(side-effect)。

也就是说,象 if (x == 20 && ++y == 19)这样的表达式被禁止。

Rule11:不得对有符号数施加位操作,例如 1 << 4 将被禁止,必须写 1UL << 4。

Rule12:不得对有副作用的表达式施加sizeof操作符。

Rule13:除了循环控制语句,不得使用逗号表达式。

Rule14:不得显式判断浮点数的相等性和不等性。

Rule15:不得遗留“永远不会用到”的代码。

Rule16:除了switch语句,不得使用标号(label)。

Rule17:不得使用goto。

Rule18:不得使用continue。

Rule19:除了switch语句,不得使用break

Rule20:if, else if, else, while, do..while, for语句块必须使用{}括起。

Rule21:循环计数器的值不得在循环体内修改。

Rule22:禁止任何直接和间接的递归函数调用。

Rule23:不应该使用#undef。

Rule24:不得将宏作为参数传给宏函数。

Rule25:在一个宏定义中,#或##符号只能出现一次。

Rule26:禁止指针运算(代之以数组下标运算)。

Rule27:禁止超过两级的指针。

Rule28:禁止使用指向函数的非常量指针。

Rule29:禁止使用setjmp, longjmp。

Rule30:禁止使用atoi, atof, atol。(这个我很赞成,建议使用strtol, strtod等函数)

Rule31:禁止使用abort, exit, getenv。

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

    关注

    5068

    文章

    19008

    浏览量

    302942
  • 函数
    +关注

    关注

    3

    文章

    4303

    浏览量

    62409
  • 工程
    +关注

    关注

    0

    文章

    165

    浏览量

    27838

原文标题:如何增强代码的可读性?嵌入式代码之编写规范

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    一文了解嵌入式软件开发的对象

    以前应用场景很单一,嵌入式开发可能谈不上面向对象开发。但现在,做嵌入式开发,没有面向对象开发,你就有点落伍了。 本文结合个人经验和周立功《抽象接口技术和组件开发规范及其思想》,循序渐进的用
    的头像 发表于 11-15 10:31 227次阅读
    一文了解<b class='flag-5'>嵌入式</b>软件开发的对象

    嵌入式学习建议

    动手做一个实际的小系统,底层硬件基础就有了。各个硬件模块驱动程序的编写嵌入式系统的必备基础。学习嵌入式系统的初期,这个过程是必须的。 ④至于嵌入式实时操作系统RTOS,一定不要一开
    发表于 10-22 11:41

    什么是嵌入式?一文读懂嵌入式主板

    在现代科技浪潮中,嵌入式技术已成为支撑各种智能设备和系统运行的核心力量。那么,究竟什么是嵌入式嵌入式系统,顾名思义,是将计算机的硬件和软件嵌入到某种设备或系统中,以实现特定功能的计算
    的头像 发表于 10-16 10:14 474次阅读

    嵌入式主板是什么意思?嵌入式主板全面解析

    嵌入式主板,通常被称为嵌入式系统的核心组件,是一种用于控制和数据处理的计算机硬件,其设计旨在嵌入特定设备中执行专门任务。嵌入式主板如同是设备的“大脑”,主要功能是根据需要管理和控制设备
    的头像 发表于 09-30 10:05 354次阅读

    北京迅为RK3568开发板嵌入式学习Linux驱动全新更新-CAN+

    北京迅为RK3568开发板嵌入式学习Linux驱动全新更新-CAN+
    的头像 发表于 09-04 15:29 393次阅读
    北京迅为RK3568开发板<b class='flag-5'>嵌入式</b>学习<b class='flag-5'>之</b>Linux驱动全新更新-CAN+

    如何提升嵌入式编程能力?

    :掌握嵌入式系统的基本原理,包括中断、并发、实时操作、低功耗设计等。 3. 实践编程:通过实际编写和测试代码来提高技能。从简单的LED闪烁程序开始,逐步过渡到更复杂的项目,如定时器PWM应用、串口、IIC
    发表于 06-21 10:01

    从事嵌入式方向,一定要软硬件通吃?

    软件工程师的职责嵌入式软件工程师的主要职责是为嵌入式系统编写和调试代码,确保系统按预期工作。他们需要处理底层硬件接口、实时操作系统(RTOS)、驱动程序和应用层软件。
    的头像 发表于 06-05 08:10 1069次阅读
    从事<b class='flag-5'>嵌入式</b>方向,一定要软硬件通吃?

    嵌入式系统中C语言的编写规范

    一间一尘不染的房子。 因此,无论本文推荐的是什么,如果已经编写代码并且您正在对其进行修补,请保持其当前的样式一致,即使它不是您最喜欢的样式。   一般规则 这里列出了最明显和最重要的一般规则。在你继续阅读其他章节
    的头像 发表于 05-11 08:49 1005次阅读

    嵌入式fpga是什么意思

    嵌入式FPGA是指将FPGA技术集成到嵌入式系统中的一种解决方案。嵌入式系统是一种为特定应用而设计的计算机系统,它通常包括处理器、内存、外设接口等组件,并且被嵌入到更大的设备或系统中,
    的头像 发表于 03-15 14:29 1187次阅读

    fpga是嵌入式

    FPGA(现场可编程门阵列)不是嵌入式系统,但FPGA在嵌入式系统中有着重要的应用。
    的头像 发表于 03-14 17:19 2137次阅读

    嵌入式学习步骤

    语言编写。但是,有些嵌入式系统也使用其他编程语言,例如Python或Java。 (3).了解硬件:深入了解您要控制的硬件设备的功能和特性。您需要了解嵌入式系统的处理器、内存、I/O端口、传感器和其他
    发表于 02-02 15:24

    单片机、嵌入式入门实验报告相关代码仿真介绍

    电子发烧友网站提供《单片机、嵌入式入门实验报告相关代码仿真介绍.zip》资料免费下载
    发表于 12-22 10:52 11次下载

    什么是嵌入式系统?嵌入式系统的具体应用

    嵌入式,一般是指嵌入式系统。用于控制、监视或者辅助操作机器和设备的装置。
    的头像 发表于 12-20 13:33 2381次阅读

    嵌入式硬件和软件哪个好?

    嵌入式硬件和软件哪个好? 嵌入式软硬件工程师哪个更有前途呢?一起来看看。 嵌入式是分为软硬件工程师的,首先我们先来看看嵌入式硬件工程师吧! 嵌入式
    发表于 12-05 15:17

    嵌入式核心板开发ESD静电保护

    嵌入式核心板开发ESD静电保护
    的头像 发表于 11-28 17:55 587次阅读
    <b class='flag-5'>嵌入式</b>核心板开发<b class='flag-5'>之</b>ESD静电保护