2008年7月30日星期三

Sharing Hardware Registers: When to replace multiple writers with a shared resource driver.

Sharing Hardware Registers: When to replace multiple writers with a shared resource driver.
Posted by Jeremy Cooke
翻译自
http://blogs.msdn.com/ce_base/archive/2007/03/29/sharing-hardware-registers-when-to-replace-multiple-writers-with-a-shared-resource-driver.aspx

Hi, I am cpuwolf。这篇来自微软的建议,写的是关于多个驱动共享同一个硬件的问题。这里给出了很好的建议。我尝试用尽可能贴切的专业词语翻译,有什么不对的地方,请指出。
当设计复杂的系统时,偶尔会必需协调对某些的共享资源的访问。一般这些同步问题都由操作系统所提供的例如critical section或mutex等来解决 。这些技术在它是一个简单的共享资源,并且较少的对它的访问时,是无可挑剔的。但对于复杂的资源访问多个threads ,进程,驱动程序,或多个应用程序,新的规范可能更为合适。一个很好的共享资源的驱动程序的例子,就是GPIO驱动程序。每个驱动可能共用一个GPIO模块的寄存器,或者共同读-修改-写,每个驱动如果不同步,那么就会产生问题,
比起直接访问共享资源,把这些访问操作抽象到一个独立的驱动程序去做,可能会更好。所有会访问共享资源的家伙,可以采用尽量少的open这个驱动或者较少使用它的接口。同时,这个驱动程序在内部去处理将同步问题和处理任何可能出现的错误。调用者可以不用再担心同步问题,因为所有这些麻烦都已经交给了别的驱动。
通过使用这一技术,程序员,往往能够避免使用critical section,否则这样的结构会充斥整个原本的代码。现在每一次对共享资源的访问,现在只需通过一个用户设计的API,这些API抽象了访问动作,并且增加程序的可读性。
共享资源的驱动程序也应该预处理和检查错误的输入,以及很好的处理共享资源的错误。由于错误码现在是集中处理的,所有程序员大可认为共享资源已经被很好的保护。这是team开发时的很重要的一点。
例子学习
这个嵌入式系统具有多通道ADC转换器,并且每个通道都有相应的设备使用。多个不相干的驱动程序都试图访问各自的通道。软件可以将hardware所有通道的转换结果放在一块内存中。如果多个线程请求ADC转换,同时没有适当的同步 那么这里就潜藏着一个污染到另一个的情况。
在这特别的系统里有和ADC转换相关的battery驱动程序, USB驱动程序,以及系统的背光驱动程序。battery驱动程序是要关心当前的电压、电池的温度、以及充电电压和充电电流。 USB驱动程序需要监控USB vbus的电压,而背光驱动器需监测环境光线与光电二极管。由于这些功能是在自己的驱动中处理,所有共享资源的访问,都必须以一个更先进的方式控制。以下图1描绘了每个驱动程序都要存取硬件的ADC 。
模拟向数字转换器,将被抽象,并使用一个专门的驱动程序。驱动程序允许多个writer使用所有通道的转换功能,同时返回结果放在一个用户指定的内存中(见图2下文) 。
这个驱动暴露出一个函数,其中包括A / D转换功能并返回结果。如下:
enum ADChannels
{
AD_CHANNEL_BAT_VOLTAGE = 0,

AD_CHANNEL_BAT_CHG_VOLTAGE,
AD_CHANNEL_BAT_CHG_CURRENT,

AD_CHANNEL_BAT_TEMP,
AD_CHANNEL_USB_VBUS,
AD_CHANNEL_PHOTODIODE,
TOTAL_AD_CHANNELS

};


BOOL PerformADConversion(USHORT *pOutBuffer, DWORD OutSize);
在这里pOutBuffer 指向用户的buffer,在函数返回的大小必须等于TOTAL_AD_CHANNELS。必须注意,当向用户数据区拷贝数据时,建议使用类似CeSafeCopyMemory 的函数来处理,它可以处理非法内存的问题。
该PerformADConversion 函数可以实例化一个critical section同步使用,可以看出在图3 :

在这个设计中,所有硬件访问都被保护在一个集中的代码区,只使用仅仅一个critical section。系统性能得以提升,因为使用了轻量级的critical section,而是一个缓慢的同步对象(如mutex) 。程序员现在可以进一步优化系统性能,每个驱动程序可以同时进行。
虽然使用一个专门的驱动程序来完成这些事情有很多的好处,但是,事实上,这种做法可能会稍微有点慢。因为通过标准的Windows CE的函数访问驱动程序是有一些开销。因此,最好的方法是建立一种结构是驱动的访问开销最小。但是无论怎样,使用这种方法的收益是远远大于这里的开销的。

没有评论: