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;
}
相关推荐
小心亦新15 分钟前
STM32学习23--I2C-1
stm32·嵌入式硬件·学习
小羊先生car39 分钟前
F429-HAL-Can总线(回环及双机实验)(2026/8/15)
c语言·单片机·嵌入式硬件·软件构建
嵌入式阿蔡1 小时前
STM32时钟树详解:配错一个全乱套
c语言·stm32·单片机·嵌入式硬件
花花鱼3 小时前
TinyML Agent:MCU 上的微型智能体,AI 智能体下沉的底层实现
人工智能·单片机·嵌入式硬件
lsz1525904 小时前
嵌入式开发第一步:STM32 F1系列功能介绍与快速上手
stm32·单片机·嵌入式硬件·嵌入式开发·可扩展模块
橘色的喵4 小时前
SD 卡在上电后的完整加载流程:从中断信号到文件系统挂载
单片机·嵌入式硬件·嵌入式·rt-thread·rtos
happygrilclh17 小时前
STM32,串口单字节中断接受,每次上电后,会收到一个0x00的解决办法。
单片机·嵌入式硬件
智闲电子设计18 小时前
STM32 独立看门狗 IWDG 实战:系统跑飞,它来兜底复位
stm32·单片机·嵌入式硬件
zcmodeltech19 小时前
智能制造教学实训沙盘模型多系统协同控制系统设计:基于STM32与Modbus RTU的工业机器人-智慧工厂-数字孪生全场景联动方案
数据库·stm32·嵌入式硬件·机器人·制造·多分类
嵌入式阿蔡21 小时前
HAL库 vs LL库 vs 寄存器:到底用哪个?
c语言·stm32·单片机·嵌入式硬件·嵌入式实时数据库