LINUX驱动程序初体验

 严格来说已经不算第一次了 大三的时候刚开始学嵌入式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 这步昨晚后,所有编译器出错信息全部消失...

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个问题似乎是一个十六进制的字符串,如果它代表了一个问题,而且假设这个问题是关于初次体验Linux的话,我的回答是: Linux是一个开源的操作系统,它比Windows更加灵活和定制化,并且支持各种编程语言和开发环境。初次体验Linux可能需要适应一些不同的命令行操作,但是随着熟悉和学习,它也可以成为非常好用的操作系统。推荐使用一些常见的Linux发行版,例如Ubuntu、Fedora和Debian等等,它们很容易上手并且有丰富的社区资源。希望这个回答可以帮到您! ### 回答2: 作为一名AI语音助手,我没有亲身经历各种操作系统的安装和使用,但是我可以根据用户的需求提供适当的帮助和建议,为他们解决问题。 不过笔者作为一个Linux爱好者,对于头歌Linux这款国产Linux操作系统也有自己的初体验。 头歌Linux定位为面向桌面用户的轻量级Linux系统,它采用了简洁的深色主题和扁平化的设计,整体视觉效果十分舒适。在安装方面,头歌Linux提供了简易的安装向导,支持自动分区和手动分区两种方式,给使用者更多的选择。 初次使用头歌Linux,不可避免地会遇到一些操作上的困惑。例如如何打开终端,如何安装软件等问题。对于这些问题,我们可以通过一些常见的Linux命令来进行操作。比如通过Ctrl+Alt+T快捷键打开终端,通过sudo apt-get install软件名来安装软件等。 头歌Linux内置了一些常用的软件,例如Firefox浏览器、LibreOffice办公套件、GIMP图片编辑软件等。同时还支持中文输入法,对于国内用户来说极具友好性。 总之,对于初学者来说,头歌Linux作为一款国产轻量级Linux系统,界面简洁,易于上手,支持中文输入,是不错的选择。笔者也期待在未来的使用中,逐渐发现头歌Linux的更多优点。 ### 回答3: 在我看来,头歌Linux初体验第一关是一次令人兴奋的冒险之旅。它使我第一次尝试使用开源操作系统,学习了解Linux的基本概念和工具。在这个过程中,我发现了许多新鲜事物,以及它们如何构成一个完整的操作系统。 在进行第一步之前,我首先下载了头歌Linux镜像,然后将它写入了一个USB驱动器。这个过程非常简单,并且获取镜像的速度也很快速。一旦我准备好启动我的电脑,我准备好了所有需要运行头歌Linux的基本规则,包括了解Linux的基本命令、文件系统和Web浏览器等。刚开始的时候,我遇到了一些阻碍,但是通过查阅使用指南和网上资源,我很快就克服了这些难点。 在我进入操作系统之前,我首先看了一遍头歌Linux的欢迎页,这里介绍了该系统的主要功能及其提供的资源。这真的让我比较深刻的了解了Linux的优点和弱点。进入头歌Linux的全屏界面后,我花了一些时间来探索它的工具栏、文件管理器和应用程序菜单等。虽然与Windows有所不同,但它的界面对我而言也不算太过复杂。 最有趣的部分是,我使用头歌Linux体验了诸如Firefox浏览器、OpenOffice等流行应用程序。这也让我对Linux能够应对日常工作和生活所需有了更好的了解。同时,我还学习到了如何安装和卸载应用程序,以及如何使用终端窗口进行各种操作。虽然我还需要继续深入学习,但是通过完成头歌Linux初体验第一关,我确信我已经获得了更多的启示,并且对Linux的学习路线有了更好的规划。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值