第一篇博客,忆苦思甜下先,当然,我尽量长话短说,但说来话长倒也无妨......这是我研究生阶段写的第一个Linux驱动,一入Linux深似海,从此Windows是路人。那是2009年冬天的第一场雪,王老师兴冲冲地拿着一块板卡给我说,你不是会Linux吗?三个月,把它的Linux驱动写出来。而我此时所谓的“Linux”,也就是在虚拟机下装个RedHat,上上网听听歌,看看电影装装X。对linux内核一点概念都没有,更不用说驱动了,于是天天上网查资料,把师兄的新书都翻蓬松了,最后参照着一堆模板写下了人生的第一个驱动,写完了发现都不知道怎么编译......最后,当系统第一次显示驱动加载成功,打印出我的设备信息时,我高兴得一拳狠狠砸在在桌子上,把身边的同学都吓住了。其实这个时候驱动也就仅仅能加载成功而已,设备的很多功能都没实现,但是这个时候的成就感,比日后实现了驱动的全部功能与用户态应用程序时,都强烈得多。现在想来,真是感谢王老师对我的宏观指导点拨、胡师兄陪我的微观编译调试、以及黄师兄借我的那本《Linux设备驱动开发详解》。

好了,正文开始,驱动的开发环境是Linux2.4.18与实时补丁Rtai-24.1.11,硬件平台是i386,就是自己的PC机啦。最开始接到任务的时候,完全不知道干嘛,如今看来,就是要写一个PCI2040 PCI-DSP桥接卡的驱动,驱动包括设备与主机连接的PCI部分以及与板载DSP连接的HPI部分。

PCI驱动与其他驱动不同的地方主要在于PCI标准规定了每个PCI设备都有至少256字节的地址空间,其中前64字节是标准化的,其余字节是设备相关的。前64字节标准配置寄存器如下所示。驱动初始化时的很多步骤都会用到这个配置空间。

首先自然要定义驱动的入口函数和出口函数,

module_init(hpi_init_module);
    module_exit(hpi_cleanup_module);

既然我们是要编写pci驱动,当然要定义一个pci_driver啦,具体实现如下

static struct pci_driver driver_details __devinitdata=
  {
        .name     =  DRV_NAME,
        .id_table =  compatible_ids,
        .probe    =  pci_probe,
        .remove   =  __devexit_p(pci_remove),
  };

这里我们就第一次用到了pci配置空间了,因为系统是根据id_table这一栏来识别PCI设备的:id_table的包含数个pci_device_id,每个pci_device_id标明了对应PCI设备的制造商ID和设备ID,同样,设备上的配置空间的前四个字节包含了制造商ID和设备ID,当驱动存在一个ID与PCI设备配置空间ID相匹配时,设备驱动才会与硬件关联起来。根据PCI2040的datasheet,我定义的pci_device_id如下:

#define VENDOR_ID 0x104c

#define DEVICE_ID 0xac60

static struct pci_device_id compatible_ids [] __devinitdata=
{
    {VENDOR_ID,DEVICE_ID,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
    {0,}
};

hpi_init_module()基本不需要干什么事情,只要调用函数pci_module_init(&driver_details)就可以了。这样,当系统检测到PCI设备时,会自动调用driver_details中的probe函数,也就是我们自己定义的pci_probe。驱动初始化的主要工作都在这个函数中进行。下面说明了一般PCI设备驱动需要的初始化工作,设备相关部分已被略去。

int __devinit pci_probe(struct pci_dev *dev, const struct pci_device_id * id)

{

......
//使能PCI设备

err=pci_enable_device(dev);
......
//申请PCI资源空间
    err=pci_request_regions(dev, data->name);
......

//读取PCI设备的IO区域的首地址,每个PCI设备最多可有六个IO区域,第i个区域的首地址在PCI配置空间的0x10+(4*i)地址中,i=0~5。

start=pci_resource_start(dev, i);

//读取PCI设备的IO区域的尾地址,首尾地址相减后加一即可得到这篇IO区域的长度,长度在ioremap时会用到
    end=pci_resource_end(dev, i);

//读取PCI设备的IO区域的标识,主要看是否是IO区域还是MEM区域
    flags=pci_resource_flags(dev, i);
    if(IS_VALID_PCI_RESOURCE(flags, IORESOURCE_MEM)){
    data->mmio_addr_csr=ioremap(start, end-start+1);

}

//设备取得对PCI总线的控制   
    pci_set_master(dev);
......
//把设备的私有信息放入系统分配的PCI设备地址中
pci_set_drvdata(dev, data);

......
}

至此,本驱动的PCI部分已经完成,系统可以识别我们的PCI设备,但是如何与板载的DSP通信呢?我们还需要在pci_probe中完成对HPI部分的初始化。

实时linux下的PCI驱动开发(上)相关推荐

  1. Linux下LED设备驱动开发(LED灯实现闪烁)

    文章目录 一.配置连接说明 二.更新设备树 (1)将led灯引脚添加到pinctrl子系统 (2)设备树中添加LDE灯的设备树节点 (3)编译更新设备树 三.驱动开发与测试 (1)编写设备驱动代码 ( ...

  2. Linux下按键设备驱动开发以及对中断的上半部分和下半部分详细介绍

    文章目录 一.编写并且加载设备树插件 (1)检测管脚是否占用 (2)添加设备树插件 (3)加载设备树插件 二.中断相关函数 (1)request_irq中断注册函数 (2)free_irq中断注销函数 ...

  3. Linux下的硬件驱动——USB设备配置以及开发

    Linux下的硬件驱动--USB设备(上)(驱动配置部分) USB设备越来越多,而Linux在硬件配置上仍然没有做到完全即插即用,对于Linux怎样配置和使用他们,也越来越成为困扰我们的一大问题.本文 ...

  4. linux网卡驱动开发视频,Linux下网卡驱动程序的开发.doc

    Linux下网卡驱动程序的开发 论文题目:Linux下网卡驱动程序的开发 专 业: 年 级: 学生学号: 学生姓名: 指导教师: 完成时间: Linux下网卡驱动程序的开发 八年经验 专业指导毕业设计 ...

  5. linux上 arm开发环境搭建,详解 LINUX下QT For ARM开发环境搭建过程

    LINUX下QT For ARM开发环境搭建过程是本文介绍的内容,不多说,先来看内容.在PC上,我们需要得到两个版本的Qt,分别是:Qt-4.5.2和QtEmbedded-4.5.2-arm.前者包括 ...

  6. arm+linux+usb驱动开发,Linux+ARM下的USB驱动开发

    驱动开发 嵌入式软件应用 文章编号:l帅8-0570(2∞8)08吨-∞86一m2 中文核心期刊'微计算机信息)(嵌入式与soc)2008年第24卷第8-2期 Linux+ARM下的USB驱动开发 U ...

  7. linux 下usb驱动开发,LINUX_ARM下的USB驱动开发.pdf

    LINUX_ARM下的USB驱动开发 CN 431258 / TP 计算机工程与科学 2006年第 28卷第 3期 ISSN 1007130X COM PU TER EN GIN EER IN G & ...

  8. Linux下的硬件驱动——USB设备(下)

    Linux下的硬件驱动--USB设备(下)(驱动开发部分) 文档选项 打印本页 将此页作为电子邮件发送 未显示需要 JavaScript 的文档选项 级别: 初级 赵明, 联想软件设计中心嵌入式研发处 ...

  9. Linux下的硬件驱动——USB设备

    想起当初对于破安卓手机,挂在系统上可是费了好些劲,今偶遇USB驱动开发,收集备用,哪天一生气,说不定也写一个linux下的手机驱动,类似于91手机助手的,也不用配置了. Linux下的硬件驱动--US ...

最新文章

  1. k近邻算法api初步使用
  2. 用Three.js写h5小游戏-3d飞机大战
  3. Linux Top 命令解析 比较详细
  4. 拒绝了对对象 'XXX' (数据库 'XXX',架构 'dbo')的 SELECT 权限
  5. CSS3实战开发:使用CSS3实现photoshop的过滤效果
  6. joblib多线程、多进程学习案例(一)——一步步写多进程任务
  7. Linux创建anaconda-navigator快捷图标并固定在dock上
  8. ERROR: “System.Web.Mvc.Controller.File(string, string, string)”是一个“方法”
  9. mongodb副本集维护
  10. 搞副业,你离不开这个工具!
  11. vuex的购物车效果 index.js
  12. java编程手册_Java编程手册
  13. 手把手式介绍 ADNI 影像数据下载
  14. 基于MFCC参数的元音识别
  15. mac拷贝图片window打不开
  16. ebtables规则arpreply
  17. 一个人在家简单吃点小火锅,搭配点小海鲜
  18. mosquitto简介和使用
  19. 《中国高等教育学历认证报告》申请中,添加高等学历认证对话框中信息填写完后提示“信息有误”
  20. 解读通往8K/3D VR直播之路

热门文章

  1. 写毕业论文常用网站(本人常用)
  2. Ahmedabad公司的LiFi技术为Nadabet提供互联网接入能力
  3. python 进度条插件原理
  4. win7系统使用经验
  5. 中级java笔试题_Java中级面试题合集
  6. 射频模块无线收发芯片
  7. 偷偷告诉你四款好玩实用的电脑软件让你嗨翻天
  8. 域AD策略屏蔽USB驱动
  9. java的thread类_thread 类详解
  10. 单应性矩阵的求解过程及应用