SCREA 发表于 2021-11-2 09:06:30

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

本帖最后由 SCREA 于 2021-11-2 09:07 编辑

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

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

初音之恋 发表于 2021-11-2 09:15:29

如果只是死等的话不要使用delay,使用信号量,有信号则进行下一步,没信号就死等,不占用CPU开销

SCREA 发表于 2021-11-2 09:18:27

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

好嘞,试试。

saccapanna 发表于 2021-11-2 09:18:50

不要用OS_Delay,直接等待消息挂起,消息一到就触发唤醒任务就绪。

SCREA 发表于 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 {
       
}

lusson 发表于 2021-11-2 09:44:04

等待消息也可以设置超时时间的。

SCREA 发表于 2021-11-2 09:46:28

lusson 发表于 2021-11-2 09:44
等待消息也可以设置超时时间的。

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

security 发表于 2021-11-2 09:47:00

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

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

security 发表于 2021-11-2 09:50:40

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

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

Trylin 发表于 2021-11-2 09:52:11

任务用信号量阻塞,中断释放信号量

jermy_z 发表于 2021-11-2 10:11:07

用等待消息队列吧   

SCREA 发表于 2021-11-2 10:18:25

本帖最后由 SCREA 于 2021-11-2 10:50 编辑

security 发表于 2021-11-2 09:50
你的点 get 错了。
理论上来讲,中断是最快的,肯定会最快响应,当响应完后,投递消息后,消息自然会被唤 ...

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

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

   中断代码   
    if (xQueueSendFromISR(gpio_evt_queue, &arg, NULL) != pdFAIL) {
      portYIELD_FROM_ISR();
    }


wshtyr 发表于 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也不能耽误的操作,可以在中断里做,做完后将处理结果以某种方式传递给任务做后续处理。

security 发表于 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 时,要立即调度一次。

浮华一生 发表于 2021-11-2 10:47:17

信号量 专门做这个事情的

SCREA 发表于 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 的深层理解。

qwe2231695 发表于 2021-11-2 17:23:28

本帖最后由 qwe2231695 于 2021-11-2 17:24 编辑

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

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

SCREA 发表于 2021-11-3 14:54:50

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

您说的对!!!{:handshake:}
页: [1]
查看完整版本: 有什么方法可以立即退出任务中os_delay?