文章目录

  • 1 软定时器的启动与停止

1 软定时器的启动与停止

软定时器单独开一个定时器任务来处理,硬定时器直接放在Systick中断中进行处理。

定时器启动:

定时器停止:

具体的实现代码如下:

/*************************************** Copyright (c)******************************************************
** File name            :   tTimer.c
** Latest modified Date :   2016-06-01
** Latest Version       :   0.1
** Descriptions         :   tinyOS的软定时器实现
**
**--------------------------------------------------------------------------------------------------------
** Created by           :   01课堂 lishutong
** Created date         :   2016-06-01
** Version              :   1.0
** Descriptions         :   The original version
**
**--------------------------------------------------------------------------------------------------------
** Copyright            :   版权所有,禁止用于商业用途
** Author Blog          :   http://ilishutong.com
**********************************************************************************************************/
#include "tinyOS.h"
#include "tTimer.h"// "硬"定时器列表
static tList tTimerHardList;// "软"定时器列表
static tList tTimerSoftList;// 用于访问软定时器列表的信号量
static tSem tTimerProtectSem;// 用于软定时器任务与中断同步的计数信号量
static tSem tTimerTickSem;/**********************************************************************************************************
** Function name        :   tTimerInit
** Descriptions         :   初始化定时器
** parameters           :   timer 等待初始化的定时器
** parameters           :   delayTicks 定时器初始启动的延时ticks数。
** parameters           :   durationTicks 给周期性定时器用的周期tick数,一次性定时器无效
** parameters           :   timerFunc 定时器回调函数
** parameters           :   arg 传递给定时器回调函数的参数
** parameters           :   timerFunc 定时器回调函数
** parameters           :   config 定时器的初始配置
** Returned value       :   无
***********************************************************************************************************/
void tTimerInit (tTimer * timer, uint32_t delayTicks, uint32_t durationTicks,void (*timerFunc) (void * arg), void * arg, uint32_t config)
{tNodeInit(&timer->linkNode);timer->startDelayTicks = delayTicks;timer->durationTicks = durationTicks;timer->timerFunc = timerFunc;timer->arg = arg;timer->config = config;// 如果初始启动延时为0,则使用周期值if (delayTicks == 0){timer->delayTicks = durationTicks;}else{timer->delayTicks = timer->startDelayTicks;}timer->state = tTimerCreated;
}/**********************************************************************************************************
** Function name        :   tTimerStart
** Descriptions         :   启动定时器
** parameters           :   timer 等待启动的定时器
** Returned value       :   无
***********************************************************************************************************/
void tTimerStart (tTimer * timer)
{switch (timer->state){case tTimerCreated:case tTimerStopped:timer->delayTicks = timer->startDelayTicks ? timer->startDelayTicks : timer->durationTicks;timer->state = tTimerStarted;// 根据定时器类型加入相应的定时器列表if (timer->config & TIMER_CONFIG_TYPE_HARD){// 硬定时器,在时钟节拍中断中处理,所以使用critical来防护uint32_t status = tTaskEnterCritical();// 加入硬定时器列表tListAddLast(&tTimerHardList, &timer->linkNode);tTaskExitCritical(status);}else{// 软定时器,先获取信号量。以处理此时定时器任务此时同时在访问软定时器列表导致的冲突问题tSemWait(&tTimerProtectSem, 0);tListAddLast(&tTimerSoftList, &timer->linkNode);tSemNotify(&tTimerProtectSem);}break;default:break;}
}/**********************************************************************************************************
** Function name        :   tTimerStop
** Descriptions         :   终止定时器
** parameters           :   timer 等待启动的定时器
** Returned value       :   无
***********************************************************************************************************/
void tTimerStop (tTimer * timer)
{switch (timer->state){case tTimerStarted:case tTimerRunning:// 如果已经启动,判断定时器类型,然后从相应的延时列表中移除if (timer->config & TIMER_CONFIG_TYPE_HARD){// 硬定时器,在时钟节拍中断中处理,所以使用critical来防护uint32_t status = tTaskEnterCritical();// 从硬定时器列表中移除tListRemove(&tTimerHardList, &timer->linkNode);tTaskExitCritical(status);}else{// 软定时器,先获取信号量。以处理此时定时器任务此时同时在访问软定时器列表导致的冲突问题tSemWait(&tTimerProtectSem, 0);tListRemove(&tTimerSoftList, &timer->linkNode);tSemNotify(&tTimerProtectSem);}timer->state = tTimerStopped;break;default:break;}
}/**********************************************************************************************************
** Function name        :   tTimerCallFuncList
** Descriptions         :   遍历指定的定时器列表,调用各个定时器处理函数
** parameters           :   无
** Returned value       :   无
***********************************************************************************************************/
static void tTimerCallFuncList (tList * timerList)
{tNode * node;// 检查所有任务的delayTicks数,如果不0的话,减1。for (node = timerList->headNode.nextNode; node != &(timerList->headNode); node = node->nextNode){tTimer * timer = tNodeParent(node, tTimer, linkNode);// 如果延时已到,则调用定时器处理函数if ((timer->delayTicks == 0) || (--timer->delayTicks == 0)){// 切换为正在运行状态timer->state = tTimerRunning;// 调用定时器处理函数timer->timerFunc(timer->arg);// 切换为已经启动状态timer->state = tTimerStarted;if (timer->durationTicks > 0){// 如果是周期性的,则重复延时计数值timer->delayTicks = timer->durationTicks;}else{// 否则,是一次性计数器,中止定时器tListRemove(timerList, &timer->linkNode);timer->state = tTimerStopped;}}}
}/**********************************************************************************************************
** Function name        :   tTimerSoftTask
** Descriptions         :   处理软定时器列表的任务
** parameters           :   无
** Returned value       :   无
***********************************************************************************************************/
static tTask tTimeTask;
static tTaskStack tTimerTaskStack[TINYOS_TIMERTASK_STACK_SIZE];static void tTimerSoftTask (void * param)
{for (;;){// 等待系统节拍发送的中断事件信号tSemWait(&tTimerTickSem, 0);// 获取软定时器列表的访问权限tSemWait(&tTimerProtectSem, 0);// 处理软定时器列表tTimerCallFuncList(&tTimerSoftList);// 释放定时器列表访问权限tSemNotify(&tTimerProtectSem);}
}/**********************************************************************************************************
** Function name        :   tTimerModuleTickNotify
** Descriptions         :   通知定时模块,系统节拍tick增加
** parameters           :   无
** Returned value       :   无
***********************************************************************************************************/
void tTimerModuleTickNotify (void)
{uint32_t status = tTaskEnterCritical();// 处理硬定时器列表tTimerCallFuncList(&tTimerHardList);tTaskExitCritical(status);// 通知软定时器节拍变化tSemNotify(&tTimerTickSem);
}/**********************************************************************************************************
** Function name        :   tTimerModuleInit
** Descriptions         :   定时器模块初始化
** parameters           :   无
** Returned value       :   无
***********************************************************************************************************/
void tTimerModuleInit (void)
{tListInit(&tTimerHardList);tListInit(&tTimerSoftList);tSemInit(&tTimerProtectSem, 1, 1);tSemInit(&tTimerTickSem, 0, 0);#if TINYOS_TIMERTASK_PRIO >= (TINYOS_PRO_COUNT - 1)#error "The proprity of timer task must be greater then (TINYOS_PRO_COUNT - 1)"
#endiftTaskInit(&tTimeTask, tTimerSoftTask, (void *)0,TINYOS_TIMERTASK_PRIO, &tTimerTaskStack[TINYOS_TIMERTASK_STACK_SIZE]);
}

tTimerModuleTickNotify 需要在中断函数中进行调用。


参考资料:

  1. 【李述铜】从0到1自己动手写嵌入式操作系统

软定时器的启动与停止相关推荐

  1. java定时器停止_java 定时器中任务的启动、停止、再启动

    package com.cvicse.ump.timer.service; import java.util.Date; import java.util.Timer; import com.cvic ...

  2. Js、jquery 定时器启动与停止效果实现

    项目背景: 大二上学期复习完jquery后的国庆作业 使用jquery百分百完成以下网址轮播图效果 完成效果需求: 一,轮播图每3秒自动切换下一个图片,同时图片对应的选项样式会改变为红色选中状态 二, ...

  3. Mac 系统部署Frp内网穿透服务 实现frpc shell启动脚本启动、停止

    Mac 系统部署Frp内网穿透服务 实现frpc shell启动脚本启动.停止 前言 最近疫情导致居家办公,而工作中需要用到公网地址便于调试,于是就在本机(Mac系统)配置了Frpc内网穿透. 本来想 ...

  4. 4、Proteus仿真STM32串口通信,发送数据控制LED流水灯的启动和停止

    一.实验说明 本次实验建立在第三个实验基础上,稍加修改,通过串口调试助手发送数据到Proteus来实现对流水灯的启动和停止,所以实验采用2个通信串口,实验原理非常简单,只要熟悉第三次实验的过程,就非常 ...

  5. Linux驱动-使用软定时器实现PWM输出

    Linux驱动-使用软定时器实现PWM输出 ​ 在没有pwm外设的情况下,可以使用定时器+GPIO的方法来实现pwm输出,实现pwm频率和占空比可控的功能.本文实现了一个Linux内核驱动,使用两个软 ...

  6. C# Winform 启动和停止进程

    启动和停止进程 一.启动进程 方法1: (1)       创建一个Process组件的实例,例如: Process myProcess = new Process(); (2)       设置其对 ...

  7. Linux Named 进程启动、停止脚本

    脚本名称 dnsnamed 脚本功能: 负责DNS服务器Named进程的启动.停止和状态信息采集等. 参数:start|stop|status 运行环境 OS:Linux Shell:Bash She ...

  8. [转]使用批处理设置、启动和停止服务

    使用批处理设置.启动和停止服务                                                              Pashine     当我们的电脑安装了数据 ...

  9. AIX上如何启动和停止系统服务

    AIX上如何启动和停止系统服务 ----------------------------- 在 AIX 上,服务也可以称为子系统(Subsystem),它是受控于系统资源控制器(System Reso ...

最新文章

  1. Linux 运维自动化之Cobbler实战案例
  2. Silverlight+WCF 新手实例 象棋 主界面-事件区-求和认输(三十二)
  3. vs2015 C#打包程序为exe
  4. dos模式下切换电脑用户
  5. Spring学习总结三
  6. 数据库服务器查询格式化显示,在数据库服务器端养成设置NLS_LANG和NLS_DATE_FORMAT环境变量的习惯...
  7. P4103-[HEOI2014]大工程【虚树,dp】
  8. 洛谷P2286 [HNOI2004]宠物收养场
  9. spark的流失计算模型_使用spark对sparkify的流失预测
  10. 基于android公交车线路查询论文文献,本科毕业论文---基于android的手机公交线路查询系统.doc...
  11. Kafka源码分析-序列3 -Producer -Java NIO(Reactor VS Peactor)
  12. java程序设计经典课堂讲课_Java程序设计与开发经典课堂
  13. 论文趣读:人工智能里程碑?回顾2015年登上Nature的DQN(全文翻译+批注)
  14. Vijos P1786 质因数分解【质因数分解】
  15. windows环境安装elasticsearch
  16. 【教程搬运】廖雪峰Git的使用教程(一)
  17. jquery日历插件 途牛_jQuery日历插件FullCalendar中文版
  18. 链表-快慢指针(C++)
  19. Python学习_基础_29_面向对象编程之多态、鸭子类型
  20. Debian 7.4 下mentohust开机自动认证

热门文章

  1. 2.5 数据不匹配时,偏差和方差的分析-深度学习第三课《结构化机器学习项目》-Stanford吴恩达教授
  2. STM32 电机教程 24 - ST MCLIB实战之无感变绝对式位置传感器
  3. 一起学nRF51xx 18 -  蓝牙协议栈烧录
  4. 类和对象—对象特性—深拷贝与浅拷贝
  5. 【移动通信】WIFI6 技术参数
  6. 译:Spring Data Repository 不区分大小写查询
  7. Jackson反序列化提示:Can not deserialize instance of Task out of START_ARRAY token
  8. exception ----- Functions
  9. 把9999的各个2进制位置上的1的 值打印出来? 如何实现? 1的数量 二机制位 x(x-1)
  10. 51Nod幼儿园霸王