Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
内核学习营
SYSTICK_心跳时钟节拍
个人分享心得(三)——时钟管理
发布于 2019-03-04 17:01:57 浏览:1964
订阅该版
[tocm] 对于MCU,晶振像心脏一样不可或缺,记录着MCU运行的时间。同样对于操作系统,也有自己的心跳——系统节拍(OS_Tick)。 ## 一. 系统时钟 系统节拍是系统的最小时间单位,以MCU硬件定时器的中断触发所产生的。即每当经过一个系统节拍时间,系统进入中断处理函数`SysTick_Handler()`。 ```c void SysTick_Handler(void) { /* enter interrupt */ rt_interrupt_enter(); HAL_IncTick(); rt_tick_increase(); /* leave interrupt */ rt_interrupt_leave(); } ``` 系统节拍的大小由一个宏定义`RT_TICK_PER_SECOND`决定,如果这个宏定义被定义为100,那么`系统节拍时间=1/100s=10ms`。 ```c #define RT_TICK_PER_SECOND 100 ``` 在中断处理函数中,最主要的工作就是将系统节拍值`rt_tick`加1,并将当前线程所剩余的时间`remaining_tick`减1,为线程占用处理器的时间做保证。 ## 二.定时器 有了系统时间便可为操作系统提供定时器功能,定时器可分为硬件定时器和软件定时器,也有单次触发定时器和周期触发定时器。 硬件定时器和软件定时器本质都是定时器,最大的区别是上下文的不同,硬件定时器的上下文为中断,软件定时器的上下文为线程。因为中断的优先级可以打断线程,所以硬件定时器的优先级相对于软件定时器的优先级更高,但是硬件定时器并不像软件定时器那么灵活,就像硬件定时器中无法调用挂起或者调度的API,因为这些API中禁止系统中断。 硬件定时器和软件定时器都是以`OS_Tick`为基础的定时器,裸机的定时器是以HWTIMER设备驱动存在。 定时器在开始定时后会按照超时时间顺序进行排列,组成链表rt_timer_list;而当超时函数被执行时相应的定时器也从`rt_timer_list`中删除,如果是周期定时器那么将会重新加入到链表中。 ## 三.定时器运用 ### 1. 定时器控制块`rt_timer` ```c struct rt_timer { struct rt_object parent; //内核对象 rt_list_t row[RT_TIMER_SKIP_LIST_LEVEL];//链表节点 void (*timeout_func)(void *parameter);//超时函数入口 void *parameter;//超时函数参数 rt_tick_t init_tick;//定时器初始超时节拍数 rt_tick_t timeout_tick;//定时器实际超时时的节拍数 }; typedef struct rt_timer *rt_timer_t; ``` 定时器都由`struct rt_timer`控制块创建内核对象,存放定时器的相关信息。定时器可以通过静态或者动态初始化,动态初始化:`rt_timer_create`,静态初始化:`rt_timer_init`。静态初始化定时器和动态初始化定时器的区别是静态初始化定时器是在已经存在的内存空间中进行初始化,即定义结构体时用struct rt_timer;而动态初始化定时器时是动态申请内存空间,则定义结构体时用rt_timer_t。 ## 2.初始化定时器函数`rt_timer_create` `rt_timer_init` ```c /*静态初始化定时器*/ void rt_timer_init(rt_timer_t timer,//定时器句柄,需要对用struct rt_timer定义的定时器控制块进行取地址操作 const char *name,//定时器名字 void (*timeout)(void *parameter),//定时器超时函数入口 void *parameter,//定时器超时函数入口参数 rt_tick_t time,//定时器超时时间,时间单位为时钟节拍 rt_uint8_t flag)//定时器创建时的参数,RT_TIMER_FLAG_ONE_SHOT单次触发定时器,RT_TIMER_FLAG_PERIODIC周期触发定时器,RT_TIMER_FLAG_HARD_TIMER硬件定时器,RT_TIMER_FLAG_SOFT_TIMER软件定时器 /*动态初始化定时器*/ rt_timer_t rt_timer_create(const char *name,//定时器名字 void (*timeout)(void *parameter),//定时器超时函数入口 void *parameter,//定时器超时函数参数 rt_tick_t time,//定时器超时时间,时间单位为时钟节拍 rt_uint8_t flag)//定时器创建时的参数,RT_TIMER_FLAG_ONE_SHOT单次触发定时器,RT_TIMER_FLAG_PERIODIC周期触发定时器,RT_TIMER_FLAG_HARD_TIMER硬件定时器,RT_TIMER_FLAG_SOFT_TIMER软件定时器 ``` 静态初始化定时器和动态初始化定时器其本质都是初始化定时器,但是静态初始化是在已经存在的内存空间中进行,而动态初始化是需要动态申请内存`rt_object_allocate()`。还有`rt_timer_init`函数没有返回值,而`rt_timer_create`函数返回初始化的定时器。 ## 3.删除脱离定时器函数`rt_timer_delete` `rt_timer_detach` ```C /*脱离定时器*/ rt_err_t rt_timer_detach(rt_timer_t timer)//所要脱离的定时器句柄 /*删除定时器*/ rt_err_t rt_timer_delete(rt_timer_t timer)//所要删除的定时器句柄 ``` `rt_timer_detach`脱离的定时器为静态创建的定时器,删掉定时器的链表节点,在将静态定时器从内核系统中进行脱离; `rt_timer_delete`删除的定时器为动态创建的定时器,删掉定时器的链表节点,再将之前申请的内存释放掉。 ## 4.启动停止定时器函数`rt_timer_start` `rt_timer_stop` ```C /*启动一个定时器*/ rt_err_t rt_timer_start(rt_timer_t timer)//输入所要启动的定时器句柄 /*停止一个定时器*/ rt_err_t rt_timer_stop(rt_timer_t timer)//输入所要停止的定时器句柄 ``` 启动定时器:将定时器标志设置为`RT_TIMER_FLAG_ACTIVATED`,并将超时函数插入到rt_timer_list队列中并开始计时。 停止定时器:将定时器标志设置为`RT_TIMER_FLAG_DEACTIVATED`并将定时器从链表中移除。 ![时钟管理.png](/uploads/201903/04/170102dx0uanane73ozex3.png) ![02.时钟管理.xmind](/uploads/201903/04/170144d9kyql8zaweaykk4.attach)
查看更多
2
个回答
默认排序
按发布时间排序
我夏了夏天
认证专家
2019-03-05
Life isn't about finding yourself, life is about creating yourself.
赞!继续加油~
shadowliang
2019-03-19
Hello,world!!!
顶一个~
撰写答案
登录
注册新账号
关注者
0
被浏览
2k
关于作者
家定不举棋
这家伙很懒,什么也没写!
提问
10
回答
6
被采纳
0
关注TA
发私信
相关问题
1
【内核学习】rtthread内核移植记录-STM32F103ZET6-HAL库
2
《内核学习营》+水一方+自用STM32F103VC 板RT-Thread内核移植分享
3
《内核学习营》+水一方+项目中创建标准的 RT-Thread工程
4
内核学习营+坦然+探索者stm32f407板子RT-thread循环点亮led灯
5
<内核学习营>+坦然+探索者stm32f407板子RT-thread串口字符点灯
6
<内核学习营>+坦然+探索者stm32f407板子RT-thread的pwm点灯实验
7
<内核学习营>+坦然+探索者stm32f407板子RT-thread串口实验
8
<内核学习营>+坦然+野火stm32f103板子RT-thread读写SD卡实验
9
<内核学习营>+坦然+探索者stm32f407板子RT-thread的RTC闹钟实验
10
【内核学习营】+王秀峰+led_rgb
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
8
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
3
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部