搜索
bottom↓
回复: 17

有什么方法可以立即退出任务中os_delay?

[复制链接]

出0入4汤圆

发表于 2021-11-2 09:06:30 | 显示全部楼层 |阅读模式
本帖最后由 SCREA 于 2021-11-2 09:07 编辑

使用FREERTOS
某中断触发:触发后,立即发送消息A。
任务X:初始化,  大循环{ 读取来自中断的队列消息A,有消息则处理,没消息就os_delay_ms(10)}.

因为中断触发时间不确定(中断触发时间级别10us~10s),一旦此任务进入os_delay等待,如何才能立即退出os_delay_ms,开始读取消息。

出0入16汤圆

发表于 2021-11-2 09:15:29 | 显示全部楼层
如果只是死等的话不要使用delay,使用信号量,有信号则进行下一步,没信号就死等,不占用CPU开销

出0入4汤圆

 楼主| 发表于 2021-11-2 09:18:27 | 显示全部楼层
初音之恋 发表于 2021-11-2 09:15
如果只是死等的话不要使用delay,使用信号量,有信号则进行下一步,没信号就死等,不占用CPU开销 ...

好嘞,试试。

出0入113汤圆

发表于 2021-11-2 09:18:50 | 显示全部楼层
不要用OS_Delay,直接等待消息挂起,消息一到就触发唤醒任务就绪。

出0入4汤圆

 楼主| 发表于 2021-11-2 09:34:45 | 显示全部楼层
saccapanna 发表于 2021-11-2 09:18
不要用OS_Delay,直接等待消息挂起,消息一到就触发唤醒任务就绪。

这个得死等,没消息的时候,则else会执行。这样任务就停不下来全部浪费在else处理上了。
https://www.freertos.org/a00018.html


if(消息函数《有消息则返回非0》){
   
}
else {
       
}

出0入54汤圆

发表于 2021-11-2 09:44:04 | 显示全部楼层
等待消息也可以设置超时时间的。

出0入4汤圆

 楼主| 发表于 2021-11-2 09:46:28 | 显示全部楼层
lusson 发表于 2021-11-2 09:44
等待消息也可以设置超时时间的。

超时是设置为0.必须立即响应,否则无法快速响应中断。
因为中断us级别,OS是ms级别

出0入8汤圆

发表于 2021-11-2 09:47:00 | 显示全部楼层
SCREA 发表于 2021-11-2 09:34
这个得死等,没消息的时候,则else会执行。这样任务就停不下来全部浪费在else处理上了。
https://www.fre ...

要用 xQueueReceive 吧,可以设置死等,或者超时等待的。
这是 RTOS 的必要功能。

出0入8汤圆

发表于 2021-11-2 09:50:40 | 显示全部楼层
SCREA 发表于 2021-11-2 09:46
超时是设置为0.必须立即响应,否则无法快速响应中断。
因为中断us级别,OS是ms级别 ...


你的点 get 错了。
理论上来讲,中断是最快的,肯定会最快响应,当响应完后,投递消息后,消息自然会被唤醒,对应的现象就是,你就会接收到消息,醒过来。否则,你将永远在睡觉(死等的模式)。
你设置为 0,那相当于轮询模式。

出0入17汤圆

发表于 2021-11-2 09:52:11 | 显示全部楼层
任务用信号量阻塞,中断释放信号量

出0入0汤圆

发表于 2021-11-2 10:11:07 | 显示全部楼层
用等待消息队列吧   

出0入4汤圆

 楼主| 发表于 2021-11-2 10:18:25 | 显示全部楼层
本帖最后由 SCREA 于 2021-11-2 10:50 编辑
security 发表于 2021-11-2 09:50
你的点 get 错了。
理论上来讲,中断是最快的,肯定会最快响应,当响应完后,投递消息后,消息自然会被唤 ...


谢谢您。是的,我把时间设为最大,只要中断不触发就一直Pending那里,但还是不能解决快速响应问题。

随后增加了主动切换到最高优先级的函数,好了些。但还是没有把时间设为0轮询处理的快。

  1.    中断代码   
  2.     if (xQueueSendFromISR(gpio_evt_queue, &arg, NULL) != pdFAIL) {
  3.         portYIELD_FROM_ISR();
  4.     }
复制代码


出0入42汤圆

发表于 2021-11-2 10:41:29 | 显示全部楼层
SCREA 发表于 2021-11-2 09:46
超时是设置为0.必须立即响应,否则无法快速响应中断。
因为中断us级别,OS是ms级别 ...

1、无论是否使用OS,只要没有频繁关闭/打开中断,中断都会及时响应。
2、对于RTOS,只有在只靠节拍(tick)定时器来调度任务时,响应时间才是ms级别。如果使用信号量实现中断和任务的同步,响应也是us级别,比中断响应略慢一点。
3、对于一个us也不能耽误的操作,可以在中断里做,做完后将处理结果以某种方式传递给任务做后续处理。

出0入8汤圆

发表于 2021-11-2 10:42:51 | 显示全部楼层
SCREA 发表于 2021-11-2 10:18
谢谢您。是的,我把时间设为最大,只要中断不触发就一直Pending那里,但还是不能解决快速响应问题。

随 ...

任务优先级是高的,你加了 portYIELD_FROM_ISR 的话,那么退出 ISR,是要立即调度唤醒你的,这就是 RTOS 的 real time 的精髓。
至于没你轮询快,那个层面的比较没太大意义。

感觉 FreeRTOS 做繁琐了,一般而言,是不需要靠  portYIELD_FROM_ISR 这些来做的,只要投递了消息之类的,退出 ISR 时,要立即调度一次。

出0入0汤圆

发表于 2021-11-2 10:47:17 | 显示全部楼层
信号量 专门做这个事情的

出0入4汤圆

 楼主| 发表于 2021-11-2 11:46:44 | 显示全部楼层
security 发表于 2021-11-2 10:42
任务优先级是高的,你加了 portYIELD_FROM_ISR 的话,那么退出 ISR,是要立即调度唤醒你的,这就是 RTOS  ...


看起来解决了。
统一谢谢楼上各位的建议。
队列、信号量、事件都可以,但优先选择信号量,毕竟相比较其它,这个资源消耗最少。关键是时序问题,Linux 不会在线Debug,调试起来不方便(又回到调试AVR没有JTAG的时代)。

感觉这种硬件上要求us的时序,OS tick只有ms输出,可以做成练习题了,搞懂能加强对OS 的深层理解。

出90入34汤圆

发表于 2021-11-2 17:23:28 | 显示全部楼层
本帖最后由 qwe2231695 于 2021-11-2 17:24 编辑

同优先级 阻塞以后,其他任务无法执行对吗?

如果系统只有3个任务,任务优先级都是Normal,那么其中一个任务阻塞等待,其他任务是一直无法得到cpu使用权的。

出0入4汤圆

 楼主| 发表于 2021-11-3 14:54:50 | 显示全部楼层
wshtyr 发表于 2021-11-2 10:41
1、无论是否使用OS,只要没有频繁关闭/打开中断,中断都会及时响应。
2、对于RTOS,只有在只靠节拍(tick ...

您说的对!!!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子论坛 -- 东莞阿莫电子网站 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2023-2-7 19:42

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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