分享

干货 | 小论定时器玩法(时间轮询法)

 知芯世界 2020-10-28

EEWORLD

电子资讯 犀利解读 

技术干货 每日更新

 

经常来说,对于一些不复杂的单片机应用,而且对于内存和存储要求比较严格,又需要多分时去处理一些指定的任务,在无法使用RTOS的情况下,使用一个硬件定时器,来建立各种任务时间标志位,是比较通用的做法,但是随着时间标志位变量的增加,代码的维护以及简洁度却越来越艰难。

因此,楼主使用了一种类似线程管理的时间轮询方式(可能用词不当),来进行一个硬件定时器模拟多个软件定时器(以下就说明为线程吧),支持线程注册、注销、挂起、唤醒、处理等接口。在使用上,只需要引用两个接口,即可开始工作。     先说明下此接口文件的头文件的一些变量,THREAD_NUM_MAX是指能支持最大的线程数目,理论上可以达到四个字节长度数目。使用时候先初始化线程Thread_Init,然后把Thread_RunCheck放在硬件定时器上1ms查询一次当作时钟基准,然后Thread_Process放于while里面轮询查找线程标志。需要定时运行某个任务时候(函数),在进入while里面之前使用注册函数Thread_Login即可。主要退出这个函数使用Thread_Logout即可。下面会举个example来说明这些接口的使用。


接下来简单介绍下一些接口的实现。源码会放于附件,具体的可以自行分析理解。


首先来说明下两个结构体定义。首先第一个结构体是对线程状态封装,包括线程运行标识flag,当定时轮询到这个线程此标志位会置位,运行条件con包括单次执行运行条件,也就是说此线程只执行一次,还有多次执行条件,永久执行条件。此些条件在头文件的枚举定义。运行次数表示执行的次数,但为永久执行条件,此cnt赋值为0即可。frep为运行周期,即是多少毫秒运行一次,fun是线程函数的指针。thread_manage结构体是线程管理结构体,里面包含当前线程运行数和挂起数。在这里我们申请下一个静态线程管理实例变量。static struct thread_manage thread;所有的线程状态变量都在这里。


 

大概说明下线程是如何一个一个轮询执行的。主要在Thread_Process接口里面。


 

同样再来分析下线程注册接口,这是在初始化的时候需要用到。

 

线程运行条件核对,放在于1ms的硬件定时器中断或者回调中,以此轮询查找线程运行周期状态是否满足。


 

在这里使用的是nucle-L011板子,利用cube生成代码工程。使用两个外设,GPIO(LED)和usart,在这里我们新建两个线程,一个500ms点灯,一个1s串口发送数据。

 
生成的cube代码在tim.c文件上,开启定时器中断,并且写上自己的回调函数。

 
写好自己的线程函数


 
初始化以及注册线程。


 

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多