硬汉嵌入式论坛

 找回密码
 立即注册
查看: 845|回复: 9
收起左侧

[ThreadX全家桶] 【已发布】想了一个微秒分辨率的任务调度实现机制方法

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2023-10-9 08:24:10 | 显示全部楼层 |阅读模式
如果直接把RTOS的系统时钟节拍设置为1us,系统负担非常大,而且很多RTOS也做不到100MHz主频下,1us切换一次任务。

这两天测试下是否可行,可行的话,给大家分享下。

这个机制主要是用来替换大家的程序里面DelayUS微秒延迟的API,让其也支持释放CPU权限来支持任务调度。延迟时间到后,还可以根据自己的优先级情况返回执行。




已经发布:


第9期ThreadX视频教程:自制个微秒分辨率任务调度实现方案(2023-10-11)
https://www.armbbs.cn/forum.php?mod=viewthread&tid=121371




回复

使用道具 举报

19

主题

234

回帖

291

积分

高级会员

积分
291
发表于 2023-10-9 08:39:41 | 显示全部楼层
进中断吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
 楼主| 发表于 2023-10-9 08:45:45 | 显示全部楼层

进中断,否则时间到了没法及时通知。
回复

使用道具 举报

4

主题

160

回帖

172

积分

初级会员

积分
172
发表于 2023-10-9 09:02:30 | 显示全部楼层
随着mcu主频的持续提高,1us可能代替1ms成为主流。。。。
回复

使用道具 举报

19

主题

234

回帖

291

积分

高级会员

积分
291
发表于 2023-10-9 09:20:21 | 显示全部楼层
我想的是开一个硬件定时器,线程阻塞等待,时间到发送线程通知或者信号量唤醒线程,
但每个线程都需要一个硬件定时器。如果共用的话那硬件定时器的中断周期要开到1us的精度,然后通过软件计数来确定唤醒哪个线程,可是1us的中断周期也太频繁了。
每个线程配一个硬件定时器的话,想延时多久就开配置成多久就行了,只需要触发一次中断。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
 楼主| 发表于 2023-10-9 09:33:24 | 显示全部楼层
tovinz 发表于 2023-10-9 09:20
我想的是开一个硬件定时器,线程阻塞等待,时间到发送线程通知或者信号量唤醒线程,
但每个线程都需要一个 ...

对,初步就是这个思路,我们的开发板有现成的API,一个定时可以开启4组任务。
不用每个任务都开,仅仅用到任务开即可,一般就2-3任务需要。

剩下就是优化下,做到最短切换极限。

[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*	函 数 名: bsp_StartHardTimer
*	功能说明: 使用TIM2-5做单次定时器使用, 定时时间到后执行回调函数。可以同时启动4个定时器通道,互不干扰。
*             定时精度正负1us (主要耗费在调用本函数的执行时间)
*			  TIM2和TIM5 是32位定时器。定时范围很大
*			  TIM3和TIM4 是16位定时器。
*	形    参: _CC : 捕获比较通道几,1,2,3, 4
*             _uiTimeOut : 超时时间, 单位 1us. 对于16位定时器,最大 65.5ms; 对于32位定时器,最大 4294秒
*             _pCallBack : 定时时间到后,被执行的函数
*	返 回 值: 无
*********************************************************************************************************
*/
void bsp_StartHardTimer(uint8_t _CC, uint32_t _uiTimeOut, void * _pCallBack)
{
    uint32_t cnt_now;
    uint32_t cnt_tar;
	TIM_TypeDef* TIMx = TIM_HARD;
	
    /* H743速度较快,无需补偿延迟,实测精度正负1us */
    
    cnt_now = TIMx->CNT; 
    cnt_tar = cnt_now + _uiTimeOut;			/* 计算捕获的计数器值 */
    if (_CC == 1)
    {
        s_TIM_CallBack1 = (void (*)(void))_pCallBack;

		TIMx->CCR1 = cnt_tar; 			    /* 设置捕获比较计数器CC1 */
        TIMx->SR = (uint16_t)~TIM_IT_CC1;   /* 清除CC1中断标志 */
		TIMx->DIER |= TIM_IT_CC1;			/* 使能CC1中断 */
	}
    else if (_CC == 2)
    {
		s_TIM_CallBack2 = (void (*)(void))_pCallBack;

		TIMx->CCR2 = cnt_tar;				/* 设置捕获比较计数器CC2 */
        TIMx->SR = (uint16_t)~TIM_IT_CC2;	/* 清除CC2中断标志 */
		TIMx->DIER |= TIM_IT_CC2;			/* 使能CC2中断 */
    }
    else if (_CC == 3)
    {
        s_TIM_CallBack3 = (void (*)(void))_pCallBack;

		TIMx->CCR3 = cnt_tar;				/* 设置捕获比较计数器CC3 */
        TIMx->SR = (uint16_t)~TIM_IT_CC3;	/* 清除CC3中断标志 */
		TIMx->DIER |= TIM_IT_CC3;			/* 使能CC3中断 */
    }
    else if (_CC == 4)
    {
        s_TIM_CallBack4 = (void (*)(void))_pCallBack;

		TIMx->CCR4 = cnt_tar;				/* 设置捕获比较计数器CC4 */
        TIMx->SR = (uint16_t)~TIM_IT_CC4;	/* 清除CC4中断标志 */
		TIMx->DIER |= TIM_IT_CC4;			/* 使能CC4中断 */
    }
	else
    {
        return;
    }
}






回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
 楼主| 发表于 2023-10-9 09:35:27 | 显示全部楼层
fyyxxm 发表于 2023-10-9 09:02
随着mcu主频的持续提高,1us可能代替1ms成为主流。。。。

1GHz主频的搞这个比较合适。
回复

使用道具 举报

10

主题

34

回帖

64

积分

初级会员

积分
64
发表于 2023-10-9 10:57:52 | 显示全部楼层
正好需要,期待硬汉老师的分享
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
 楼主| 发表于 2023-10-10 13:46:23 | 显示全部楼层
今晚有时间的话,整个小视频给大家分享下。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
 楼主| 发表于 2023-10-11 09:27:30 | 显示全部楼层
做好了

12.png
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-29 06:47 , Processed in 0.196866 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表