【问题标题】:Why is C used for driver development rather than C#? [duplicate]为什么驱动程序开发使用 C 而不是 C#? [复制]
【发布时间】:2010-10-14 07:05:34
【问题描述】:

可能重复:
C# driver development?

为什么我们使用 C 而不是 C# 来开发设备驱动程序?

【问题讨论】:

标签: c# c driver


【解决方案1】:

因为 C# 程序无法在内核模式下运行 (Ring 0)。

【讨论】:

【解决方案2】:

主要原因是 C 比 C# 更适合低级(接近硬件)开发。 C 被设计为一种可移植的汇编代码形式。此外,很多时候使用 C# 可能很困难或不安全。关键时间是驱动程序在 ring-0 或内核模式下运行的时间。大多数应用程序不应该在这种模式下运行,包括 .NET 运行时。

虽然理论上可行,但很多时候 C 更适合这项任务。其中一些原因是对生成的机器代码进行更严格的控制,并且在直接使用硬件时更接近处理器几乎总是更好。

【讨论】:

    【解决方案3】:

    稍微忽略 C# 的托管语言限制,面向对象的语言(例如 C#)通常会在底层做一些事情,这可能会妨碍开发驱动程序。驱动程序开发——实际上是在硬件中读取和操作位——通常具有严格的时序约束,并利用在其他类型的编程中避免的编程实践,例如忙等待和取消引用从整数常量值设置的指针。设备驱动程序通常实际上是用 C 和内联汇编的混合编写的(或者使用其他一些发出 C 编译器通常不生成的指令的方法)。单独的低级锁定机制(用汇编编写)就足以使 C# 的使用变得困难。 C# 有很多锁定功能,但是当您深入挖掘时,它们处于线程级别。驱动程序需要能够阻止中断以及其他线程来执行某些任务。

    面向对象的语言也倾向于一遍又一遍地分配和释放(通过垃圾收集)大量内存。但是,在中断处理程序中,您访问堆分配功能的能力受到严格限制。这既是因为堆分配可能会触发垃圾收集(昂贵),而且因为您必须避免和处理试图同时分配的中断代码和非中断代码。如果对这段代码、编译器的输出以及管理代码的任何东西(VM 或可能本机编译并且仅使用库)没有太多限制,您最终可能会遇到一些非常奇怪的错误。

    托管语言必须由某人管理。这种管理可能依赖于功能正常的底层操作系统。这会为许多(但不是全部)驱动程序使用托管代码产生引导问题。

    完全可以用 C# 编写设备驱动程序。如果您正在驱动一个串行设备,例如 GPS 设备,那么它可能是微不足道的(尽管您将在较低的地方使用 UART 芯片或 USB 驱动程序,这可能是用 C 或汇编编写的),因为它可以完成作为应用程序。如果您正在编写以太网卡(不用于网络引导),那么(理论上)可能在某些部分使用 C#,但您可能会严重依赖用其他语言和/或编写的库使用操作系统的用户空间驱动程序功能。

    C 用于驱动程序,因为它具有相对可预测的输出。如果您对处理器的汇编有所了解,您可以用 C 编写一些代码,为该处理器编译,并很好地猜测该处理器的汇编是什么样子。您还将了解这些指令的确定性。它们都不会让您感到惊讶并启动垃圾收集器或调用析构函数(或终结)。

    【讨论】:

      【解决方案4】:

      因为 C# 是一种高级语言,它不能直接与处理器对话。 C 代码直接编译成处理器可以理解的本机代码。

      【讨论】:

      • C# 间接编译为本机代码。每台计算机都“间接”编译成处理器可以理解的东西。
      • @Earlz,作为一个长期从事嵌入式系统和驱动程序的人,让 JIT 或解释器在我的内核中松散的想法让我非常不舒服。我很难知道驱动程序将满足其延迟要求而不会增加该级别的复杂性。另一方面,我欢迎 Windows 中的用户模式驱动程序和 linux 中的 FUSE 之类的趋势。
      【解决方案5】:

      只是为了对 Darin Dimitrov 的回答有所帮助。是的,C# 程序不能在内核模式下运行。

      但他们为什么不能呢?

      在 Patrick Dussud 的 interview 代码背后,他描述了在 Vista 开发过程中尝试将 CLR 包含在低级别*。他们遇到的障碍是 CLR 依赖于操作系统安全库,而操作系统安全库又依赖于 UI 级别。他们无法为 Vista 解决这个问题。除了奇点,我不知道有任何其他努力可以做到这一点。

      *请注意,虽然“低级别”可能不足以在 C# 中编写驱动程序,但它至少是必要的。

      【讨论】:

        【解决方案6】:

        C 是一种支持更多与其他外围设备交互的语言。所以C用于开发系统软件。唯一的问题是需要管理内存。这是开发人员的噩梦。但是在C#中,内存管理可以轻松自动完成(c和C#之间有n个差异,尝试谷歌搜索)。

        【讨论】:

        【解决方案7】:

        这是实话。倾向于擅长硬件或硬件接口的人,并不是很成熟的程序员。他们倾向于坚持使用 C 等更简单的语言。否则,框架会发展到允许在内核级别使用 C++ 甚至 C# 等语言。整个操作系统都是用 C++ (ECOS) 编写的。所以,恕我直言,这主要是传统。

        现在, 有一些合理的理由反对在驱动程序/内核等要求苛刻的代码中使用更复杂的语言。有可见性方面。 C# 和 C++ 编译器在幕后做了很多工作。一个无害的赋值语句可能会隐藏大量代码(操作符覆盖、属性)。例外的成本可能无法清晰可见。垃圾收集使对象/内存的生命周期变得不清楚。所有使编程更容易的功能,也都是悬而未决的绳索。

        然后是语言所需的生态系统。如果所需的功能引入了太多的组件,那么尺寸本身就可能成为一个因素。如果语言中的原语往往很重(为了有用的软件抽象),那是驱动程序和内核可能不愿意承担的负担。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-02-27
          • 2011-04-30
          • 2019-10-16
          • 2012-10-22
          • 2011-06-18
          • 1970-01-01
          • 2019-09-29
          相关资源
          最近更新 更多