驱动思想之机制和策略
驅(qū)動程序的角色
作為一個程序員, 你能夠?qū)δ愕尿?qū)動作出你自己的選擇, 并且在所需的編程時間和結(jié)果的靈活性之間, 選擇一個可接受的平衡. 盡管說一個驅(qū)動是"靈活"的, 聽起來有些奇怪, 但是我們喜歡這個字眼, 因為它強調(diào)了一個驅(qū)動程序的角色是提供機制, 而不是策略.
機制和策略的區(qū)分是其中一個在 Unix 設(shè)計背后的最好觀念. 大部分的編程問題其實可以劃分為兩部分:" 提供什么能力"(機制) 和 "如何使用這些能力"(策略). 如果這兩方面由程序的不同部分來表達, 或者甚至由不同的程序共同表達, 軟件包是非常容易開發(fā)和適應(yīng)特殊的需求.
例如, 圖形顯示的 Unix 管理劃分為 X 服務(wù)器, 它理解硬件以及提供了統(tǒng)一的接口給用戶程序, 還有窗口和會話管理器, 它實現(xiàn)了一個特別的策略, 而對硬件一無所知. 人們可以在不同的硬件上使用相同的窗口管理器, 而且不同的用戶可以在同一臺工作站上運行不同的配置. 甚至完全不同的桌面環(huán)境, 例如 KDE 和 GNOME, 可以在同一系統(tǒng)中共存. 另一個例子是 TCP/IP 網(wǎng)絡(luò)的分層結(jié)構(gòu): 操作系統(tǒng)提供 socket 抽象層, 它對要傳送的數(shù)據(jù)而言不實現(xiàn)策略, 而不同的服務(wù)器負責各種服務(wù)( 以及它們的相關(guān)策略). 而且, 一個服務(wù)器, 例如 ftpd 提供文件傳輸機制, 同時用戶可以使用任何他們喜歡的客戶端; 無論命令行還是圖形客戶端都存在, 并且任何人都能編寫一個新的用戶接口來傳輸文件.
在驅(qū)動相關(guān)的地方, 機制和策略之間的同樣的區(qū)分都適用. 軟驅(qū)驅(qū)動是不含策略的--它的角色僅僅是將磁盤表現(xiàn)為一個數(shù)據(jù)塊的連續(xù)陣列. 系統(tǒng)的更高級部分提供了策略, 例如誰可以存取軟驅(qū)驅(qū)動, 這個軟驅(qū)是直接存取還是要通過一個文件系統(tǒng), 以及用戶是否可以加載文件系統(tǒng)到這個軟驅(qū). 因為不同的環(huán)境常常需要不同的使用硬件的方式, 盡可能對策略透明是非常重要的.
在編寫驅(qū)動時, 程序員應(yīng)當特別注意這個基礎(chǔ)的概念: 編寫內(nèi)核代碼來存取硬件, 但是不能強加特別的策略給用戶, 因為不同的用戶有不同的需求. 驅(qū)動應(yīng)當做到使硬件可用, 將所有關(guān)于如何使用硬件的事情留給應(yīng)用程序. 一個驅(qū)動, 這樣, 就是靈活的, 如果它提供了對硬件能力的存取, 沒有增加約束. 然而, 有時必須作出一些策略的決定. 例如, 一個數(shù)字 I/O 驅(qū)動也許只提供對硬件的字符存取, 以便避免額外的代碼處理單個位.
你也可以從不同的角度看你的驅(qū)動: 它是一個存在于應(yīng)用程序和實際設(shè)備間的軟件層. 驅(qū)動的這種特權(quán)的角色允許驅(qū)動程序員y嚴密地選擇設(shè)備應(yīng)該如何表現(xiàn): 不同的驅(qū)動可以提供不同的能力, 甚至是同一個設(shè)備. 實際的驅(qū)動設(shè)計應(yīng)當是在許多不同考慮中的平衡. 例如, 一個單個設(shè)備可能由不同的程序并發(fā)使用, 驅(qū)動程序員有完全的自由來決定如何處理并發(fā)性. 你能在設(shè)備上實現(xiàn)內(nèi)存映射而不依賴它的硬件能力, 或者你能提供一個用戶庫來幫助應(yīng)用程序員在可用的原語之上實現(xiàn)新策略, 等等. 一個主要的考慮是在展現(xiàn)給用戶盡可能多的選項, 和你不得不花費的編寫驅(qū)動的時間之間做出平衡, 還有需要保持事情簡單以避免錯誤潛入.
對策略透明的驅(qū)動有一些典型的特征. 這些包括支持同步和異步操作, 可以多次打開的能力, 利用硬件全部能力, 沒有軟件層來"簡化事情"或者提供策略相關(guān)的操作. 這樣的驅(qū)動不但對他們的最終用戶好用, 而且證明也是易寫易維護的. 成為策略透明的實際是一個共同的目標, 對軟件設(shè)計者來說.
許多設(shè)備驅(qū)動, 確實, 是與用戶程序一起發(fā)行的, 以便幫助配置和存取目標設(shè)備. 這些程序包括簡單的工具到完全的圖形應(yīng)用. 例子包括 tunelp 程序, 它調(diào)整并口打印機驅(qū)動如何操作, 還有圖形的 cardctl 工具, 它是 PCMCIA 驅(qū)動包的一部分. 經(jīng)常會提供一個客戶庫, 它提供了不需要驅(qū)動自身實現(xiàn)的功能.
本書的范圍是內(nèi)核, 因此我們盡力不涉及策略問題, 應(yīng)用程序, 以及支持庫. 有時我們談?wù)摬煌牟呗砸约叭绾沃С炙麄? 但是我們不會進入太多有關(guān)使用設(shè)備的程序的細節(jié), 或者是他們強加的策略的細節(jié). 但是, 你應(yīng)當理解, 用戶程序是一個軟件包的構(gòu)成部分, 并且就算是對策略透明的軟件包在發(fā)行時也會帶有配置文件, 來對底層的機制應(yīng)用缺省的動作。
The Role of the Device Driver
As a programmer, you are able to make your own choices about your driver, and choose an acceptable trade-off between the programming time required and the flexibility of the result. Though it may appear strange to say that a driver is “flexible,” we like this word because it emphasizes that the role of a device driver is providing mechanism, notpolicy.
The distinction between mechanism and policy is one of the best ideas behind the Unix design. Most programming problems can indeed be split into two parts: “what capabilities are to be provided” (the mechanism) and “how those capabilities can be used” (the policy). If the two issues are addressed by different parts of the program, or even by different programs altogether, the software package is much easier to develop and to adapt to particular needs.
For example, Unix management of the graphic display is split between the X server, which knows the hardware and offers a unified interface to user programs, and the window and session managers, which implement a particular policy without knowing anything about the hardware. People can use the same window manager on different hardware, and different users can run different configurations on the same workstation. Even completely different desktop environments, such as KDE and GNOME, can coexist on the same system. Another example is the layered structure of TCP/IP networking: the operating system offers the socket abstraction, which implements no policy regarding the data to be transferred, while different servers are in charge of the services (and their associated policies). Moreover, a server like ftpd provides the file transfer mechanism, while users can use whatever client they prefer; both command-line and graphic clients exist, and anyone can write a new user interface to transfer files.
Where drivers are concerned, the same separation of mechanism and policy applies. The floppy driver is policy free—its role is only to show the diskette as a continuous array of data blocks. Higher levels of the system provide policies, such as who may access the floppy drive, whether the drive is accessed directly or via a filesystem, and whether users may mount filesystems on the drive. Since different environments usually need to use hardware in different ways, it’s important to be as policy free as possible.
When writing drivers, a programmer should pay particular attention to this fundamental concept: write kernel code to access the hardware, but don’t force particular policies on the user, since different users have different needs. The driver should deal with making the hardware available, leaving all the issues abouthowto use the hardware to the applications. A driver, then, is flexible if it offers access to the hardware capabilities without adding constraints. Sometimes, however, some policy decisions must be made. For example, a digital I/O driver may only offer byte-wide access to the hardware in order to avoid the extra code needed to handle individual bits.
You can also look at your driver from a different perspective: it is a software layer that lies between the applications and the actual device. This privileged role of the driver allows the driver programmer to choose exactly how the device should appear: different drivers can offer different capabilities, even for the same device. The actual driver design should be a balance between many different considerations. For instance, a single device may be used concurrently by different programs, and the driver programmer has complete freedom to determine how to handle concurrency.
You could implement memory mapping on the device independently of its hardware capabilities, or you could provide a user library to help application programmers implement new policies on top of the available primitives, and so forth. One major consideration is the trade-off between the desire to present the user with as many options as possible and the time you have to write the driver, as well as the need to keep things simple so that errors don’t creep in. Policy-free drivers have a number of typical characteristics. These include support for both synchronous and asynchronous operation, the ability to be opened multiple times, the ability to exploit the full capabilities of the hardware, and the lack of software layers to “simplify things” or provide policy-related operations. Drivers of this sort not only work better for their end users, but also turn out to be easier to write and maintain as well. Being policy-free is actually a common target for software designers.
Many device drivers, indeed, are released together with user programs to help with configuration and access to the target device. Those programs can range from simple utilities to complete graphical applications. Examples include thetunelp program, which adjusts how the parallel port printer driver operates, and the graphicalcardctl utility that is part of the PCMCIA driver package. Often a client library is provided as well, which provides capabilities that do not need to be implemented as part of the driver itself.
The scope of this book is the kernel, so we try not to deal with policy issues or with application programs or support libraries. Sometimes we talk about different policies and how to support them, but we won’t go into much detail about programs using the device or the policies they enforce. You should understand, however, that user programs are an integral part of a software package and that even policy-free packages are distributed with configuration files that apply a default behavior to the underlying mechanisms.
From: LDD3
轉(zhuǎn)載于:https://www.cnblogs.com/embedded-linux/p/5941241.html
總結(jié)
以上是生活随笔為你收集整理的驱动思想之机制和策略的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: powershell新建python文件
- 下一篇: emacs python debug_我