rt-thread提高控制频率

        也许有人认为RTOS多线程只能实现微秒级延时,也就是说他的线程执行频率顶死只能达到1000HZ,这执行频率只能说不高不低十分鸡肋,那么有什么办法将线程执行频率提高至1K以上呢?那必须是有的

目录

方法一:定时器手搓 

方法二:修改系统定时器

SysTick_Handler

rt_thread_mdelay

 SysTick_Config


 

方法一:定时器手搓 

        想实现微秒级多线程的方法有很多种,其一就是使用定时器中断,在每个中断里跑一个线程,这种方法也是接近于手搓内核(滑稽),在无刷电机FOC驱动中经常用到

        但是考虑到单片机的外设资源有限、项目的可移植性等方面(最主要是我懒)SO 我还是选择使用rt-thread,毕竟不用自己造轮子()

方法二:修改系统定时器

个人使用的是rt-thread-nano   这玩意小,移植方便

d8d84eca578846bab6e31007c6ca8f94.png

 

SysTick_Handler

        rt-thread内核的本质其实就是使用定时器进行一个线程的分配,在几个线程里“反复横跳”。在配置rt-thread的时候,我们知道,rtos会接管几个函数,其中便有系统定时器中断处理函数SysTick_Handler

243f835af9d94d138274d0c901e3300b.png

rt_thread接管后的SysTick_Handler

137d4d1dfbbb47639a39381d326910d7.png

        为什么rtos会接管这个函数呢,找到rt_thread中的SysTick_Handler并转至定义,发现SysTick_Handler即处理了rt_os_tick_callback这个函数,那这个函数有什么作用呢,根据函数名就不难看出。rt_interrupt_enter ,这是一个中断函数的接口,而rt_tick_increase 则用来记录系统定时器的节拍。而系统定时器又是由SysTick_Config这个函数配置的,我们也知道,在移植rtos时需要配置系统定时器,如下图所示

cd98c664c172454db163521c95858689.png

        该函数的参数即为系统定时器两个中断之间的节拍数,两个中断之间节拍数=系统时钟频率/每秒所产生的节拍数

那么这个系统定时器和执行频率又有什么关系呢

rt_thread_mdelay

我们找到rt_thread_mdelay,跳转到定义

1851d62ac0b541588700a80d3f48193d.png

可以看到rt_thread_mdelay函数调用了rt_tick_from_milisecond() 和 rt_thread_sleep()这两个函数

739320e2dfa6475cb8748d4c8a7dd8df.png

        跳转到第一个函数的定义,可以发现,该函数根据输入的延时毫秒数计算出相应的tick的值,并将tick值传给rt_thread_sleep函数将该线程挂起

/**
 * This function will calculate the tick from millisecond.
 *
 * @param ms the specified millisecond
 *           - Negative Number wait forever
 *           - Zero not wait
 *           - Max 0x7fffffff
 *
 * @return the calculated tick
 */
rt_tick_t rt_tick_from_millisecond(rt_int32_t ms)
{
    rt_tick_t tick;

    if (ms < 0)
    {
        tick = (rt_tick_t)RT_WAITING_FOREVER;
    }
    else
    {
        tick = RT_TICK_PER_SECOND * (ms / 1000);
        tick += (RT_TICK_PER_SECOND * (ms % 1000) + 999) / 1000;
    }

    /* return the calculated tick */
    return tick;
}

        对于RT_TICK_PER_SECOND这个宏,跳转到定义,rt-thread给出的解释是OS tick per second即为滴答定时器每秒钟产生的节拍数,而根据SysTick_Config我们可以知道这里的节拍数即为系统定时器每秒钟所产生的中断数

e3a9c488119747509a48bb1a86cea143.png

 SysTick_Config

        这样一来,我们的思路就很清晰了,要想提高线程的执行频率,可以通过缩短系统定时器的节拍(中断)间的时间间隔来实现,即修改rt_hw_board_init中的SysTick_Config来实现

void rt_hw_board_init(void)
{
//#error "TODO 1: OS Tick Configuration."
    /* 
     * TODO 1: OS Tick Configuration
     * Enable the hardware timer and call the rt_os_tick_callback function
     * periodically with the frequency RT_TICK_PER_SECOND. 
     */

	SystemInit();
	
	SystemCoreClockUpdate();
	
	#ifdef REUSE_SYSTICK_TIMER    
	    //缩短系统时钟节拍,使精确度达到10us
		SysTick_Config(640);
	
	#else 
	    //原代码,系统时钟节拍为 64000 ,即1ms,1tick即产生一次中断
		SysTick_Config(64000000 / RT_TICK_PER_SECOND);
	
	#endif
	

	

	
    /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}

        需要注意的是,由rt_tick_from_milisecond该函数定义便可知,更改RT_TICK_PER_SECOND宏的大小虽然可以缩短系统定时器的中断间隔,但是却无法对线程的执行频率起到提高的作用

        修改节拍后,rt_thread_mdelay则不是毫秒级了,当然可以根据自己的配置修改一下,也可以直接不修改,使用宏定义起一个便于你理解的函数名

本人大二,菜狗一枚,还请各位大佬多多指教

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值