白话通过系统来访问硬件
对于一个产品,它有连接若干种硬件,包括gpio,串行口,usb 等, 我们怎么访问它? 通过系统接口, 系统程序已经为我们提供了驱动. 系统接口是啥样子的? 通常是一个文件, 当然这是一种比较特殊的文件. 我们通过这种访问文件的方式 来访问硬件设备. 只要知道这个文件的名称就可以了, 当然,也可能需要知道它的控制属性,用ioctl 来改变 它的一些行为.
有一种设备是固定的, 例如串行口设备 /dev/ttyS0 等等. 开机后,这个设备文件就在那, 你可以按照默认的属性读写它.
还有一种设备, 其设备名不一定以/dev 开头, 例如控制器上的某个引脚吧. 我们发命令把它拉高或拉低. 如果用汇编,大概就是写个0或1到某个寄存器bit 但是有了系统,我们应用程序就没有权利直接访问外设了, 而且也没有人再去记这个引脚对应什么地址的第几bit位. 怎么操作呢? 这个引脚,应该会对应到某个文件上, 向这个文件写1就相当于拉高, 写0就是拉低. 所以你不需要记地址了,而需要记文件路径. 如果在命令行下操作, echo 一个数到设备文件,就相当于写数到引脚了.
如果用程序怎样实现呢.用程序用手工是一样的. 我们以M6g2c 来举例说明, 目的: 把68号引脚置位为低. 其它的计算机系统可不一定这样. M6g2c 的引脚是多功能的, 所以 第一步要把68号引脚设为io引脚. 怎么告诉系统呢? 向"/sys/class/gpio/export" 这个文件写 "68" 字符串就可以了.
且慢: "/sys/class/gpio/export" 这是个什么东西? 这是个系统文件, linux 下一切皆文件的思想, 你想跟系统打交道,就通过文件了. 你只要想把那个引脚设为io功能而不是其它的专有功能,就向它写引脚号就好了.
第二步: 告诉系统这个引脚(68号引脚)要用作输出功能,而不是输入功能,怎么做呢? 你需要向 "/sys/class/gpio/gpio68/direction" 文件写入 "out" 字符串.
且慢: 路径中的gpio68 跟68号引脚是什么关系? 一一对应吗? 58就对应gpio58? 对,就是这么一一对应的, 只不过当你向"/sys/class/gpio/export 写了"58" 字符串时, 系统就给你创建了/sys/class/gpio/gpio58 目录,里边包含着若干文件. 看起来还是挺好玩的,嗯! 跟系统对话, 用字符串!
第三步: 准备工作都已具备, 把数值写到68号引脚上,怎么做呢. 向"/sys/class/gpio/gpio68/value" 写数值0或1. 还真的是一切皆文件, 呵呵!
手敲就是echo, cat 程序就是fopen,fread,fwrite.
访问串行口,访问i2c,访问lcd(frame buffer), 访问spi, 大体上也都是这样的操作过程. 具体的文件名称是什么,以及如何控制属性等就需要具体的样例代码了,此处忽略. 大家都用过打印机吧, 对,把文件丢给打印机,它就给我们打印了, 等价于echo 文件内容 到打印机设备句柄, 不过用的是打印机默认属性. 打印机的属性肯定通过另外的文件或方式 设置,此处忽略,反正道理是相通的,可以想象一下. 这样就不怕和硬件打交道了.
且慢: 新到了一个设备,不能工作,没有驱动. 要让它工作起来. 啊,要写驱动啊? 那厂家 是干什么吃的, 先别自己写,没有资料你也写不成. 无驱不动,厂家肯定会有的. 你就是厂家, 不是新到了一个设备,而是把这个芯片挂到系统上, 那要看看了,是字符型设备,usb设备还是其它类型设备,通过什么总线挂的. 把芯片资料拿过来, 估计有人已经做过了吧,先查一下是不是可以借鉴. 路漫漫兮修远兮...
|