开发编码规范笔记
前言
(1)该博客仅用于个人笔记
格式转换
(1)查看是
LF行尾还是CRLF行尾。
# 单个文件,\n 表示 LF 行尾。\r\n 表示 CRLF 行尾。
hexdump -c <yourfile>
# 单个文件,'$' 表示 LF 行尾。'^M$' 表示 CRLF 行尾。
cat -e <yourfile>
(2)将文件转换为
LF格式。
# 单个文件
dos2unix <yourfile>
# 批量操作
find <path> -type f -exec dos2unix {} \;
(3)将文件转换为
CRLF格式。
# 单个文件
unix2dos <yourfile>
# 批量操作
find <path> -type f -exec unix2dos {} \;
C代码规范
断言
适用场景
(1)
assert()只能用于检测由于严重的内部逻辑错误或损坏而导致程序无法继续运行的不可恢复的错误。对于可恢复的错误,包括由于无效的外部输入而可能出现的错对于误,应返回错误值。
(2)对于返回值为esp_err_t类型的函数,应该使用ESP_ERROR_CHECK()而不是assert()。
断言设置使能
(1)对于断言的设置,可以进入
menuconfig搜索CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL进行配置:
- Enabled : 启动断言功能。当断言失败时,会打印出断言的内容和行号。适用于开发阶段,因为它可以帮助开发者快速定位和修复代码中的错误。
- Silent : 启动静默。断言失败时,不会打印出具体的断言信息和行号,而是直接中止程序。开发者需要通过中止地址来查找断言失败的位置。适用于在某些情况下需要节省代码大小的场景,同时仍然希望保留某种程度的断言检查。
- Disabled : 禁用断言。禁用断言后,任何断言检查都不会执行,从而提高程序的性能。

“变量设置但未使用”警告
(1)如果断言被失能,那么下面的
res可能会出现“变量设置但未使用”警告。
int res = do_something();
assert(res == 0);
(2)为了避免这样的问题,我们可以让所有的返回值用同一个变量定义,然后加上关键字即可。
int res __attribute__((unused));res = do_something();
assert(res == 0);res = do_something_else();
assert(res != 0);
变量
前缀
(1)静态全局变量用
g_前缀,静态局部变量用s_前缀。作用域仅限于当前文件的变量必须声明为静态变量static。
static uint8_t g_num; // 静态全局变量用 g_ 前缀
int main()
{static uint8_t s_num; // 静态局部变量用 s_ 前缀while (1);
}
使用
(2)变量注意重入问题。 尽量在一个固定函数中操作静态全局变量。使用
get_set_等接口进行变量操作。
static SemaphoreHandle_t g_mutexhandle = NULL; // 变量定义要赋初值,全局静态变量以 g_ 前缀
static uint8_t g_num = 0; // 变量定义要赋初值,全局静态变量以 g_ 前缀static void set_num(uint8_t value) // 使用 set_ 前缀接口操作变量
{// 获得信号量xSemaphoreTake(g_mutexhandle, portMAX_DELAY);g_num = value;// 释放信号量pthread_mutex_unlock(g_mutexhandle);
}static int get_num() // 使用 get_ 前缀接口操作变量
{uint8_t value;// 获得信号量xSemaphoreTake(g_mutexhandle, portMAX_DELAY);value = g_num;// 释放信号量pthread_mutex_unlock(g_mutexhandle);return value;
}int main()
{static uint8_t s_count; // 静态局部变量用 s_ 前缀// 创造互斥量g_mutexhandle = xSemaphoreCreateMutex();while(1){set_num(10);s_count = get_num(); // 静态全局变量用 g_ 前缀vTaskDelay(pdMS_TO_TICKS(1000));}vSemaphoreDelete(g_mutexhandle);g_mutexhandle = NULL; // 句柄类型变量,在对象销毁后,应重新赋值为 NULL
}
变量名
(1)变量应尽量使用有意义的词语,或者已经达成共识的符号或变量缩写

函数
(1)如果一个函数存在重入和线程安全问题,需在注释中说明。
/*** @brief 打印函数,该函数存在线程安全问题* * @param __restrict 字符串* @param ... 可变参数* @return int */
int printf (const char *__restrict, ...);
(2)函数名统一使用小写,同一组件保持同一前缀。

头文件
固定格式
(1)头文件固定如下格式。
#ifndef FILE_NAME_H /* 名字要与 .c 文件对应 */
#define FILE_NAME_H#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus *//********************************************* 头文件内容写里面********************************************/#ifdef __cplusplus
}
#endif /* __cplusplus */#endif /* FILE_NAME_H */
类型定义
(1)类型都需要通过
typedef定义并且命名
typedef enum{MODULE_FOO_ONE,MODULE_FOO_TWO,MODULE_FOO_THREE
} module_foo_t; /* typedef 之后名字后缀为 _t */typedef struct {esp_chip_model_t model; uint32_t features; uint16_t revision; uint8_t cores;
} esp_chip_info_t; /* typedef 之后名字后缀为 _t */
格式化代码
(1)如果重头写一个文件,可以使用
astyle工具。
# 格式化代码
astyle example.c
# 使用乐鑫官方脚本
${esp-idf}/tools/format.sh <yourfile>
最终代码演示
C代码
/********************************************************************************** 版权声明*********************************************************************************/
/** SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD** SPDX-License-Identifier: Apache-2.0*//********************************************************************************** 头文件规范*********************************************************************************/
// #include < C 标准库头文件 >
// #include < POSIX 头文件及其常见扩展 >
// #include " IDF 头文件 "
// #include " 组件头文件,例如 FreeRTOS "
// #include " 私有头文件 "#define uint8_t unsigned char
#define NULL 0
#define portMAX_DELAY -1/********************************************************************************** 变量定义规范*********************************************************************************/
static uint8_t g_num = 5, g_x = 0, g_y = 0; /* ","仅后面有空格,静态全局变量用 g_ 前缀 */
static uint8_t *g_z = NULL;
static SemaphoreHandle_t g_mutexhandle = NULL; // 互斥量/********************************************************************************** 代码规范*********************************************************************************/
static void circulate_function()
{/* 函数定义的括号应该单独一行 */if (g_num) { /* 循环关键字后面加一个空格,函数内左括号与条件放在同一行 */printf("hello");}else if (g_x) {printf("world");}for (; g_x < g_num; g_x++) { /* 循环关键字后面加一个空格,函数内左括号与循环放在同一行 */printf("esp");}while (g_x){ /* 循环关键字后面加一个空格,函数内左括号与循环放在同一行 */printf("esp32");}switch (g_num) { /* 循环关键字后面加一个空格,函数内左括号与循环放在同一行 */ case 0:break;default:break;}
}/* 尽量在一个固定函数中操作静态全局变量 */
static void set_num(uint8_t value) // 使用 set_ 前缀接口操作变量
{// 获得信号量xSemaphoreTake(g_mutexhandle, portMAX_DELAY);g_num = value;// 释放信号量pthread_mutex_unlock(g_mutexhandle);
}static int get_num() // 使用 get_ 前缀接口操作变量
{uint8_t value;// 获得信号量xSemaphoreTake(g_mutexhandle, portMAX_DELAY);value = g_num;// 释放信号量pthread_mutex_unlock(g_mutexhandle);return value;
}int main() /* 函数之间放置一个空行 */
{/* Tab 键为4个空格,而不是制表符进行缩进 *//* 如果不需要这行代码,直接删除,否则就解释禁用原因。 */// printf("hello world");static uint8_t s_count; // 静态局部变量用 s_ 前缀// 创造互斥量g_mutexhandle = xSemaphoreCreateMutex();while(1){set_num(10);s_count = get_num(); // 因为该变量不存在重入问题,因此不需要进行保护vTaskDelay(pdMS_TO_TICKS(1000));}vSemaphoreDelete(g_mutexhandle);g_mutexhandle = NULL; // 句柄类型变量,在对象销毁后,应重新赋值为 NULL// 获得信号量xSemaphoreTake(g_mutexhandle, portMAX_DELAY);/* 一元运算符不需要空格 */g_x = g_num++; g_y = g_num--; *g_z = &g_num; g_x = !g_num; g_x = ~g_x;g_y = *g_z;g_x = (uint8_t)g_x;/* 二元运算符需要空格 */g_num = g_x + g_y;g_num = g_x - g_y;g_num = g_x * g_y; /* 这个可以删除空格 */g_num = g_x*g_y; g_num = g_x / g_y; /* 这个可以删除空格 */g_num = g_x/g_y;g_num = g_x % g_y;g_num = (g_x == g_y);g_num = (g_x != g_y); g_num = (g_x > g_y); g_num = (g_x < g_y); g_num = (g_x >= g_y); g_num = (g_x <= g_y); g_num = (g_x && g_y); g_num = (g_x || g_y); g_num = g_x & g_y; g_num = g_x | g_y; g_num = g_x ^ g_y; g_num = g_x << 1; g_num = g_x >> 1; g_x += 3; g_x -= 2; g_x *= 2; g_x /= 4; g_x %= 2; g_y &= 3; g_y |= 2; g_y ^= 3; g_y <<= 1; g_y >>= 1; // 释放信号量pthread_mutex_unlock(g_mutexhandle);
}
头文件
#ifndef FILE_NAME_H /* 名字要与 .c 文件对应 */
#define FILE_NAME_H#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus *//* 枚举要通过 typedef 定义并且命名 */
typedef enum {MODULE_FOO_ONE,MODULE_FOO_TWO,MODULE_FOO_THREE
} module_foo_t; /* typedef 之后名字后缀为 _t *//*** @brief 该函数存在线程安全问题* * @param __restrict * @param ... * @return int */
int printf (const char *__restrict, ...);#ifdef __cplusplus
}
#endif /* __cplusplus */#endif /* FILE_NAME_H */
参考
(1)Espressif IoT Development Framework Style Guide
相关文章:
开发编码规范笔记
前言 (1)该博客仅用于个人笔记 格式转换 (1)查看是 LF 行尾还是CRLF 行尾。 # 单个文件,\n 表示 LF 行尾。\r\n 表示 CRLF 行尾。 hexdump -c <yourfile> # 单个文件,$ 表示 LF 行尾。^M$ 表示 CRLF …...
spring boot easyexcel
1.pom <!-- easyexcel 依赖 --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version></dependency><dependency><groupId>org.projectlombok</group…...
Docker 部署 ShardingSphere-Proxy 数据库中间件
文章目录 Github官网文档ShardingSphere-Proxymysql-connector-java 驱动下载conf 配置global.yamldatabase-sharding.yamldatabase-readwrite-splitting.yamldockerdocker-compose.yml Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为…...
Qt常用快捷键
Qt中的常用快捷键 F1查看帮助F2快速到变量声明 从cpp→hShift F2 函数的声明和定义之间快速切换 ;选中函数名 ,从h→cppF4在 cpp 和 h 文件切换 Shift F4在cpp/h文件与 界面文件中切换Ctrl /注释当前行 或者选中的区域Ctrl I自动缩进当前…...
关于RiboSeq分析流程的总结
最近关注了一下RiboSeq的分析方法,方法挺多的,但是无论哪种软件,都会存在或多或少的问题,一点问题不存在的软件不存在,问题的原因出在,1.有的脚本是用python2编写的,目前python2已经不能用了 2.…...
NLP任务:情感分析、看图说话
我可不向其他博主那样拖泥带水,我有代码就直接贴在文章里,或者放到gitee供你们参考下载,虽然写的不咋滴,废话少说,上代码。 gitee码云地址: 卢东艺/pytorch_cv_nlp - 码云 - 开源中国 (gitee.com)https:/…...
Linux桌面溯源
X窗口系统(X Window System) Linux起源于X窗口系统(X Window System),亦即常说的X11,因其版本止于11之故。 X窗口系统(X Window System,也常称为X11或X)是一种以位图方式显示的软件窗口系统。…...
深入Linux:权限管理与常用命令详解
文章目录 ❤️Linux常用指令🩷zip/unzip指令🩷tar指令🩷bc指令🩷uname指令🩷shutdown指令 ❤️shell命令以及原理❤️什么是 Shell 命令❤️Linux权限管理的概念❤️Linux权限管理🩷文件访问者的分类&#…...
Mojo 编程语言:AI开发者的新宠儿
Mojo(Meta Object Oriented programming for Java Objects)是一种面向对象的编程语言,旨在简化和加速Java应用程序的开发过程。作为近年来新兴的编程语言,Mojo因其与Java的紧密集成以及AI开发领域的应用潜力而逐渐成为AI开发者的新…...
ARM/Linux嵌入式面经(十):极氪
开篇强调两个事情: pdf文件都在百度网盘群:911289806一定要把超链接里面的文章看了,那都是为了你们写的。老板!!!现在多学点,涨个2k工资,真的很值得。要不吃学习的苦,要不吃生活的苦。 1. 自我介绍 专开新篇,等我! 2. 项目介绍,提问 专开新篇,等我! 3. SPI通信和…...
【PVE】新增2.5G网卡作为主网卡暨iperf测速流程
【PVE】新增2.5G网卡作为主网卡暨iperf测速流程 新增网卡 新增网卡的首先当然需要关闭PVE母机,把新网卡插上,我用淘宝遥现金搞了个红包,花了26元买了块SSU的2.5G网卡。说实话这个价位连散热片都没有,确实挺丐的。稍后测下速度看…...
数学建模美赛入门
数学建模需要的学科知识 高等数学线性代数 有很多算法的掌握是需要高等数学和线代的相关知识 如:灰色预测模型需要微积分知识;神经网络需要用到导数知识;图论和层次分析法等都需要用到矩阵计算的相关知识等; 概率论与数理统计&am…...
两段序列帧动画播放,在ios机型上出现闪屏
使用场景:两段序列帧动画连接播放,先播放第一段播一次,再播放第二段,第二段循环播放,在ios机型上出现动画闪动,播放不正常。 错误的写法:把每一段序列帧动画单独写在了定义的动画里 .gacha-bg…...
【C++深度探索】全面解析多态性机制(二)
🔥 个人主页:大耳朵土土垚 🔥 所属专栏:C从入门至进阶 这里将会不定期更新有关C/C的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉 前言 我…...
MySQL配置数据库的连接命令
MySQL配置数据库连接命令 在MySQL中,配置数据库连接的命令涉及创建用户、授予权限、配置主从复制等多个方面。以下是常用的命令及其用途: 创建用户 创建一个新的数据库用户并为其设置密码: CREATE USER usernamehost IDENTIFIED BY passwo…...
[PaddlePaddle飞桨] PaddleSpeech-自动语音识别-小模型部署
PaddleSpeech的GitHub项目地址 环境要求: gcc > 4.8.5 paddlepaddle < 2.5.1 python > 3.8 OS support: Linux(recommend), Windows, Mac OSXpip下载指令: python -m pip install paddlepaddle-gpu2.5.1 -i https://pypi.tuna.tsinghua.edu.c…...
redis查询慢,你们是如何排查优化的?(总结篇)
1,先进行基准测试,查看redis是否存在查询过慢情况,根据自己的情况而定 2、检查网络连接是否出现延迟,数据丢包问题(可能性小 3、开启慢查询日志,通过日志可以清楚知道哪些命令比较耗时,同时避…...
Docker 容器出现 IP 冲突
Docker 容器出现 IP 冲突的情况可能由以下几个原因导致: 静态 IP 分配:如果你在 docker-compose.yml 文件中为多个容器手动设置了相同的静态 IP 地址,那么这些容器在启动时就会出现 IP 冲突。确保每个容器分配的静态 IP 地址是唯一的。桥接网…...
paddlepaddle2.6,paddleorc2.8,cuda12,cudnn,nccl,python10环境
1.安装英伟达显卡驱动 首先需要到NAVIDIA官网去查自己的电脑是不是支持GPU运算。 网址是:CUDA GPUs | NVIDIA Developer。打开后的界面大致如下,只要里边有对应的型号就可以用GPU运算,并且每一款设备都列出来相关的计算能力(Compu…...
【D3.js in Action 3 精译】1.3 D3 视角下的数据可视化最佳实践(上)
当前内容所在位置 第一部分 D3.js 基础知识 第一章 D3.js 简介 1.1 何为 D3.js?1.2 D3 生态系统——入门须知 1.2.1 HTML 与 DOM1.2.2 SVG - 可缩放矢量图形1.2.3 Canvas 与 WebGL1.2.4 CSS1.2.5 JavaScript1.2.6 Node 与 JavaScript 框架1.2.7 Observable 记事本 1…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
