LINUX驱动程序初体验

原创 2007年10月01日 22:21:00
 严格来说已经不算第一次了 大三的时候刚开始学嵌入式LINUX  就写过驱动 不过过了这么久没弄 基本忘光了 从头开始. 这篇文章不讲驱动的框架,而是记录我在编写第一个驱动中遇到的问题.

问题一: 到底哪个先执行

    这是一个来自运算符优先级的诡异的问题.是在编写用户空间代码时遇到的.还是先上问题代码:

这段代码的意图在于打开我编写的设备,并开启设备的异步通知机制; 不过在执行write系统调用的时候,用于测试的字符串"s"被打印在了控制台上. ..... 这真是个让人困惑的问题. 这个自符串(虽然只有一个字符的长度)本来是写向设备的.是如何阴差阳错到了控制台上呢...  检查文件描述符fd的值,发现居然是0 .0 代表了控制台设备 是每个进程默认打开的设备 难怪乎了. 可明明设备打开是成功,fd为什么变成了0呢.  问题就出在 if(fd = open("/dev/mod",O_RDWR) < 0) 上面.  原以为赋值运算符的优先级高于<运算 一查才发现原来是倒过来的 所以<运算先被执行了 结果为假 也就是0  这个值又被赋给了 fd......  真相大白...

这个错误虽然是因为错误的估计了运算符的优先级而引起的 却也暴露了用C这种介于高级与低级之间的语言进行编程时给程序员带来的问题--- 数据结构类型太少.  在JAVA之下,标识文件的数据结构类型与标识真假的boolean类型代表两个完全不同的类型 相互赋值时会发生错误 因此象这类错误会在编译器就被发现而不至于引起更让人困惑现象.C语言里, 文件句柄,BOOL值都是用整型值来表示 相互赋值在语法上没有任何问题 于是上面的问题就出现了...

问题二:返回值太重要 重要的可以决定程序是否崩溃

    相对与前一个 这个问题隐藏得更深(至少对初学者来说是这样)  问题代码在这里:

static int mobile_open(struct inode * inode,struct file * filp)
{
    MOD_INC_USE_COUNT;
    
    
return 1;
}

    看看吧 多么简单的代码 就两句;作为一个驱动的 open 方法的实现,这个函数仅仅增加引用计数值,然后返回.可就是两句代码. 引得其后在用户空间里的代码在调用fcntl系统调用设置设备文件属主的时候出现了segmentation fault .

 按照LINUX对驱动程序方法的定义,方法的返回值有重大的意味. 他标志着这次方法的调用是否成功.而我在写这个方法的时候,想当然的以为1代表打开成功. 就给返回了. 而事实恰恰是LINUX规定OPEN方法返回0才代表万事OK.于是,一方面内核认为这是一次失败的设备打开操作,而另一方面却返回给用户空间的OPEN系统调用一个合法的文件描述符... 所以在FCNTL系统调用作用与这个文件描述符的时候,将访问一个没有为其分配空间的数据结构,产生非法访问的错误...

    将return 1改为return 0.OK.

问题三: 她和她,WHICH IS YOUR RIGHT ONE?

    LINUX最为迷惑开发者之一的地方在与起头文件. 你可以在很多地方看到有include字样的目录. 而GCC会有一个默认的寻找头文件的目录 .在本例中,为了编译出内核一部分的MODULE,必须使用内核代码中的头文件目录.这很简单,我用-I选项就能轻松搞定. 不过,别忘了 ,GCC默认的头文件搜索目录始终默默的存在着, 当我们自己指定的目录出现问题时,这个我们并不注意到的目录里的文件会是我们的恶梦...

    本例中,当使用ARM-LINUX-GCC 交叉编译器为手机编译MODULE时,出现类似下面这样的错误:

In file included   from  ...................................................... xxx.h

   from.........................................................yyy.h

  from...........................................................zzz.h

Symbol  ABC redefined....

仔细观察这些问题头文件所在的路径,你会惊讶的发现他们存在于我们指定编译器搜索的路径之外.这就是默认的路径------两套不同的头文件体系交叉被编译器默不作声的交叉使用了. 试想我们想要INCLUDE的是在A目录下的文件A.H.而在B目录下存在一个同名的A.H 并被错误的INCLUDE近来...这会是什么后果...乱套了... 

    可为什么会发生这种状况呢. 我们用-I/usr/src/arm-linux-src/include选项作为头文件的目录,可头文件还会包含其他头文件,举个例子,这个目录下的ptracr.h会有这样一行 #include <asm/ptrace.h>意思是:编译器,你给我把//usr/src/arm-linux-src/include/asm下的ptrace.H给我包含进来 编译器一找,发现没有asm这个目录,这个时候他并不报错,而是在默认的目录里继续寻找是否有个asm目录,他下面是否有个 ptrace.h  一找,哟 还真有 就是他了...本来一个是给用户程序用的 ,另一个是给内核程序用的 就这么混用到了一起 ....

      那那个惹出问题的ptrace.h 文件到底该在哪呢 其实asm是一个包含具体体系结构代码的目录,他在/usr/src/arm-linux-src/include以这种形式存在:

   asm-arm , asm-x86, asm-mips......

    为了编译出给ARM体系结构的代码,asm必须指向的是 asm-arm目录.这个好解决:ln -s ./asm-arm asm 这步昨晚后,所有编译器出错信息全部消失...

 

 

安装Linux mint12初体验(1)

作者:renkai611919 转自:http://blog.csdn.net/renkai611919/article/details/7251546
  • whw8007
  • whw8007
  • 2014年09月09日 16:30
  • 371

Linux下驱动程序的特点——基础篇

Linux通过设备驱动程序为应用程序提供了统一抽象的接口,从而隐藏了大量不同设备之间的区别和细节,在Linux中对硬件设备的操作和通常的文件一样,利用标准的文件操作可以对设备上进行打开、关闭、读取或者...
  • ttfwind
  • ttfwind
  • 2006年03月02日 17:49
  • 2286

LINUX字符设备驱动程序原理总结

LINUX字符设备驱动程序原理总结  一)设备的输入/输出原理通常,任何数据都必须通过内核空间才能到达应用程序的缓冲上。例如:对一个设备的读操作会引起数据被至少复制两遍,一遍是将内容复制到内核缓冲中,...
  • jackred
  • jackred
  • 2010年07月08日 10:12
  • 574

firewalld-cmd初体验

firewalld基本命令[root@localhost ~]# firewall-cmd –state ##查看firewalld状态 [root@localhost ~]# ...
  • Error_404notFound
  • Error_404notFound
  • 2017年06月08日 22:39
  • 255

程序员初体验

故事开头先介绍下自己吧(别介绍了,没人看)还是要有点礼貌吧,博主大三刚刚上完的一个普通全日制本科学生,,博客这个东西开始一直认为是那些有逼格的大牛们写的,像我们这种小老弟负责阅读转载就行,(那你为什么...
  • wangzili1995
  • wangzili1995
  • 2017年07月29日 22:12
  • 114

intellj idea 初体验

转idea 遇到了一个小问题就处理了两天时间,不过好在 这两天工作上也没什么事。 问题是这样子的,新检出一个项目之后部署到tomcat之后发现tomcat启动不报错,server和tomcat lo...
  • streetlight8023
  • streetlight8023
  • 2016年07月26日 18:07
  • 152

初学Linux驱动编译

初学驱动编译,各种不懂啊,记得有些东西曾经看到过有印象,但是还是不清晰,原因就是基础不牢固,动手太少。内容多不要紧,重复是最好的老师!坚持能进步!记录一下今天的收获。 1、内核的编译 分为为当前使用的...
  • u011732167
  • u011732167
  • 2016年07月23日 21:03
  • 859

手把手教你写第一个Linux驱动程序

说到写第一个linux内核驱动程序,再简单不过了。以前也写过,这次将做一个图形化的整理。我这里以我的开发环境tiny4412为主,我将在这上面写第一个驱动程序。首先,我在driver/目录下创建yan...
  • morixinguan
  • morixinguan
  • 2017年01月19日 22:57
  • 980

Linux下第一个驱动程序

因为在Ubuntu环境下写的文章和做的实验,没有安装linux下比较好用的截图工具,所以没有附带太多截屏,还望海涵,不过该描述的都到位了。          曾经还一直处于应用程序开发的我,以为驱...
  • dreambegin
  • dreambegin
  • 2011年10月21日 13:35
  • 5062

Linux高级字符设备驱动程序

设备ioctl控制 大部分驱动除了需要具备读写设备的能力外,还需要具备对硬件控制的能力。例如,要求硬件设备报告错误信息,改变波特率,这些操作常常通过ioctl方法来实现。 用户使用方法:在用户空间...
  • qq_27522735
  • qq_27522735
  • 2016年12月26日 16:38
  • 396
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LINUX驱动程序初体验
举报原因:
原因补充:

(最多只允许输入30个字)