vv6
vv6
驱动牛犊
驱动牛犊
  • 注册日期2002-03-01
  • 最后登录2011-06-17
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望12点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:1325回复:2

关于多处理器的ISR例程

楼主#
更多 发布于:2004-05-15 20:40
用DriverWorks编写PCI9054的驱动程序应用在双CPU系统中。中断服务例程ISR包含读中断寄存器以及其它IO操作,另有一例程包含IO操作A。用逻辑分析仪观测PCI9054的Local端信号,不时发现下面情况:发生中断后先读中断寄存器,然后是另一例程中的IO操作A,接着又是中断服务例程中的其它操作。武安河的书中介绍用中断临界段的方法,哪位高手知道实现“中断临界段”具体函数是什么?或者有什么其它方法?
hellangel
驱动中牛
驱动中牛
  • 注册日期2004-02-16
  • 最后登录2016-04-19
  • 粉丝0
  • 关注0
  • 积分1002分
  • 威望236点
  • 贡献值0点
  • 好评度205点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2004-05-16 12:27
ISR的同步操作
作为一个通用规则,ISR可以与驱动程序的其它部分共享数据和硬件资源。任何时候你听到“共享”这个词,就应该立即想到同步问题。例如,一个标准的UART设备有一个数据端口,驱动程序就用这个端口来读写数据。你可能希望串口驱动程序的ISR能随时访问这个端口。改变波特率必须设置一个控制标志,因此应该先在这个数据端口上执行两个单字节的写操作,然后清除控制标志。如果UART在改变波特率的途中被中断,你可能看到两种意外情况,或者是中断传输的数据字节被放到波特率分配寄存器中,或者是应该传递给分配寄存器的控制数据被当成普通数据传输。

系统在一个相对高的IRQL(DIRQL)上用一个自旋锁来保护ISR的执行。为了简化获取该自旋锁以及提升IRQL到与中断相同的级,系统提供了下面服务函数:

BOOLEAN result = KeSynchronizeExecution(InterruptObject, SynchRoutine, Context);
 

InterruptObject(PKINTERRUPT)是一个指向中断对象的指针,这个中断对象描述了我们要同步的中断。SynchRoutine(PKSYNCHRONIZE_ROUTINE)是存在于驱动程序中的回调函数的地址。Context(PVOID)是作为参数传递到SynchRoutine的任意上下文参数。我们使用通用术语“同步关键段例程(synch critical section routine)”来描述KeSynchronizeExecution应用的子例程。同步关键段例程有如下原型:

BOOLEAN SynchRoutine(PVOID Context);
 

即该例程接受一个参数并返回一个布尔类型的结果。当该例程获得控制时,当前CPU将运行在IoConnectInterrupt调用中指定的同步IRQL上,并且拥有与中断关联的自旋锁。因此,设备中断将被临时阻塞,SynchRoutine就可以自由地访问与ISR共享的数据和硬件资源。

KeSynchronizeExecution将返回SynchRoutine返回的任何值。由于布尔类型声明为无符号字符类型,因此你只能有一个字节用来从SynchRoutine返回信息。

春眠不觉晓,处处闻啼鸟。 夜来风雨声,花落知多少?
vv6
vv6
驱动牛犊
驱动牛犊
  • 注册日期2002-03-01
  • 最后登录2011-06-17
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望12点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-05-16 13:27
我的PCI卡在硬件上已经做了处理,不怕ISR中断任何操作,但是逻辑分析仪上看ISR被其他运行在PASSIVE的例程中断了,这是最致命的!在多处理器系统中,运行在DIRQL的ISR例程和运行在PASSIVE的例程可以异步运行么?
游客

返回顶部