您现在的位置是: 首页 > 系统优化 系统优化
驱动程序开发原理_驱动程序开发原理是什么
ysladmin 2024-05-09 人已围观
简介驱动程序开发原理_驱动程序开发原理是什么 接下来,我将通过一些实际案例和个人观点来回答大家对于驱动程序开发原理的问题。现在,让我们开始探讨一下驱动程序开发原理的话题。1.单片机驱动开发是什么意思2.驱动开发
接下来,我将通过一些实际案例和个人观点来回答大家对于驱动程序开发原理的问题。现在,让我们开始探讨一下驱动程序开发原理的话题。
1.单片机驱动开发是什么意思
2.驱动开发
3.驱动程序无法使用怎么办
4.嵌入式驱动开发:你需要掌握的六大知识领域
单片机驱动开发是什么意思
单片机驱动开发是指使用单片机来实现特定功能的开发工作。单片机作为一种专门的微型计算机芯片,可以对外部信号进行采集、处理和控制,广泛应用于嵌入式系统和自动控制领域。单片机驱动开发需要编写特定的程序,控制芯片的各个功能模块,如输入输出口、定时器、串口等。这种开发方式具有成本低、可靠性高、体积小等优势,因此在工业自动化、智能家居、医疗设备等领域得到了广泛应用。 单片机驱动开发需要掌握一定的硬件电路设计和编程技能。首先要根据用户需求设计电路原理图,确定各种传感器、执行器等设备的连接方式和信号参数,并选择合适的单片机型号。然后根据硬件电路图编写C语言程序,对芯片进行编程,在程序中实现各个功能模块的初始化、中断处理、定时器配置、端口控制、数据传输等操作。在编程过程中需要熟悉单片机的寄存器、位操作、指针等知识,以达到高效、精确的控制效果。 单片机驱动开发的应用场景非常广泛,例如智能家居系统中的温度控制、灯光控制、安防系统等均可使用单片机进行驱动开发。医疗设备领域的心电图仪、血压计等也采用单片机控制,实现对生命信号的采集和处理。工业自动化中的流水线、机器人、智能仓储等也是单片机驱动开发的重要应用领域。可以预见,随着科技进步和市场需求的不断提高,单片机驱动开发领域将不断拓展,成为未来智能设计的重要基础。驱动开发
本文分三部分来介绍如何构造一个简单的USB过滤驱动程序,包括“基本原理”、“程序的实现”、“使用INF安装”。此文的目的在于希望读者了解基本原理后,可以使用除DDK以外最流行也最方便的驱动开发工具DriverStudio来实现一个自己的过滤驱动,并正确地安装。
一、基本原理
我们知道,WDM(和KDM)是分层的,在构造设备栈时,IO管理器可以使一个设备对象附加到另外一个初始驱动程序创建的设备对象上。与初始设备对象相关的驱动程序决定的IRP,也将被发送到附加的设备对象相关的驱动程序上。这个被附加的驱动程序便是过滤驱动程序。如右图,过滤驱动可以在设备栈的任何层次中插入。IO管理器发出的IRP将会沿着右图的顺序从上往下传递并返回。因此,我们可以使用过滤驱动程序来检查、修改、完成它接收到的IRP,或者构造自己的IRP。
上面这种文字是很枯燥的,好在“前人”已经写过一些范例以供我们更好地理解这些概念。读过Waltz Oney的《Programming Windows Driver Mode》一书的读者大概都知道Waltz Oney提供的范例中有一个关于USB过滤器(第九章)的例子,而在此基础上,《USB Design By Example》()的作者John Hyde实现了一个USB键盘过滤驱动程序,即给此程序增加了一个“拦截(Intercept)”功能来处理USB键盘的Report以实现特定的功能:当驱动程序在IRP_MJ_INTERNAL_DEVICE_CONTROL设置的完成例程从USB设备拦截到一个Get_Report_Descriptor时,拦截程序将此Descriptor中的USAGE值从“Keyboard”改为“UserDefined”,再返回给系统。
我们可以从这个例子中获得一些灵感,比如,在Win2k下,键盘是由OS独占访问的,我们可以通过这种方式使之可以让用户自由访问;我们也可以拦截其他Report_Descriptor,将部分键重新定义,以满足特殊的要求;如果你愿意再做一个用户态的程序,你还可以将你拦截到的键值传递给你的用户态程序,以实现象联想、实达等国内电脑大厂出品的那些键盘上的各种实用的功能。
二、程序的实现
Waltz Oney和John Hyde的例子已经写得很详细了,读者可以不用修改一个字节便顺利地编译生成一个过滤驱动程序。本文的目的在于使用DriverStudio组件Driverworks来实现同样的功能。
相信读者读到这篇文章时,已经对DriverStudio有了很多的了解。DriverStudio作为一个以C++为基础的“快速”驱动开发工具,它封装了基本上所有的DDK的函数,其集成在VC++中的DriverWizard,可以很方便地引导你完成设备驱动程序开发的全过程,能根据你的硬件种类自动生成设备驱动程序源代码,并提供了很多范例程序。当然,这些例子中便包含一个USB Filter驱动程序的框架。在不侵犯版权的前提下,充分利用现有共享的、免费的、授权的代码是我们的一贯作法。我们下面便以此范例为基础来作修改。
我们的目的是做一个HID小驱动程序hidusb.sys的Lower Filter,它附加在“人机接口设备” ,通过拦截USB的Get_Report_Descriptor来修改其返回值,当它发现该Descriptor的Usage 为“Keyboard”时,将其改为“UserDefined”,如此我们便可以完全控制这只键盘。具体做法是,拦截IRP_MJ_INTERNAL_DEVICE_CONTROL,并检查其IOCTL代码及URB,如果满足IOCTRL功能代码为IOCTL_INTERNAL_USB_SUBMIT_URB以及URB功能代码为URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE的条件,即上层驱动发来Get_Report_Descriptor请求时,设置一个完成例程,在这个完成例程中,我们将判断Usage的值,将Usage由“6(Keyboard)”时,将其改为“0(UserDefined)”。
打开C:\Program Files\NuMega\DriverStudio\DriverWorks\Examples\wdm\usbfilt目录(具体目录依你的DriverStudio所安装的目录不同而不同) ,再打开工程文件usbfilt.dsw,我们先看一下代码。
程序由两个类组成,一个是Driver类,一个是Device类。Driver类包括:
入口函数DriverEntry:
DECLARE_DRIVER_CLASS(UsbFilterDriver, NULL)
/////////////////////////////////////////////////////////////////////
// Driver Entry
//
NTSTATUS UsbFilterDriver::DriverEntry(PUNICODE_STRING RegistryPath)
{
T << "UsbFilterDriver::DriverEntry\n";
m_Unit = 0;
return STATUS_SUCCESS;
// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(RegistryPath);
}
AddDevice函数
NTSTATUS UsbFilterDriver::AddDevice(PDEVICE_OBJECT Pdo)
{
T << "UsbFilterDriver::AddDevice\n";
UsbFilterDevice * pFilterDevice = new (
static_cast<PCWSTR>(NULL),
FILE_DEVICE_UNKNOWN,
static_cast<PCWSTR>(NULL),
0,
DO_DIRECT_IO
)
UsbFilterDevice(Pdo, m_Unit);
if (pFilterDevice)
{
NTSTATUS status = pFilterDevice->ConstructorStatus();
if ( !NT_SUCCESS(status) )
{
T << "Failed to construct UsbFilterDevice"
<< (ULONG) m_Unit
<< " status = "
<< status
<< "\n";
delete pFilterDevice;
}
else
{
m_Unit++;
}
return status;
}
else
{
T << "Failed to allocate UsbFilterDevice"
<< (ULONG) m_Unit
<< "\n";
return STATUS_INSUFFICIENT_RESOURCES;
}
}
这两段代码基本上和自动生成的代码差不多。AddDevice的作用是构造一个过滤器的实例。
关键的代码在Device类。在这个类里,我们把过滤器插入设备栈,并拦截IRP,用自己的完成例程来实现特定的功能。
Device构造函数
UsbFilterDevice::UsbFilterDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
KWdmFilterDevice(Pdo, NULL)
{
T << "UsbFilterDevice::UsbFilterDevice\n";
// Check constructor status
if ( ! NT_SUCCESS(m_ConstructorStatus) )
{
return;
}
// Remember our unit number
m_Unit = Unit;
// initialize the USB lower device
m_Usb.Initialize(this, Pdo);
NTSTATUS status = AttachFilter(&m_Usb); //Attach the filter
if(!NT_SUCCESS(status))
{
m_ConstructorStatus = status;
return;
}
SetFilterPowerPolicy();
SetFilterPnpPolicy();
}
在DDK中,我们用IoAttachDevice将设备对象插入设备栈中。DriverStudio封装了这个函数。在DriverStudio中,其他驱动程序需要用Initialize来初始化设备对象和接口,对于过滤驱动,我们关键是需要Attachfilter将其附加在堆栈中。
对于大部分如IRP_MJ_SYSTEM_CONTROL等IRP,我们所做的只需用PassThrough(Irp)将其直接往设备栈下层传递,不需要做任何工作。这些代码我们就不一一列举了。下面的部分才是本文的关键。
我们知道,HIDUSB.SYS是使用内部IOCTRL发出URB给USB类驱动程序(USBD)读取数据的,那么,HIDUSB首先必须构造一个IRP_MJ_INTERNAL_DEVICE_CONTROL,它的IOCTL功能码为IOCTL_INTERNAL_USB_SUBMIT_URB(发出URB的内部IOCTL)。另外,因为我们要检查并修改的是USB键盘某个接口的报告描述,那么这个URB应该是URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE,如下:
NTSTATUS UsbFilterDevice::InternalDeviceControl(KIrp I)
{
T << "UsbFilterDevice::InternalDeviceControl\n";
// Pass through IOCTLs that are not submitting an URB
//不是我们感兴趣的IOCTL不要理它
if (I.IoctlCode() != IOCTL_INTERNAL_USB_SUBMIT_URB)
return DefaultPnp(I);
PURB p = I.Urb(CURRENT); // get URB pointer from IRP
//不是我们感兴趣的URB,也不要理它,
if (p->UrbHeader.Function !=
URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE)
return DefaultPnp(I);
//符合要求的IRP才被设置完成例程
return PassThrough(I, LinkTo(DeviceControlComplete), this);
}
在设置好条件以后,再来实现完成例程。所有的检查、修改等动作都是在完成例程里面完成的。
NTSTATUS UsbFilterDevice::DeviceControlComplete(KIrp I)
{
PURB p = I.Urb(CURRENT);
if(p)
{
//拦截到设备返回的描述表,
char* DescriptorBuffer = (char*)p->UrbControlDescriptorRequest.TransferBuffer;
//指向第三个字节,表示设备Usage属性的值
DescriptorBuffer += 3;
//如果值为6则改成0,6表示hid键盘,0表示未知设备
//在设备管理器里面,原来的hid兼容键盘就不复存在了,取而代之的则是hid兼容设备
if ((*DescriptorBuffer&0xff) == 6)
*DescriptorBuffer = 0;
}
return I.Status();
}
读者可以对照DriverWorks中的例子,直接替换掉(或者修改)上面这两个函数,再编译一下,便可以得到一个完整的键盘过滤器驱动程序。
其实,只要弄清楚了我们需要做些什么动作,在DriverStudio里面只需要写少量的关键代码,便可实现我们的要求,其余的大部分工作,或有范例可供参考,或有Driver Wizard自动生成。
从上面可以看出,我们只需要修改这两个函数,拦截合适的IRP,便可以在完成例程里面实现我们特定的要求。正如开头所说,我们也可以拦截其他的IRP,拦截其他的URB,或者拦截特定键盘的按键键值,将之传递到用户态,以方便实现联想、实达等随机配备的多功能键盘的功能。
三、使用INF安装驱动
在完成了驱动以后,还必须把它安装到系统里面,驱动程序才会起作用。一般来说,我们都必须为我们的驱动程序提供一个inf文件,以便于用户安装或者维护。对于新手来说,过滤驱动程序的inf或许有些棘手。所以,针对本文所描述的驱动,我们提供一个Win98下的安装范例usbkey.inf,范例中“;”后的文字是注解,以方便读者理解。
; usbkey.INF
; Installs Lower Level Filter for a HID keyboard device
; (c) Copyright 2001 SINO Co., Ltd.
;
[Version]
;”CHICAGO”表示Win9x平台
Signature="$CHICAGO$"
;键盘所属类名
Class=HID
ClassGUID={745a17a0-74d3-11d0-b6fe-00a0c90f57da}
;驱动程序提供者,此信息会显示在设备属性的“常规”页
Provider=%USBDBE%
LayoutFile=layout.inf
;显示在驱动程序文件详细资料窗口
DriverVer=11/12/2001,4.10.2222.12
;[ControlFlags]
;ExcludeFromSelect = *
;驱动程序安装目录,inf会将我们的驱动程序安装到如下目录
;记得Destinationdir后面一定要带一个“s”
[DestinationDirs]
DefaultDestDir = 10,system32\drivers
;要增加的注册表项
[ClassInstall]
Addreg=HIDClassReg
[HIDClassReg]
HKR,,,,%HID.ClassName%
HKR,,Icon,,-20
;制造商
[Manufacturer]
%USBDBE%=USBDBE
[USBDBE]
;我们所要附加过滤驱动程序的设备ID。这个ID可以从IC的规范上得来,也可以
;用hidview.exe读出,或者从注册表HKLM\Enum\hid和usb项找出
%HID.DeviceDesc% = Keypad_Inst, USB\VID_05AF&PID_0805&MI_00
;要安装的文件和需要修改的注册表项
;Install usbkey driver
[Keypad_Inst]
CopyFiles=Keypad_Inst.CopyFiles
AddReg=Keypad_Inst.AddReg
[Keypad_Inst.CopyFiles]
hidusb.sys
hidparse.sys
hidclass.sys
usbfilt.sys
[Keypad_Inst.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,"hidusb.sys"
[Keypad_Inst.HW]
AddReg=Keypad_Inst.AddReg.HW
;Lowerfilters表示是低层过滤驱动,如果是上层过滤驱动,则必须改为upperfilters
[Keypad_Inst.AddReg.HW]
HKR,,"LowerFilters",0x00010000,"usbfilt.sys"
;HID设备所需要安装的文件和注册表中需要修改的地方
;Install USBHIDDevice
[USBHIDDevice]
CopyFiles=USBHIDDevice.Copy
AddReg=USBHIDDevice.AddReg
[USBHIDDevice.Copy]
hidclass.sys
hidusb.sys
hidparse.sys
[USBHIDDevice.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,"hidusb.sys"
;以下定义需要在上面某些地方使用时替换的字符串
[strings]
USBDBE = "SINO Co., Ltd."
HID.DeviceDesc = "SINO USB MultiKeyboard"
HID.HIDDeviceDesc = "Human Interface Devices"
HID.DefaultDevice = "HID Default Device"
HID.ClassName = "Human Input Devices (HID)"
HID.SvcDesc = "Microsoft HID Class Driver"
其实最简单的写inf的方式,是找一些类似设备的inf文件或范例来修改。在不侵权的前提下,充分利用现有资源是我们的一贯原则。
驱动程序无法使用怎么办
驱动开发,顾名思义,就是软程序的编程开发应用。应用开发,就是根据你所研究的领域进行有选择的硬件开发、以计算机技术为基础,并且软硬件可裁剪,适用于应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。它一般由嵌入式微处理器、外围硬件设备、嵌入式操作系统以及用 户的应用程序等四个部分组成,用于实现对其他设备的控制、监视或管理等功能。包括硬件和软件两部分。硬件包括处理器/微处理器、存储器及外设器件和I/O端口、图形控制器等。软件部分包括操作系统软件(OS)(要求实时和多任务操作)和应用程序编程。嵌入式系统中的软件一般都固化在存储器芯片或单片机本身中,而不是存贮于磁盘等载体中。
嵌入式系统本身不具备自举开发能力,即使设计完成以后用户通常也是不能对其中的程序功能进行修改的,必须有一套开发工具和环境才能进行开发。推荐北京精仪达盛、亚龙、天煌等品牌的硬件产品,如系统开发板、DSP、ARM等。
下面说你工作时要用稿的知识
1.处理器技术 1)通用处理器 2)单用途处理器 3)专用处理器
2.IC技术 1)全定制/VLSI 2)半定制ASIC 3)可编程ASIC
3.设计/验证技术
嵌入式系统的设计技术主要包括硬件设计技术和软件设计技术两大类。硬件设计领域的技术主要包括芯片级设计技术和电路板级设计技术芯片级设计技术的核心是编译/综合、库/IP、测试/验证。编译/综合技术使设计者用抽象的方式描述所需的功能,并自动分析和插入实现细节。库/IP技术将预先设计好的低抽象级实现用于高级。
当然、一个出色的职业经理,除了商务,这些技术方面,也是必须要懂的。
希望以上对你有所启示,不懂了可以留言、。
驱动开发和应用开发的前景?你想问的是学好这些需要哪些基本功力是吧?真正的技术是积累出来的,多看专业书。等你学习到一定阶段你就会发现什么驱动,什么应用都是雕虫小技而已,现在慢慢学,不用急。多留心就好
我问你你学习这一系列的东西是为了什么?开公司还是当老师 ?还是没事自己搞研发?现在时代的产品要求的是全方面的人才,艺多不压身,你着重往JAVA方面发展吧。但是C也是必须的,知道吧小弟,出来了就是工程师,想要比别人优秀,就要让自己的水平在你所在的领域游刃有余,要让你工作的地方 没你不行。至于怎样达到这个水平,哪是你自己的事了。
嵌入式驱动开发:你需要掌握的六大知识领域
驱动程序无法使用。首先确认之前是否存在这个问题。如果该设备之前运行是正常,突然出现驱动程序无法使用。可以用以下方法处理:操作环境:华硕天选FA506IV、Windows10、设备管理器。
1、打开开始菜单,进入“设备管理器”。
2、然后在其中双击存在问题的设备。
3、最后在驱动程序下选择“回退驱动程序”即可。
驱动开发的原理与步骤:
1,明白你手头的硬件工作原理,包括处理器架构的知识,还有外设控制器的datasheet为必读之物;驱动程序的开发工作是很具挑战性的,因为必须配合着硬件与软件上相当明确与高级的平台技术。
2,假如你们要开发的整个系统是裸机程序,那你要开发的驱动程序就是一套和硬件打交道的函数库;但是假如你们计划在产品中使用一个操作系统。
那开发驱动之前就需要熟悉这个操作系统的相关内部操作原理,因为你写的是驱动程序需要很好的“镶嵌”到这个操作系统的环境中去。
嵌入式驱动开发是一个深度而广泛的领域,但有几个核心领域是你必须攻克的。从操作系统框架到硬件细节,这里是你需要涉猎的领域。 嵌入式操作系统驱动框架每个操作系统都有其独特的架构。了解驱动程序在系统中的地位,以及如何构建它们,是开发嵌入式驱动的关键。
总线知识PCI和USB总线只是冰山一角。了解不同总线的工作原理,将帮助你更好地设计、调试和优化驱动。
芯片级别的知识驱动开发的核心是对设备寄存器的配置、CPU与设备的通信,以及如何处理各种命令。深入了解芯片的工作原理,将让你站在一个更高的层次上看待问题。
CPU体系结构的洞察为了写出高效、稳定的驱动,对所使用的CPU体系结构有深入的理解是必不可少的。
编程语言精粹C和汇编语言是驱动开发的核心。虽然C++在某些场合可能会派上用场,但C和汇编仍然是最主要的工具。
内核调试的魔法深入理解内核调试技术,如Linux内核调试,将帮助你更快地定位和解决问题,使你的驱动更加稳健。
今天关于“驱动程序开发原理”的讨论就到这里了。希望通过今天的讲解,您能对这个主题有更深入的理解。如果您有任何问题或需要进一步的信息,请随时告诉我。我将竭诚为您服务。