硬汉嵌入式论坛

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

[FreeRTOS] 请教一下中断延迟的问题

[复制链接]

20

主题

56

回帖

116

积分

初级会员

积分
116
发表于 2015-5-30 17:59:02 | 显示全部楼层 |阅读模式
一个优先级高的任务等待一个信号量,中断事件发生后经xSemaphoreGiveFromISR信号量被释放并且执行了portYIELD_WITHIN_API()语句,实际的情况是似乎并未引起高优先级的任务事先抢占,分别在中断服务程序和该任务被激活记录了定时器的数值,最大延迟3mS。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2015-6-2 20:11:22 | 显示全部楼层
说说两点发现:
1 本来说cortex-M3的CPU的优先级是与原来的FreeRTOS不同的,优先级号越低则优先级高,而我用的NXP的LPC-1788运行的内核却不然,做了个实验,仍然是优先级号大的优先级高。
2 在中断中释放了信号量之后,执行portEND_SWITCHING_ISR(),大多数情况下任务切换还是可以的,在16-400uS之间,但仍然出现了3mS延迟的情况。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 2015-6-2 20:33:09 | 显示全部楼层
1. CM3的优先级是基于中断的,中断号越小优先级越高(假如都是抢占式的,没有子优先级),FreeRTOS是基于任务的,任务优先级号越大任务优先级越高。
    LPC1788必须也是这样的,除非他的库函数做了处理。ARM官方的CMSIS库是通用的,这个库LPC1788应该也可以调用,里面有NVIC的设置函数,你可以试试。

2. 出现3ms的延迟估计是退出中断后,去执行其它高优先级任务了,这个任务执行完后才执行的信号量等待任务。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2015-6-3 19:54:31 | 显示全部楼层
十分感谢管理员的答复,经过今天的试验,也证实了楼上的说法,在之前本人的见解多是对资料没看明白,产生了误解。试验发现,正常的任务切换在16uS左右,大的延时是由于存在其他高优先级的任务影响了portEND_SWITCHING_ISR()任务切换,被阻塞的任务并未及时获得执行。但是,将被阻塞的任务提升至最高优先级后,出现一个新的问题。正常运行一段时间,发生中断后该任务不再被唤醒,就像被挂起一样,其他低优先级任务不受影响。当出现以更高优先级的任务,中断后执行portEND_SWITCHING_ISR(),且更高优先级任务挂起,会唤醒该任务。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2015-6-3 19:55:02 | 显示全部楼层
十分感谢管理员的答复,经过今天的试验,也证实了楼上的说法,在之前本人的见解多是对资料没看明白,产生了误解。试验发现,正常的任务切换在16uS左右,大的延时是由于存在其他高优先级的任务影响了portEND_SWITCHING_ISR()任务切换,被阻塞的任务并未及时获得执行。但是,将被阻塞的任务提升至最高优先级后,出现一个新的问题。正常运行一段时间,发生中断后该任务不再被唤醒,就像被挂起一样,其他低优先级任务不受影响。当出现以更高优先级的任务,中断后执行portEND_SWITCHING_ISR(),且更高优先级任务挂起,会唤醒该任务。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2015-6-3 19:56:08 | 显示全部楼层
十分感谢管理员的答复,经过今天的试验,也证实了楼上的说法,在之前本人的见解多是对资料没看明白,产生了误解。试验发现,正常的任务切换在16uS左右,大的延时是由于存在其他高优先级的任务影响了portEND_SWITCHING_ISR()任务切换,被阻塞的任务并未及时获得执行。但是,将被阻塞的任务提升至最高优先级后,出现一个新的问题。正常运行一段时间,发生中断后该任务不再被唤醒,而信号量已经被释放,就像任务被挂起一样,其他低优先级任务不受影响。当出现以更高优先级的任务,中断后执行portEND_SWITCHING_ISR(),且更高优先级任务挂起,会唤醒该任务。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2015-6-3 20:06:10 | 显示全部楼层
不好意思,网络问题,导致多次发送相同的回复。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 2015-6-3 21:23:29 | 显示全部楼层

回 bucker 的帖子

bucker:不好意思,网络问题,导致多次发送相同的回复。 (2015-06-03 20:06) 
没事的。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2015-6-4 22:14:47 | 显示全部楼层
今天没取得什么进展,延迟的问题是由于优先级的问题造成,已经解决了。获得信号量的任务是最高优先级的,中断后的延迟大约16-25uS,还算可以,但遇到一个新的麻烦,就是这样运行一段时间后会导致这个任务出现有信号量但无法唤醒的情况,出现的节奏有一定随机性,已可排除任务堆栈溢出的可能性。如果出现沉睡的情况,在别的任务中降低该任务的优先级可唤醒这个任务。由于缺乏对FreeRTOS任务调度器的了解,尚无法追踪该任务是处在那种状态及任务列表的顺序情况。[s:147]
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 2015-6-4 22:38:33 | 显示全部楼层

回 bucker 的帖子

bucker:今天没取得什么进展,延迟的问题是由于优先级的问题造成,已经解决了。获得信号量的任务是最高优先级的,中断后的延迟大约16-25uS,还算可以,但遇到一个新的麻烦,就是这样运行一段时间后会导致这个任务出现有信号量但无法唤醒的情况,出现的节奏有一定随机性,已可排除任务堆栈 .. (2015-06-04 22:14) 
FreeRTOS的源码读起来有些费劲,而且有好多宏定义,不像ucos层次结构那么清晰。如果没有记错的话,FreeRTOS的调度是把就绪的任务按照优先级高低顺序排好,调度的时候直接获取就绪列表上面的第一个任务就行。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2015-6-6 21:16:53 | 显示全部楼层
目前仍未取得收获,只好让高优先级的任务改成用中断服务程序实现了。我的情况是,中断大约3mS一次,有个低优先级任务是负责刷显示屏的,运行一次大约5.8mS,这意味着该任务可能被原来的高优先级任务多次剥夺运行状态,不清楚是否因为任务切换较频繁,导致某些列表或资源发生溢出。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 2015-6-7 00:05:34 | 显示全部楼层
给你发个我做的例子,一个低优先级的任务通过外部按键发送信号量,高优先级任务获取信号量后实现emWin屏的截图。
这个是我们V5板子上面的。
光盘A: http://pan.baidu.com/s/1sjLoRbZ
1.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 2015-6-7 00:07:25 | 显示全部楼层
跟你的要求还有些不同,你的要求是中断给任务发送消息。我的是任务给任务发
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2015-6-9 22:58:36 | 显示全部楼层
eric2013:
跟你的要求还有些不同,你的要求是中断给任务发送消息。我的是任务给任务发

前面我说的不够清楚,再稍微详细说明一下,我的程序常态下有4个任务和一个中断在运行:
中断可以看作定时服务,每3mS一次,每次中断都释放一次采集信号量并强制进行一次任务切换;
任务1 优先级最高,负责处理采集数据,它被一个采集信号量阻塞,中断后释放了该采集信号量,处理数据后将数据存入全局变量继续被阻塞;
任务2优先级低一些,负责刷新屏幕,等待键盘队列消息,有了键盘队列消息后进行界面切换操作,但如果等待键盘消息超时就每1S刷新一次屏显数据,刷新大约耗时5.8mS,这意味着在间隔1S时可能在一次刷屏中会遇到两次被任务1剥夺的情况;
任务3是键盘扫描,负责向队列发送消息,优先级比任务2低,其间会有执行任务延时的操作,如果不建立该任务,对出现的问题不产生影响;
任务4优先级最低,就是个蜂鸣器鸣叫的任务,等待一个信号量,基本上处于长期被阻塞的状态。
在任务之间切换及发送消息没问题,但中断发采集信号量,采集信号量已有效,高优先级任务1却不运行了,查了下列表,高优先级任务似乎是在运行态的。但是,如果在任务2将任务1优先级降低,只要有任何一个任务比它优先级高,任务1就会被激活,这意味着只要出现强制任务切换时,任务1未获得最先执行权,故障就得以消除。曾一度以为遇到死锁,但除了任务1,一切其他任务并未受到影响,程序中并未出现两个任务间争夺信号量或队列资源的情况,不符合死锁的条件,虽然共用了一个全局变量,任务1用到EMC总线读操作,任务2用到EMC总线写操作,但EMC总线读写应该是原子操作,要说可能受影响也可能是任务2的操作受到的影响大,不应该影响任务1的运行吧。虽然将任务1的代码改为中断服务中运行,这个问题得到回避,但实时系统的剥夺特性却丧失了,确实让人心有不甘。目前检查了任务堆栈,各任务都有足够的余量,不可能出现堆栈溢出的情况,我想难道是移植过程出的问题还是FreeRTOS存在BUG,这也似乎也不应该。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-15 05:36 , Processed in 0.254994 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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