回调函数的基本概念

回调函数是一种通过函数指针实现的编程机制,允许将函数作为参数传递或在运行时动态指定逻辑。本质上,它是一种“函数调用函数”的模式,常用于解耦底层驱动与上层应用逻辑。

实现中断回调函数的步骤

定义函数指针类型
使用 typedef 声明一个无参数、无返回值的函数指针类型:

typedef void (*call_back_t)(void);

 

声明全局函数指针变量
定义一个全局变量存储回调函数地址:

call_back_t funCallBackPtr;

 

在中断服务函数中调用回调
在定时器中断服务函数中通过指针间接调用注册的回调函数:

void TIM_IRQHandler(void) {
    if (funCallBackPtr != NULL) {
        funCallBackPtr(); // 触发回调
    }
}

 

实现具体功能函数
编写实际业务逻辑的函数(如打印日志):

void logPrint(void) {
    printf("定时器中断触发,当前时间:%d\n", getSystemTime());
}

 

注册回调函数
将业务函数地址赋值给函数指针:

funCallBackPtr = logPrint;

 

回调函数的核心价值

解耦与扩展性

  • 底层驱动无需修改即可适配不同业务逻辑。
  • 业务代码独立于硬件层,便于维护和复用。

典型应用场景

  1. 外设驱动(如UART接收完成回调):
typedef void (*UART_RxCpltCallback)(uint8_t *data, uint16_t len);
UART_RxCpltCallback uartRxCb;

void USART_IRQHandler(void) {
    if (/*接收完成*/) {
        uartRxCb(rxBuffer, rxLen); // 触发数据回调
    }
}

 

  1. RTOS任务通知
    通过回调处理定时器超时或消息队列事件,避免任务与内核强耦合。

  2. 传感器数据上报
    传感器驱动采集数据后,通过回调将结果传递给应用层。

实际工程建议

参数化回调设计
为增强灵活性,可定义带参数的函数指针类型:

typedef void (*event_callback_t)(void *context, uint32_t event_id);

 

空指针检查
调用回调前需验证指针有效性,防止未注册时触发异常:

if (callback != NULL) {
    callback(arg1, arg2);
}

 

多回调管理
复杂场景可使用回调数组或链表支持多个监听器:

struct CallbackNode {
    event_callback_t func;
    void *context;
    struct CallbackNode *next;
};

 

通过上述方法,回调函数能显著提升嵌入式代码的模块化程度和可维护性。

 

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐