1 系统时钟中断驱动引擎
rt-thread操作系统中当线程时间片耗尽,或是当线程sleep一段时间后唤醒再被调度,此过程又是如何进行的呢?到底是谁来驱动这一过程的呢?
答案是时钟中断源。且来看看时钟中断例程:
在bsp/stm32f20x/drivers/board.c源文件中存在这么一个时钟中断例程代码:(这里以stm32f20x的MCU为例)
/**
* This is the timer interrupt service routine.
*
*/
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();//进入中断
rt_tick_increase();//增加tick
/* leave interrupt */
rt_interrupt_leave();//离开中断
}
其中rt_tick_increase的函数如下定义:
/**
* This function will notify kernel there is one tick passed. Normally,
* this function is invoked by clock ISR.
*/
void rt_tick_increase(void)
{
struct rt_thread *thread;
/* increase the global tick */
++ rt_tick;//全局变量rt_tick加1
/* check time slice */
thread = rt_thread_self();//获取当前调度的线程
-- thread->remaining_tick;//当前调度的线程的剩余时间片减1
if (thread->remaining_tick == 0)//如果当前调度的线程没有剩余时间片了
{
/* change to initialized tick */
thread->remaining_tick = thread->init_tick;//重新将剩余时间片设置为初始化时间片
/* yield */
rt_thread_yield();//将此线程从调度器就绪队列中取出来放到末尾,再次然后调度
}
/* check timer */
rt_timer_check();//检查时钟链表上是否有时间到达的时钟
}
rt_thread_yield函数已在之前的文章
http://blog.csdn.net/flydream0/article/details/8584362一文的第7章已有介绍,而rt_timer_check函数在
http://blog.csdn.net/flydream0/article/details/8570841#t4一文中第3.3节也已有介绍。
由上述代码可见,一旦系统产生时钟中断,在中断例程中,系统首先将检查当前正在运行的线程剩余时间片是否耗尽,如果耗尽则将其从调度器就绪队列中取出放到末尾,然后再重新调度线程,接着检查是否有休眠的线程时间到达,如果有,则触发其时钟超时回调函数,这个时钟超时回调函数在之前的文章http://blog.csdn.net/flydream0/article/details/8584362#t2一文中的2.1节介绍初始化线程函数_rt_thread_init时有如下代码:
//...
/* init thread timer */
rt_timer_init(&(thread->thread_timer),//初始化线程的定时器
thread->name,
rt_thread_timeout,
thread,
0,
RT_TIMER_FLAG_ONE_SHOT);
//...
可见在线程初始化时,就设置了线程内部时钟的超时回调函数rt_thread_timeout函数,关键就是这个函数会进行一些线程调度的操作,其源码如下定义:
/**
* This function is the timeout function for thread, normally which is invoked
* when thread is timeout to wait some resource.
*
* @param parameter the parameter of thread timeout function
*/
void rt_thread_timeout(void *parameter)
{
struct rt_thread *thread;
thread = (struct rt_thread *)parameter;
/* thread check */
RT_ASSERT(thread != RT_NULL);
RT_ASSERT(thread->stat == RT_THREAD_SUSPEND);
/* set error number */
thread->error = -RT_ETIMEOUT;
/* remove from suspend list *///从挂起链表中移除
rt_list_remove(&(thread->tlist));
/* insert to schedule ready list */
rt_schedule_insert_thread(thread);//加入调度器
/* do schedule */
rt_schedule();//重新调度
}
可见,其会将当前挂起的线程加入到调度器就绪队列,然后重新调度。
2 系统时钟中断引擎小结
综上所述,当系统产生时钟中断时,首先检查当前正在运行的线程是否还有剩余时间片,如果耗尽则从就绪队列中移除放到末尾再重新调度,接着检查是否存在挂起的线程有时间到达的,如果有,则加入到调度器就绪队列中,然后重新调度。
3 软件定时器模式下的驱动引擎
此外,需要注意地是,如果用户设置使用软件软件定时器方式,则系统中还存在一时钟线程timer_thread,见http://blog.csdn.net/flydream0/article/details/8570841一文,此线程专门随时系统时钟tick的增加来检查定时器是否时间到达,这其中就包含线程的定时器,一旦线程对应的定时器时间到达,则将加入到线程调度器就绪队列中进行调度。由此可见,在设置了软件定时器模式时(默认情况下,rt-thread使用硬件定时器),这个timer_thread线程也是rt_thread操作系统线程调度的驱动引擎.
4 如何设置系统时钟中断间隔
查看rt-thread操作系统的用户手册时,上面有提到rt_thead操作系统的时钟每个tick的默认间隔为10ms,那么这个10 ms双是如何来的呢?
答案是在/bsp/stm32f20x/drivers/board.c源文件中,且看SysTick_Configuration函数的实现:
/*******************************************************************************
* Function Name : SysTick_Configuration
* Description : Configures the SysTick for OS tick.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SysTick_Configuration(void)
{
RCC_ClocksTypeDef rcc_clocks;
rt_uint32_t cnts;
RCC_GetClocksFreq(&rcc_clocks);//获得系统的晶振频率
cnts = (rt_uint32_t)rcc_clocks.HCLK_Frequency / RT_TICK_PER_SECOND;//计算出多少次晶振才是一个tick时间片
SysTick_Config(cnts);//配置系统tick
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//配置时钟源
}
由上述代码可见,rt_thread的系统tick是由RT_TICK_PER_SECOND这个宏来配置的,RT_TICK_PER_SECOND在头文件rtconfig.h文件中定义,如下:
/* Tick per Second */
#define RT_TICK_PER_SECOND 100
此参数的含义是1秒包含多少个tick, 这里默认是100,则默认情况下1秒包含100个tick,那么即每个tick为10ms,现在明白了吧?
如果我们要修改每个tick的时间隔,则只需要修改RT_TICK_PER_SECOND这个宏的值即可.
分享到:
相关推荐
1、TFT根据RT Thread驱动框架编写,FSMC总线,可直接用。适合常用的9320、9325、9328TFT驱动。 2、SPI W25Qxx Nor flash驱动,可存储字库和文件系统。 3、实时时钟(RTC),可用串口指令设置时间和日期,串口打印...
RT-thread RTOS系统概述,RTX内核可以轻松地使用实时执行器,该实时执行器为基于ARM CPU核的微控制器提供。RTX内核提供了一组C函数以及C宏,可以让开发者使用在CPU中并行运行的任务去创建实时运用程序。这个部分提供...
C语言基于RT-Thread和N32G457的数字气压表源码。基于RT-Thread系统和N32G457的数字气压表的设计。 气压传感器使用国产的华普HP5806气压传感器,RTC时钟使用国产时钟芯片SD3078. 配置参数存储采样AT24C16;气压数据...
桌面Mini时钟项目用来演示如何使用RT-Thread Stduio开发项目,整个项目的架构如下: 在上一篇博文中简单的介绍了RT-Thread Studio一站式工具,基于STM32L431RCT6这个芯片创建工程,并修改时钟为使用外部时钟。 使用...
2. 中断控制器,支持时钟/看门狗中断,串口收发中断,IIC中断等 3. 串口(Demo版本仅支持UART0和UART1),包括FIFO模式和非FIFO模式 4. IIC控制器 5. 电源管理(PWM) 6. Nand/Nor Flash控制器 7. LCD控制器 8. SD卡控制...
1. 项目进度 桌面Mini时钟项目用来演示如何使用RT-Thread ...使用RT-Thread Studio DIY 迷你桌面时钟(二)| 获取温湿度传感器数据(I2C设备驱动+SHT3x软件包) 接下来添加at_device设备ESP8266用于连接网络,添加ne
>timer.S————设置 8253 工作模式,提高时钟中断的频率 >timer.h————声明 timer.S 中的函数 >8259A.S————两个函数:设置8259A的pic_init 和 开启中断的set_if >8259A.h————声明 8259A.S 中的函数 ...
在前四篇博文中简单的介绍了RT-Thread Studio一站式工具,基于STM32L431RCT6这个芯片创建工程,并修改时钟为使用外部时钟,以及添加SHT3x软件包获取温湿度传感器数据,添加了ESP8266设备连接网络,使用NTP服务器进行...
RT-Thread使用情况概述移植RT-Thread到STM32H50,设置系统滴答时钟产生1ms中断,驱动RT-Thread. #define RT_HEAP_SIZE (1024*40) //1024 #define RT_MAIN_THREAD_STACK_SIZE 1024 #define RT_USING_HEAP 其他为默认 ...
操作系统-时钟中断-模拟时钟中断的产生及设计一个对时钟中断事件进行处理的模拟程序,含详细代码 操作系统-时钟中断-模拟时钟中断的产生及设计一个对时钟中断事件进行处理的模拟程序,含详细代码
4.7 RT-Thread 硬件定时器的使用 主板 BearPi IOT Std 板 主芯片 STM32L431RCT6 本次使用TIM2, 用STM32CubeMX 初始化为内部时钟
操作系统-时钟中断-模拟时钟中断的产生及设计一个对时钟中断事件进行处理的模拟程序,含详细代码
如果对测试代码有疑问,请联系rt-thread咨询 bsp/mini2440/sdcard.c rt_uint8_t sd_init(void) { //-- SD controller & card initialize int i; sd_delay(1000000); //此处增加一行对ARM仿真性能进行压力测试 ...
RT-Thread使用情况概述内核部分:主要使用了线程管理 时钟管理 组件部分:FinSH控制台,netdev网卡,SAL套接字抽象层,ulog日志 软件包部分:cjson webclient,pahomqtt,fal,wiznet,dhtxx 硬件框架采集端:简单的LORA模组,...
在Linux的0号中断是一个定时器中断。...Linux的OS时钟的物理产生原因是可编程定时/计数器产生的输出脉冲,这个脉冲送入CPU,就可以引发一个中断请求信号,我们就把它叫做时钟中断。 “时钟中断”是特
1. 项目进度 桌面Mini时钟项目用来演示如何使用RT-Thread Stduio开发项目,整个项目的架构如下: ...使用RT-Thread Studio DIY 迷你桌面时钟(二)| 获取温湿度传感器数据(I2C设备驱动+SHT3x软件包)
用rt-thread系统替换uC/OS-II系统来实现探索者开发板综合测试实验,程序直接下载到探索者开发板上就能使用。可以实现电子图书、数码相框、时钟、记事本、计算器和音频播放等功能。
模拟时钟中断的产生及设计一个对时钟中断事件进行处理的模拟程序。 通过实习了解中断及中断处理程序的作用。本实习模拟“时钟中断事件”的处理,对其它中断事件的模拟处理,可根据各中断事件的性质确定处理原则,...
时钟程序---可以自主控制时间,倒计时等。
基于GD32E230C芯片已经移植好的RT-Thread-Nano DEMO