贸易公司如何做英文网站,零售户订烟电商网站,黄页推广网站下载,网络营销模式的优缺点分析前言 #xff08;1#xff09;该博客仅用于个人笔记 格式转换 #xff08;1#xff09;查看是 LF 行尾还是CRLF 行尾。 # 单个文件#xff0c;\n 表示 LF 行尾。\r\n 表示 CRLF 行尾。
hexdump -c yourfile
# 单个文件#xff0c;$ 表示 LF 行尾。^M$ 表示 CRLF …前言 1该博客仅用于个人笔记 格式转换 1查看是 LF 行尾还是CRLF 行尾。 # 单个文件\n 表示 LF 行尾。\r\n 表示 CRLF 行尾。
hexdump -c yourfile
# 单个文件$ 表示 LF 行尾。^M$ 表示 CRLF 行尾。
cat -e yourfile2将文件转换为LF格式。 # 单个文件
dos2unix yourfile
# 批量操作
find path -type f -exec dos2unix {} \;3将文件转换为CRLF格式。 # 单个文件
unix2dos yourfile
# 批量操作
find path -type f -exec unix2dos {} \;C代码规范
断言
适用场景 1assert() 只能用于检测由于严重的内部逻辑错误或损坏而导致程序无法继续运行的不可恢复的错误。对于可恢复的错误包括由于无效的外部输入而可能出现的错对于误应返回错误值。 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 */参考 1Espressif IoT Development Framework Style Guide