4. HAL中的回调机制
任务目标
在HAL模块中实现异步回调机制:上层通过HAL接口注册回调函数,底层在独立线程中模拟事件发生,触发回调将事件数据传递回上层。本案例聚焦HAL层回调的完整链路,不涉及具体硬件。
核心实现
// hal_callback.h
#ifndef HAL_CALLBACK_H
#define HAL_CALLBACK_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
HAL_EVENT_DATA_READY = 1,
HAL_EVENT_ERROR
} hal_event_type_t;
typedef struct {
hal_event_type_t type;
uint32_t value;
} hal_event_t;
// 回调函数原型:上层实现,HAL层调用
typedef void (*hal_event_callback_t)(const hal_event_t *event, void *user_data);
// HAL接口
int hal_callback_init(void);
int hal_callback_register_callback(hal_event_callback_t cb, void *user_data);
int hal_callback_start(void);
int hal_callback_stop(void);
void hal_callback_deinit(void);
#ifdef __cplusplus
}
#endif
#endif // HAL_CALLBACK_H
// hal_callback.c
#include "hal_callback.h"
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
static pthread_t s_thread;
static volatile int s_running = 0;
static hal_event_callback_t s_cb = NULL;
static void *s_user_data = NULL;
static pthread_mutex_t s_lock = PTHREAD_MUTEX_INITIALIZER;
static void *event_loop(void *arg) {
(void)arg;
uint32_t counter = 0;
while (s_running) {
usleep(500000); // 模拟500ms事件周期
hal_event_t event;
memset(&event, 0, sizeof(event));
event.type = HAL_EVENT_DATA_READY;
event.value = ++counter;
pthread_mutex_lock(&s_lock);
hal_event_callback_t cb = s_cb;
void *user_data = s_user_data;
pthread_mutex_unlock(&s_lock);
if (cb) {
cb(&event, user_data);
}
}
return NULL;
}
int hal_callback_init(void) {
s_cb = NULL;
s_user_data = NULL;
s_running = 0;
return 0;
}
int hal_callback_register_callback(hal_event_callback_t cb, void *user_data) {
if (!cb) return -1;
pthread_mutex_lock(&s_lock);
s_cb = cb;
s_user_data = user_data;
pthread_mutex_unlock(&s_lock);
return 0;
}
int hal_callback_start(void) {
if (s_running) return 0;
s_running = 1;
if (pthread_create(&s_thread, NULL, event_loop, NULL) != 0) {
s_running = 0;
return -1;
}
return 0;
}
int hal_callback_stop(void) {
if (!s_running) return 0;
s_running = 0;
pthread_join(s_thread, NULL);
return 0;
}
void hal_callback_deinit(void) {
hal_callback_stop();
pthread_mutex_destroy(&s_lock);
}
// test_client.c(上层调用示例)
#include "hal_callback.h"
#include <stdio.h>
static void on_hal_event(const hal_event_t *event, void *user_data) {
int *count = (int *)user_data;
(*count)++;
printf("[callback] type=%d value=%u (total=%d)\n",
event->type, event->value, *count);
}
int main(void) {
int callback_count = 0;
hal_callback_init();
hal_callback_register_callback(on_hal_event, &callback_count);
hal_callback_start();
// 运行3秒后停止
sleep(3);
hal_callback_stop();
hal_callback_deinit();
printf("Total callbacks received: %d\n", callback_count);
return 0;
}
编译与运行
gcc -o hal_callback_test hal_callback.c test_client.c -lpthread
./hal_callback_test
验证方法
- 程序运行约3秒后自动退出,打印
Total callbacks received: N。 - 由于事件周期为500ms,预期N≈6(允许因调度略有偏差)。
- stdout中应出现约6行
[callback] type=1 value=1..6格式的输出,value递增且无重复。 - 若N为0,说明回调未触发,检查线程创建或回调注册是否成功。
关键说明
- 回调在HAL内部线程中执行,上层回调函数中不应执行耗时操作或直接调用HAL的stop/deinit,避免死锁。
- 注册回调使用互斥锁保护,防止注册与事件触发并发竞争。
- 本示例使用
usleep模拟底层事件,实际硬件场景中可在中断或事件循环中调用回调。