请教ISR数据传递问题

小弟目前正在做一个课题的系统设计, 对QNX下的线程通信有些疑问.

课题使用一块A/D采样板收集一个角动量转换器的输出值,测量一个手柄的当前位置. A/D采样板由主线程启动采样,采用中断工作方式, 在采样结束后通过PCI总线向系统发出中断.

目前设计中,在A/D板卡驱动ISR中访问硬件,通过从板卡IO空间中读取最新的采样值. 但是对于ISR如何将读数返回给主线程存在疑问.

QNX的Message属于同步发送,ISR中调用MsgSend()会阻塞ISR线程, 应该是不能使用的.
QNX 的的帮助文件Writing a Resoruce Manager中提到: QNX的ISR可以发出一个PULSE通知一个线程,并迫使系统进行一次线程调度. 我想也许可以在主线程中通过调用pulse_attach()向系统注册监听ISR发出的脉冲, 并通过全局变量互斥访问来获得采样数值, 不知道这种办法是否安全? 如果可行, 程序改如何编制, 帮助文档中叙述不详, 还望高手指点.

另外,如果数据传递两比较大, 是否可以采用POSIX的 Message Queue来传递? POSIX的Messge Queue 好象是属于核外实现, 更适用于进程间通信, 采用 Message Queue是否会显著降低系统性能?

进程间方法很多(当然也可以用于线程间,问题是是否必要),
QNX也有异步非阻塞的消息传递Asynchronous Messaginghttp://www.qnx.com/developers/docs/6.4.0/neutrino/technotes/async_messaging.html,问题是Asynchronous messaging is an experimental feature; 不过你做课题应该没什么影响。

Pulse本身可带3/5个Byte的数据,如果够用就最好。

MQ会比Message慢。如P4 1.8G的CPU,大概Pulse需要1微秒,Message需要几微秒,MQ可能需要10几微秒。不知道10多微秒对你的系统来说是否慢。

-------------------------------
线程间用一个全局变量再加mutex同步也是不错的选择。但没有上面暗中带有的Queue的功能,可能会掉数据。


如果我选的话,先看Pulse够用否,再看Asynchronous Messaging。MQ就简单,如果速度满足要求的话。

谢谢nakeyfish. 我会仔细看一下异步消息的资料.

我们实验室订购的是6.2.1 Standard版本, 帮助里好像还没有提到异步消息,最多是脉冲和POSIX消息队列.
系统扩展设备比较复杂, 包含多路低速A/D, 并且数个429通道上一直有数据通信.

我们再规划一下通信方式.
多谢.

ISR(你用InterruptAttach()挂上去的那个函数)里不能进行任何内核调用,所以 Message Passing或是POSIX消息队列都不能用来从ISR往别的线程传数据。

脉冲能带4字节数,如果数据量小,ISR可以把数据直接放在脉冲里。如果数据量较大,可以用一个全局数据块,由ISR和工作线程共享。不过,这块数据不能用mutex进行保护(因为ISR里不能调用MutexLock),而是应该用InterruptLock()/InterruptUnlock()来进行保护。

还有一个办法是直接用中断线程(IST),也就是用InterruptAttachEvent()来注册一个事件;这个事件可以是个脉冲,也可以是SIGEV_INTERRUPT;总之,由这个事件来激活一个线程,对硬件的读写在线程内进行。这个线程,可以做任何操作(包括阻塞操作)

这个方法灵活度好. AD采样可以使用PULSE解决, 429估计要用IST了.

多谢xtang.

用IST的注意点是中断延时会增大。所以你要考虑你的IST是不是能把硬件里的数据及时取出来。(如果来不及取,后一个数据又到了的话,硬件里有没有足够的缓冲)

当然,你可以提高IST线程的优先级。

多谢提醒. 板卡设计了FIFO缓冲区, 估算过时间能来得及. 当然具体情况还是要实测了以后再说.