Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
OS 相同优先级错时调度的方法?
发布于 2013-09-12 13:26:36 浏览:3307
订阅该版
各位高手: 我在应用中,需要采用OS 的相同优先级,但是任务是错开调度。 例如: task_1ms task_10msA task_10msB task_50ms Task_100ms 现在系统采用分时调度。 在调度中,10msA, 10msB . 10msA 先调度,在延迟3ms 后10msB 再调度。这样10msA, 10msB 在系统调度中就错开,CPU 尽量避免在10ms的整数倍时负载过重的问题。 100ms在任务任务10msA延迟7ms后启动。对于这样的调度,是否有个简单的处理方式。
查看更多
6
个回答
默认排序
按发布时间排序
forsakening
2013-09-23
这家伙很懒,什么也没写!
不明觉厉,先mark!
fengzi
2013-09-23
这家伙很懒,什么也没写!
如果说你的需求是比较严格的按照时间刻度启动各个task, 可以这样 定义一个[事件] 各个task等待[事件]触发而挂起, 在一个定时中断或一个高优先级的线程(定时精度得考虑sys tick大小)中做定时的计算,在相应的时刻发送[事件],唤醒相应的线程 不过直观感觉,你描述的需求和你的实际需求似乎有歧义 [s:188]
grissiom
2013-09-23
这家伙很懒,什么也没写!
没有简单的处理方式。可以让几个线程调度的时间片互质,但是这也只是增加了同时被运行的周期。这个周期是各个时间片的最小公倍数。
taurus3g
2013-10-18
这家伙很懒,什么也没写!
谢谢各位的响应: 我提出这个想法是,利用最少的资源来完成这个无优先级抢占的应用。 这里根据最新的RT-THREAD 的定时模块章节的介绍: 软定时器最主要的目的是在系统经过设定的时间后,系统能够自动执行用户设定的动 作。当定时器设定的时间到了,即超时时,执行的动作函数称之为定时器的超时函数。与线 程不同的是,超时函数的执行上下文环境并未用显式给出。 在RT-Thread实时操作系统中,定时器超时函数存在着两种情况: ? 超时函数在(系统时钟)中断上下文环境中执行; ? 超时函数在线程的上下文环境中执行。 如果超时函数是在中断上下文环境中执行,显然对于超时函数的要求与中断服务例 程的要求相同:执行时间应该尽量短,执行时不应导致当前上下文挂起、等待。例如在 中断上下文中执行的超时函数它不应该试图去申请动态内存、释放动态内存等(其中一 个就包括rt_timer_delete函数调用)。 而超时函数在线程上下文中执行,则不会有这个限 制,但是通常也要求超时函数执行时间应该足够短,而不应该影响到其他定时器或本次 定时器的下一次周期性超时。 这两种情况在RT-Thread定时器控制块中分别使用参数: RT_TIMER_FLAG_HARD_TIMER和RT_TIMER_FLAG_SOFT_TIMER指定。HARD_TIMER代表的是 定时器超时函数执行上下文是在中断上下文环境中执行;SOFT_TIMER代表的是定时器函 数执行的上下文是timer线程(在rtconfig.h头文件中应该定义宏RT_USING_TIMER_SOFT使 timer线程能被使用)。 这里是否简单的修改如下结构体定义,增加一个偏移量的属性。 struct rt_timer { struct rt_object_parent; rt_list_t list; /* 用于链接定时器的链表 */ void (*timeout_func)(void* parameter); /* 定时器超时调用的函数 */ void *parameter; /* 超时函数用到的入口参数 */ rt_tick_t init_tick; /* 定时器初始超时节拍数 */ **rt_tick_t rt_offset_tick; /* timer offset */ ** rt_tick_t timeout_tick; /* 定时器实际超时时的节拍数 */ }; typedef struct rt_timer* rt_timer_t 在系统创建定时器时,根据偏移量,自动在初始化加上这个偏移量,这样下次触发的时间就可以起到 错开执行 的目的,虽然都是10MS 的Tick。 但是各自的执行点不一样。 这样达到同样的目的,不用使用其它的线程,事件。
taurus3g
2013-10-19
这家伙很懒,什么也没写!
根据上面的思路, 今天对Timer.c 模块进行的少量的变动。 修改如下: ``` static void _rt_timer_init(rt_timer_t timer, void (*timeoutfunc)(void *parameter), void *parameter, rt_tick_t time, rt_tick_t offset, rt_uint8_t flag) { /* set flag */ timer->parent.flag = flag; /* set deactivated */ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; timer->timeout_func = timeoutfunc; timer->parameter = parameter; timer->timeout_tick = 0; timer->init_tick = time; **timer->offset_tick = offset;** /* initialize timer list */ rt_list_init(&(timer->list)); } ``` 对 rt_err_t rt_timer_start(rt_timer_t timer) 函数进行少量的修改: ``` if(timer->parent.flag & RT_TIMER_FLAG_OFFSET){ timer->timeout_tick = rt_tick_get() + timer->init_tick; } else{ timer->timeout_tick = rt_tick_get() + timer->init_tick + timer->offset_tick; timer->parent.flag |= RT_TIMER_FLAG_OFFSET; } ``` 在对函数申明的形参进行增加一个offset. 这样就基本完成了。 进行少量的代码测试: ``` void App_10msA(void *parameter) { rt_kprintf(" 10msA Actived "); } void App_10msB(void *parameter) { rt_kprintf(" 10msB Actived "); } void App_20ms(void *parameter) { rt_kprintf(" 20ms Actived "); } void App_50ms(void *parameter) { rt_kprintf(" 50ms Actived "); } void App_100ms(void *parameter) { rt_kprintf(" 100ms Actived "); } int rt_application_init() { rt_timer_init(&timer_10msA, "timer1", /* 定时器名字是 timer1 */ App_10msA, /* 超时时回调的处理函数 */ RT_NULL, /* 超时函数的入口参数 */ 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ 1, RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ rt_timer_init(&timer_10msB, "timer2", /* 定时器名字是 timer1 */ App_10msB, /* 超时时回调的处理函数 */ RT_NULL, /* 超时函数的入口参数 */ 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ 0, RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ rt_timer_init(&timer_20ms, "timer2", /* 定时器名字是 timer1 */ App_20ms, /* 超时时回调的处理函数 */ RT_NULL, /* 超时函数的入口参数 */ 20, /* 定时长度,以OS Tick为单位,即20个OS Tick */ 0, RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ rt_timer_init(&timer_50ms, "timer3", /* 定时器名字是 timer1 */ App_50ms, /* 超时时回调的处理函数 */ RT_NULL, /* 超时函数的入口参数 */ 50, /* 定时长度,以OS Tick为单位,即50个OS Tick */ 2, RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ rt_timer_init(&timer_100ms, "timer4", /* 定时器名字是 timer1 */ App_100ms, /* 超时时回调的处理函数 */ RT_NULL, /* 超时函数的入口参数 */ 100, /* 定时长度,以OS Tick为单位,即100个OS Tick */ 7, RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ rt_timer_start(&timer_10msA); rt_timer_start(&timer_10msB); rt_timer_start(&timer_20ms); rt_timer_start(&timer_50ms); rt_timer_start(&timer_100ms); return 0; } ``` 测试结构如下: 10msB Actived 10msA Actived 10msB Actived 10msA Actived 50ms Actived 20ms Actived 10msB Actived 10msA Actived 10msB Actived 10msA Actived 20ms Actived 10msB Actived 10msA Actived 10msB Actived 10msA Actived 20ms Actived 10msB Actived 10msA Actived 50ms Actived 100ms Actived 下面10msTaskA在前, 10msTaskB 偏移1Tick. 测试结果: ``` rt_timer_init(&timer_10msA, "timer1", /* 定时器名字是 timer1 */ App_10msA, /* 超时时回调的处理函数 */ RT_NULL, /* 超时函数的入口参数 */ 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ 0, RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ rt_timer_init(&timer_10msB, "timer2", /* 定时器名字是 timer1 */ App_10msB, /* 超时时回调的处理函数 */ RT_NULL, /* 超时函数的入口参数 */ 10, /* 定时长度,以OS Tick为单位,即10个OS Tick */ 1, RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */ ``` 测试结果: 100ms Actived 10msA Actived 10msB Actived 20ms Actived 10msA Actived 10msB Actived 10msA Actived 10msB Actived 20ms Actived 10msA Actived 10msB Actived 10msA Actived 10msB Actived 50ms Actived 20ms Actived 10msA Actived 10msB Actived 10msA Actived 10msB Actived 20ms Actived 10msA Actived 10msB Actived 10msA Actived 10msB Actived 20ms Actived 10msA Actived 10msB Actived 50ms Actived 100ms Actived 这样容易的实现的周期任务的错时。
撰写答案
登录
注册新账号
关注者
0
被浏览
3.3k
关于作者
taurus3g
这家伙很懒,什么也没写!
提问
8
回答
13
被采纳
0
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
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
【NXP-MCXA153】 定时器驱动移植
2
GD32F450 看门狗驱动适配
3
【NXP-MCXA153】看门狗驱动移植
4
RT-Thread Studio V2.2.9 Release Note
5
CherryUSB的bootuf2配置
热门标签
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
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
7
个答案
2
次被采纳
a1012112796
18
个答案
1
次被采纳
Ryan_CW
5
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
9
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部