news 2026/5/7 17:57:24

11、C语言程序设计:_FUNCTION__ 宏在嵌入式开发中的应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
11、C语言程序设计:_FUNCTION__ 宏在嵌入式开发中的应用

1. 基本介绍


__FUNCTION__ 是C语言的一个特殊预定义标识符,它在编译时会被替换为当前函数的名字(字符串常量)。

__FUNCTION__ 的主要优势:
【1】自动获取函数名 - 无需手动输入,减少错误
【2】代码维护方便 - 函数重命名时自动更新
【3】调试效率高 - 快速定位问题来源
【4】日志信息丰富 - 提供完整的调用上下文

在嵌入式系统中的实际应用:
【1】 故障诊断 - 快速定位硬件故障位置
【2】性能优化 - 识别瓶颈函数
【3】状态跟踪 - 监控系统运行状态
【4】远程调试 - 通过日志分析现场问题
【5】代码审查 - 理解函数调用关系

2. 各种用法及示例

2.1 基本调试打印

include <stdio.h>

void calculate_sum(int a, int b) {
printf("函数 %s 被调用,参数:%d, %d\n", __FUNCTION__, a, b);
int result = a + b;
printf("函数 %s 计算完成,结果:%d\n", __FUNCTION__, result);
}

int main() {
calculate_sum(5, 3);
return 0;
}

输出:

函数 calculate_sum 被调用,参数:5, 3
函数 calculate_sum 计算完成,结果:8

2.2 错误处理和日志记录


include <stdio.h>
include <stdlib.h>

define LOG_ERROR(msg) \
fprintf(stderr, "错误[%s]: %s\n", __FUNCTION__, msg)

int divide(int a, int b) {
if (b == 0) {
LOG_ERROR("除数不能为零");
return 0;
}
return a / b;
}

int allocate_memory(int size) {
void ptr = malloc(size);
if (ptr == NULL) {
LOG_ERROR("内存分配失败");
return -1;
}
return 0;
}

int main() {
divide(10, 0);
allocate_memory(1000000000);
return 0;
}

输出:

错误[divide]: 除数不能为零
错误[allocate_memory]: 内存分配失败

2.3 性能分析和函数追踪


include <stdio.h>
include <time.h>

define TRACE_ENTER() \
printf(">>> 进入函数:%s\n", __FUNCTION__)

define TRACE_EXIT() \
printf("<<< 退出函数:%s\n", __FUNCTION__)

define TIME_FUNCTION(func_call) \
do { \
clock_t start = clock(); \
func_call; \
clock_t end = clock(); \
double duration = (double)(end - start) / CLOCKS_PER_SEC; \
printf("函数执行时间:%f 秒\n", duration); \
} while(0)

void process_data() {
TRACE_ENTER();
// 模拟耗时操作
for (int i = 0; i < 1000000; i++);
TRACE_EXIT();
}

void another_function() {
TRACE_ENTER();
printf("正在执行任务...\n");
TRACE_EXIT();
}

int main() {
TIME_FUNCTION(process_data());
TIME_FUNCTION(another_function());
return 0;
}

输出:

>>> 进入函数:process_data
<<< 退出函数:process_data
函数执行时间:0.005000 秒
>>> 进入函数:another_function
正在执行任务...
<<< 退出函数:another_function
函数执行时间:0.001000 秒

2.4 函数调用链追踪


include <stdio.h>

define MAX_CALL_DEPTH 10
int call_depth = 0;

define ENTER_FUNCTION() \
do { \
call_depth++; \
if (call_depth <= MAX_CALL_DEPTH) { \
for (int i = 0; i < call_depth; i++) printf(" "); \
printf("-> %s()\n", __FUNCTION__); \
} \
} while(0)

define EXIT_FUNCTION() \
do { \
if (call_depth <= MAX_CALL_DEPTH) { \
for (int i = 0; i < call_depth; i++) printf(" "); \
printf("<- %s()\n", __FUNCTION__); \
} \
call_depth--; \
} while(0)

void function_c() {
ENTER_FUNCTION();
printf(" 执行function_c的任务\n");
EXIT_FUNCTION();
}

void function_b() {
ENTER_FUNCTION();
printf(" 执行function_b的任务\n");
function_c();
EXIT_FUNCTION();
}

void function_a() {
ENTER_FUNCTION();
printf(" 执行function_a的任务\n");
function_b();
EXIT_FUNCTION();
}

int main() {
ENTER_FUNCTION();
function_a();
EXIT_FUNCTION();
return 0;
}

输出:

-> main()
-> function_a()
执行function_a的任务
-> function_b()
执行function_b的任务
-> function_c()
执行function_c的任务
<- function_c()
<- function_b()
<- function_a()
<- main()

2.5 条件编译和调试级别控制


include <stdio.h>

// 调试级别:0=关闭,1=基本,2=详细,3=全部
define DEBUG_LEVEL 2

if DEBUG_LEVEL >= 1
define DEBUG_INFO(msg, ...) \
printf("[INFO][%s] " msg "\n", __FUNCTION__, __VA_ARGS__)
else
define DEBUG_INFO(msg, ...)
endif

if DEBUG_LEVEL >= 2
define DEBUG_DETAIL(msg, ...) \
printf("[DETAIL][%s] " msg "\n", __FUNCTION__, __VA_ARGS__)
else
define DEBUG_DETAIL(msg, ...)
endif

if DEBUG_LEVEL >= 3
define DEBUG_VERBOSE(msg, ...) \
printf("[VERBOSE][%s] " msg "\n", __FUNCTION__, __VA_ARGS__)
else
define DEBUG_VERBOSE(msg, ...)
endif

void initialize_system() {
DEBUG_INFO("系统初始化开始");
DEBUG_DETAIL("分配内存...");
DEBUG_VERBOSE("内存地址: %p", malloc(100));
DEBUG_INFO("系统初始化完成");
}

void process_user_input(int input) {
DEBUG_INFO("处理用户输入: %d", input);
DEBUG_DETAIL("验证输入有效性...");
if (input < 0) {
DEBUG_INFO("输入无效");
}
}

int main() {
DEBUG_INFO("程序启动");
initialize_system();
process_user_input(42);
process_user_input(-5);
DEBUG_INFO("程序结束");
return 0;
}

输出(DEBUG_LEVEL=2时):

[INFO][main] 程序启动
[INFO][initialize_system] 系统初始化开始
[DETAIL][initialize_system] 分配内存...
[INFO][initialize_system] 系统初始化完成
[INFO][process_user_input] 处理用户输入: 42
[DETAIL][process_user_input] 验证输入有效性...
[INFO][process_user_input] 处理用户输入: -5
[DETAIL][process_user_input] 验证输入有效性...
[INFO][process_user_input] 输入无效
[INFO][main] 程序结束

2.6 状态机函数追踪


include <stdio.h>

typedef enum {
STATE_IDLE,
STATE_RUNNING,
STATE_PAUSED,
STATE_ERROR
} SystemState;

SystemState current_state = STATE_IDLE;

define STATE_TRANSITION(new_state) \
do { \
printf("状态转移 [%s]: %d -> %d\n", \
__FUNCTION__, current_state, new_state); \
current_state = new_state; \
} while(0)

void start_system() {
if (current_state == STATE_IDLE) {
STATE_TRANSITION(STATE_RUNNING);
printf("系统启动成功\n");
} else {
printf("当前状态无法启动系统\n");
}
}

void pause_system() {
if (current_state == STATE_RUNNING) {
STATE_TRANSITION(STATE_PAUSED);
printf("系统已暂停\n");
}
}

void resume_system() {
if (current_state == STATE_PAUSED) {
STATE_TRANSITION(STATE_RUNNING);
printf("系统恢复运行\n");
}
}

void error_occurred() {
STATE_TRANSITION(STATE_ERROR);
printf("发生错误,系统进入错误状态\n");
}

int main() {
start_system();
pause_system();
resume_system();
error_occurred();
return 0;
}

输出:

状态转移 [start_system]: 0 -> 1
系统启动成功
状态转移 [pause_system]: 1 -> 2
系统已暂停
状态转移 [resume_system]: 2 -> 1
系统恢复运行
状态转移 [error_occurred]: 1 -> 3
发生错误,系统进入错误状态

3. 嵌入式系统综合示例

/
智能温控系统 - 嵌入式综合示例
功能:控制加热器、风扇、读取温度传感器、记录日志
/

include <stdio.h>
include <stdint.h>
include <string.h>

// ==================== 模拟硬件接口 ====================
typedef struct {
uint8_t heater_power; // 加热器功率 0-100%
uint8_t fan_speed; // 风扇速度 0-100%
float current_temp; // 当前温度 °C
float target_temp; // 目标温度 °C
} SystemController;

// 模拟硬件寄存器
SystemController hw_ctrl = {0};

// ==================== 日志系统 ====================
// 日志级别
typedef enum {
LOG_LEVEL_ERROR = 1,
LOG_LEVEL_WARNING = 2,
LOG_LEVEL_INFO = 3,
LOG_LEVEL_DEBUG = 4
} LogLevel;

// 当前日志级别(可通过配置修改)
LogLevel current_log_level = LOG_LEVEL_INFO;

// 日志记录宏
define LOG(level, format, ...) \
do { \
if ((level) <= current_log_level) { \
const char level_str; \
switch(level) { \
case LOG_LEVEL_ERROR: level_str = "ERROR"; break; \
case LOG_LEVEL_WARNING: level_str = "WARNING"; break; \
case LOG_LEVEL_INFO: level_str = "INFO"; break; \
case LOG_LEVEL_DEBUG: level_str = "DEBUG"; break; \
default: level_str = "UNKNOWN"; break; \
} \
char log_buffer[128]; \
snprintf(log_buffer, sizeof(log_buffer), \
"[%s][%s] " format "\n", \
level_str, __FUNCTION__, __VA_ARGS__); \
/ 实际嵌入式系统中可能输出到串口或SD卡 / \
printf("%s", log_buffer); \
} \
} while(0)

// ==================== 错误处理系统 ====================
define CHECK_TEMP_RANGE(temp) \
do { \
if ((temp) < -40.0 || (temp) > 150.0) { \
LOG(LOG_LEVEL_ERROR, "温度超出范围: %.2f°C", temp); \
emergency_shutdown(); \
return -1; \
} \
} while(0)

define CHECK_HARDWARE_STATUS() \
do { \
if (!is_hardware_ready()) { \
LOG(LOG_LEVEL_ERROR, "硬件未就绪"); \
return -2; \
} \
} while(0)

// ==================== 性能监控 ====================
ifdef PERFORMANCE_MONITORING
define PERF_START() \
uint32_t perf_start_time = get_system_tick()

define PERF_END(operation_name) \
do { \
uint32_t perf_end_time = get_system_tick(); \
uint32_t perf_duration = perf_end_time - perf_start_time; \
LOG(LOG_LEVEL_DEBUG, "%s 耗时: %u ms", \
operation_name, perf_duration); \
} while(0)
else
define PERF_START()
define PERF_END(operation_name)
endif

// ==================== 硬件控制函数 ====================
int set_heater_power(uint8_t power) {
LOG(LOG_LEVEL_INFO, "设置加热器功率: %d%%", power);

CHECK_HARDWARE_STATUS();

if (power > 100) {
LOG(LOG_LEVEL_WARNING, "功率值 %d 超过上限,限制为 100%%", power);
power = 100;
}

hw_ctrl.heater_power = power;

// 模拟硬件设置
LOG(LOG_LEVEL_DEBUG, "加热器功率已更新");
return 0;
}

int set_fan_speed(uint8_t speed) {
LOG(LOG_LEVEL_INFO, "设置风扇速度: %d%%", speed);

CHECK_HARDWARE_STATUS();

if (speed > 100) {
LOG(LOG_LEVEL_WARNING, "速度值 %d 超过上限,限制为 100%%", speed);
speed = 100;
}

hw_ctrl.fan_speed = speed;

LOG(LOG_LEVEL_DEBUG, "风扇速度已更新");
return 0;
}

float read_temperature_sensor(int sensor_id) {
LOG(LOG_LEVEL_DEBUG, "读取传感器 %d", sensor_id);

PERF_START();

// 模拟传感器读取(实际可能是I2C/SPI通信)
float temp = 25.0 + (sensor_id 0.5); // 模拟温度

CHECK_TEMP_RANGE(temp);

PERF_END("读取温度传感器");

LOG(LOG_LEVEL_INFO, "传感器 %d 温度: %.2f°C", sensor_id, temp);
return temp;
}

// ==================== 核心控制逻辑 ====================
void temperature_control_loop(void) {
LOG(LOG_LEVEL_INFO, "温度控制循环开始");

// 读取所有传感器
float temp1 = read_temperature_sensor(1);
float temp2 = read_temperature_sensor(2);

// 计算平均温度
float avg_temp = (temp1 + temp2) / 2.0;
hw_ctrl.current_temp = avg_temp;

LOG(LOG_LEVEL_INFO, "平均温度: %.2f°C, 目标温度: %.2f°C",
avg_temp, hw_ctrl.target_temp);

// PID控制逻辑(简化版)
float error = hw_ctrl.target_temp - avg_temp;

if (error > 2.0) {
// 需要加热
uint8_t power = (uint8_t)(error 20.0);
if (power > 100) power = 100;
set_heater_power(power);
set_fan_speed(30); // 低速风扇帮助热交换
}
else if (error < -2.0) {
// 需要降温
set_heater_power(0);
uint8_t speed = (uint8_t)(-error 30.0);
if (speed > 100) speed = 100;
set_fan_speed(speed);
}
else {
// 维持温度
set_heater_power(20);
set_fan_speed(20);
LOG(LOG_LEVEL_INFO, "温度稳定在目标范围内");
}

LOG(LOG_LEVEL_INFO, "温度控制循环结束");
}

// ==================== 系统管理函数 ====================
int initialize_system(void) {
LOG(LOG_LEVEL_INFO, "系统初始化开始");

// 初始化硬件
if (initialize_hardware() != 0) {
LOG(LOG_LEVEL_ERROR, "硬件初始化失败");
return -1;
}

// 设置默认参数
hw_ctrl.target_temp = 25.0;
hw_ctrl.heater_power = 0;
hw_ctrl.fan_speed = 0;

LOG(LOG_LEVEL_INFO, "目标温度设置为: %.2f°C", hw_ctrl.target_temp);
LOG(LOG_LEVEL_INFO, "系统初始化完成");
return 0;
}

void set_target_temperature(float temp) {
LOG(LOG_LEVEL_INFO, "设置目标温度: %.2f°C", temp);

CHECK_TEMP_RANGE(temp);

hw_ctrl.target_temp = temp;

LOG(LOG_LEVEL_INFO, "目标温度已更新");
}

void emergency_shutdown(void) {
LOG(LOG_LEVEL_ERROR, "紧急关闭系统");

// 关闭所有输出
hw_ctrl.heater_power = 0;
hw_ctrl.fan_speed = 0;

LOG(LOG_LEVEL_INFO, "系统已安全关闭");
}

// ==================== 辅助函数(模拟) ====================
int initialize_hardware(void) {
LOG(LOG_LEVEL_DEBUG, "初始化硬件");
// 模拟硬件初始化
return 0;
}

int is_hardware_ready(void) {
// 模拟硬件状态检查
return 1;
}

uint32_t get_system_tick(void) {
// 模拟系统时钟
static uint32_t tick = 0;
return tick++;
}

// ==================== 主函数 ====================
int main(void) {
LOG(LOG_LEVEL_INFO, "智能温控系统启动");

// 初始化系统
if (initialize_system() != 0) {
LOG(LOG_LEVEL_ERROR, "系统启动失败");
return 1;
}

// 设置目标温度
set_target_temperature(30.0);

// 运行几个控制循环
for (int i = 0; i < 3; i++) {
LOG(LOG_LEVEL_INFO, "========== 控制循环 %d ==========", i + 1);
temperature_control_loop();
}

// 改变目标温度
set_target_temperature(20.0);

// 再运行几个控制循环
for (int i = 0; i < 2; i++) {
LOG(LOG_LEVEL_INFO, "========== 控制循环 %d ==========", i + 4);
temperature_control_loop();
}

// 测试错误情况
LOG(LOG_LEVEL_INFO, "========== 测试错误处理 ==========");
set_target_temperature(200.0); // 超出范围

LOG(LOG_LEVEL_INFO, "系统运行完成");
return 0;
}


示例输出:

[INFO][main] 智能温控系统启动
[INFO][initialize_system] 系统初始化开始
[DEBUG][initialize_hardware] 初始化硬件
[INFO][initialize_system] 目标温度设置为: 25.0°C
[INFO][initialize_system] 系统初始化完成
[INFO][set_target_temperature] 设置目标温度: 30.0°C
[INFO][set_target_temperature] 目标温度已更新
[INFO][main] ========== 控制循环 1 ==========
[INFO][temperature_control_loop] 温度控制循环开始
[DEBUG][read_temperature_sensor] 读取传感器 1
[INFO][read_temperature_sensor] 传感器 1 温度: 25.5°C
[DEBUG][read_temperature_sensor] 读取传感器 2
[INFO][read_temperature_sensor] 传感器 2 温度: 26.0°C
[INFO][temperature_control_loop] 平均温度: 25.75°C, 目标温度: 30.0°C
[INFO][set_heater_power] 设置加热器功率: 85%
[DEBUG][set_heater_power] 加热器功率已更新
[INFO][set_fan_speed] 设置风扇速度: 30%
[DEBUG][set_fan_speed] 风扇速度已更新
[INFO][temperature_control_loop] 温度控制循环结束
...
[ERROR][set_target_temperature] 温度超出范围: 200.0°C
[ERROR][emergency_shutdown] 紧急关闭系统
[INFO][emergency_shutdown] 系统已安全关闭

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/6 13:36:06

社会网络仿真软件:NetLogo_(9).可视化技术与应用

可视化技术与应用 在社会网络仿真中&#xff0c;可视化技术是至关重要的。它不仅能够帮助研究者更直观地理解仿真模型的运行过程和结果&#xff0c;还能使非专业用户更容易地解读和分析数据。NetLogo 提供了丰富的可视化工具和功能&#xff0c;使得开发者可以轻松地创建动态的…

作者头像 李华
网站建设 2026/5/6 13:36:06

Riemann-Geometry PINN机械退化趋势预测(Pytorch)

算法特点 将黎曼流形理论转化为可训练的神经网络正则化项 解决高维特征空间几何结构保持难题&#xff0c;防止模型塌陷 通过余弦相似度矩阵保持退化轨迹的局部平滑性 相似退化状态的特征在黎曼流形上保持接近 黎曼正则化&#xff1a;保持特征空间的几何结构 物理约束&…

作者头像 李华
网站建设 2026/5/6 13:36:01

跨国制造企业全球供应链协同平台(SRM+WMS+TMS)数字化转型方案深度解析:打造端到端可视化的“数字供应链“(WORD)

导语&#xff1a;当地缘政治重构全球分工&#xff0c;当海运物流成为"黑天鹅"频发地&#xff0c;传统供应链的"成本优先"逻辑正在崩塌。本文深度拆解跨国制造企业全球供应链协同平台建设方案&#xff0c;从SRM供应商协同、WMS智能仓储到TMS全球物流追踪&am…

作者头像 李华
网站建设 2026/5/6 14:44:24

从0到1:AI应用架构师如何打造智能家居系统?

从0到1&#xff1a;AI应用架构师的智能家居系统设计全指南——从概念到落地的完整路径 摘要/引言&#xff1a;为什么我们需要重新设计智能家居系统&#xff1f; 凌晨1点&#xff0c;你被客厅的灯光吵醒——原来是宠物猫碰倒了茶几上的传感器&#xff0c;触发了“有人闯入”的…

作者头像 李华
网站建设 2026/5/1 9:08:32

Context7 MCP

在TRAE中使用Context7&#xff0c;相当于给你的AI助手配了一位随时能调阅全球最新技术文档的图书管理员。它的核心是解决一个根本问题&#xff1a;让AI的答案摆脱训练数据的时间限制&#xff0c;能“活在当下”。 Context7 是什么&#xff1a;为什么需要它&#xff1f; 你可以…

作者头像 李华
网站建设 2026/4/23 14:58:48

数据结构:(三)字符串——从暴力匹配到 KMP 的跨越

一、 串的存储结构&#xff1a;定长 vs 堆串是由零个或多个字符组成的有限序列。在 C 语言中&#xff0c;我们主要关注两种实现&#xff1a;定长顺序存储&#xff1a;使用静态数组 char str[MAXSIZE]。缺点是长度固定&#xff0c;容易发生截断。堆分配存储&#xff08;重点&…

作者头像 李华