MultiTimer源码分析

结合AI,对MultiTimer源码分析

c 复制代码
/**
 * @brief 全局定时器链表头指针
 *        指向链表中的第一个定时器,该定时器具有最早的截止时间
 */
static MultiTimer* timerList = NULL;

/**
 * @brief 平台特定的 ticks 函数指针
 *        用于获取当前系统时间 ticks
 */
static PlatformTicksFunction_t platformTicksFunction = NULL;

/**
 * @brief 安装平台特定的 ticks 函数
 *        在使用其他 MultiTimer 函数之前必须调用此函数
 *
 * @param ticksFunc 指向平台 ticks 函数的指针
 * @return int 成功返回 0,失败返回 -1
 */
int multiTimerInstall(PlatformTicksFunction_t ticksFunc) {
    // 检查 ticksFunc 是否有效
    if (ticksFunc == NULL) {
        return -1; // 如果 ticksFunc 为 NULL,返回错误
    }
    
    // 存储平台 ticks 函数指针
    platformTicksFunction = ticksFunc;
    return 0; // 返回成功
}

/**
 * @brief 从链表中移除指定的定时器
 *
 * @param timer 要移除的定时器指针
 * @note 这是一个静态辅助函数,不向用户暴露
 */
static void removeTimer(MultiTimer* timer) {
    // 使用二级指针简化链表操作
    MultiTimer** current = &timerList;
    
    // 遍历链表查找目标定时器
    while (*current) {
        if (*current == timer) {
            // 通过更新前一个节点的 next 指针来移除定时器
            *current = timer->next;
            break; // 移除后退出循环
        }
        // 移动到链表中的下一个节点
        current = &(*current)->next;
    }
}

/**
 * @brief 启动或重启一个定时器
 *        如果定时器已经在运行,它将使用新参数重新启动
 *
 * @param timer 要启动的定时器结构体指针
 * @param timing 定时器持续时间(以 ticks 为单位)
 * @param callback 定时器到期时执行的回调函数
 * @param userData 传递给回调函数的用户定义数据
 * @return int 成功返回 0,失败返回 -1
 */
int multiTimerStart(MultiTimer* timer, uint64_t timing, MultiTimerCallback_t callback, void* userData) {
    // 验证输入参数
    if (!timer || !callback || platformTicksFunction == NULL) {
        return -1; // 如果任何参数无效,返回错误
    }

    // 如果定时器已经在链表中,先移除它
    // 这允许重启一个现有的定时器
    removeTimer(timer);

    // 计算定时器的截止时间
    // deadline = 当前 ticks + 定时时长
    timer->deadline = platformTicksFunction() + timing;
    
    // 设置回调函数和用户数据
    timer->callback = callback;
    timer->userData = userData;

    // 将定时器插入到有序链表中
    // 链表按截止时间升序排序
    MultiTimer** current = &timerList;
    
    // 找到正确的插入位置
    while (*current && ((*current)->deadline < timer->deadline)) {
        current = &(*current)->next;
    }
    
    // 将定时器插入链表
    timer->next = *current;
    *current = timer;

    return 0; // 返回成功
}

/**
 * @brief 停止一个正在运行的定时器
 *        定时器将从链表中移除
 *
 * @param timer 要停止的定时器结构体指针
 * @return int 成功返回 0
 */
int multiTimerStop(MultiTimer* timer) {
    // 从链表中移除定时器
    removeTimer(timer);
    return 0; // 总是返回成功
}

/**
 * @brief 处理所有到期的定时器并执行它们的回调函数
 *        此函数应在主循环中定期调用
 *
 * @return int 到下一个定时器到期的时间(以 ticks 为单位),如果没有定时器则返回 0
 *         这可用于优化主循环延迟
 */
int multiTimerYield(void) {
    // 检查是否已安装平台 ticks 函数
    if (platformTicksFunction == NULL) {
        return -1; // 如果 platformTicksFunction 为 NULL,返回错误
    }
    
    // 获取当前系统 ticks
    uint64_t currentTicks = platformTicksFunction();
    
    // 处理所有到期的定时器
    // 链表是有序的,所以我们只需要从头部检查
    while (timerList && (currentTicks >= timerList->deadline)) 
    {
        // 从链表中移除到期的定时器
        MultiTimer* timer = timerList;
        timerList = timer->next;

        // 如果回调函数有效,则执行它
        if (timer->callback) {
            timer->callback(timer, timer->userData);
        }
    }
    
    // 计算并返回下一个定时器到期前的时间
    // 如果没有定时器,返回 0
    return timerList ? (int)(timerList->deadline - currentTicks) : 0;
}
相关推荐
blevoice2 小时前
JL杰理AC696N开发板常见问题FAQ-问题6:为什么提示“key 不匹配”?杰理的蓝牙芯片的key是什么?以及该如何添加key? 杰理key文件原理?
单片机·嵌入式硬件·物联网·jl杰理蓝牙音频芯片·ac696n·蓝牙音箱方案开发
三佛科技-187366133974 小时前
辉芒微FT62FC1x低成本小体积定时器触摸MCU芯片选型深度解析
单片机·嵌入式硬件
独小乐5 小时前
018.使用I2C总线EEPROM|千篇笔记实现嵌入式全栈/裸机篇
linux·笔记·单片机·嵌入式硬件·arm·信息与通信
C^h5 小时前
rtthread控制达妙4310电机
数据库·单片机·嵌入式硬件
三佛科技-187366133975 小时前
LP3717BSL 12V1A隔离型极简化自供电充电器适配器电源方案测试报告
单片机·嵌入式硬件
一路往蓝-Anbo6 小时前
第二章:STM32 bxCAN 控制器详解:从内存到总线的“中转站”
stm32·单片机·嵌入式硬件·软件工程
Dunkle.T7 小时前
DC-DC PCB设计要点说明——拓扑、走线、选型、铺铜详解
单片机·嵌入式硬件·pcb·dc-dc
charlie1145141917 小时前
嵌入式C++工程实践——第13篇:第一次重构 —— enum class取代宏,类型安全的开始
开发语言·c++·vscode·stm32·安全·重构·现代c++
三品吉他手会点灯9 小时前
STM32F103 学习笔记-21-串口通信(第4节)—串口发送和接收代码讲解(上)
笔记·stm32·单片机·嵌入式硬件·学习
weifengdq9 小时前
SJA1124 SPI转4路LIN STM32 测试笔记
stm32·spi·nxp·lin·sja1124·spi4lin