阅读STM32-hal库代码得到的几点C代码编程规范

发布时间 2023-12-22 11:37:21作者: HAOstudio

阅读STM32-hal库代码得到的几点C代码编程规范

规范一:
头文件使用

#ifndef _XXX_H
#define _XXX_H

#ifdef __cplusplus
extern "C" {
#endif


// 头文件内容


#ifdef __cplusplus
}
#endif
#endif

在C++编译环境中,会定义__cplusplus宏,如果在C++代码中需要使用C语言的函数和变量,就需要使用extern "C" {...}将C语言的代码放在花括号中,表示其中的代码需要按照C语言的规则进行编译。

如果在C语言环境中,没有__cplusplus宏,所以就不会使用extern "C" {...},所有代码都会按照C语言的规则进行编译。

在.h头文件中一般会有以下内容:

  1. 包含另外一些头文件
  2. 进行typedef结构体类型的定义
  3. 进行enum枚举体类型的定义
  4. 宏定义#define
  5. 函数声明(供其他.c文件调用)
  6. extern一些全局变量(供其他.c文件调用)

规范二:
在c文件中只放对应的h头文件,其他需要的头文件都包含在自己的头文件中。

规范三:
c文件中定义的全局变量如果需要让别的文件引用,就将该变量以extern的方式放在对应头文件中。别的文件如果需要使用这个全局变量,就包含该头文件即可。

规范四:
函数前面加上static,说明该函数只在该文件中使用,即为私有函数。在当前c文件的最前面声明该static函数即可。(供当前c文件调用)

规范五:
对于函数来说,默认为extern。加不加extern是等价的。除非使用static关键字,否则一般函数声明都默认为extern。

规范六:
使用#define的方式定义函数很常见。
对于宏定义,保险的做法是不仅应在参数两侧加括号,也应在整个字符串外加括号。

/**
  * @brief Clear ADC error code (set it to no error code "HAL_ADC_ERROR_NONE").
  * @param __HANDLE__ ADC handle
  * @retval None
  */
#define ADC_CLEAR_ERRORCODE(__HANDLE__) ((__HANDLE__)->ErrorCode = HAL_ADC_ERROR_NONE)

规范七:
使用枚举类型一般是定义一些状态值。作为函数的返回类型。

规范八:
如果函数需要传入结构体,则一般是传入结构体指针,这样传参更加快速。

规范九:
变量的命名:驼峰命名法

规范十:
弱函数定义

__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);

  /* NOTE: This function should not be modified, when the callback is needed,
            the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */ 
}

__WEAK也是一个宏,被定义成了如下:

#ifndef   __WEAK
  #define __WEAK                                 __attribute__((weak))
#endif

用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak声明的函数,并且编译器不会报错。所以我们可以在别的地方定义一个相同名字的函数,而不必也尽量不要修改之前的函数。