正点原子【第四期】手把手教你学 Linux之驱动开发篇

ARM裸机开发,基本就是使能对应时钟,设置管脚复用,设置高低电平。
对于linux则是使用linux的各种框架实现功能开发。

MCU对端口操作,也有固定流程。
使能时钟
设置IO复用
设置属性,比如输入还是输出
输出什么,高低电平等等。
而写linux时,这些功能都是直接调用。
linux提供了GPIO,I2C,SPI等等的操作函数,设置属性,直接调用,给出读写的数据,地址等等。
但是写的时候,需要满足一个驱动框架。
最终表现为/dev/xxx文件。
对其就有打开,关闭,读写等等。上层应用就是使用这些操作来操作设备。
--------------------------------------------------------------------

字符设备是不定长的字符(流)读写。
块设备不按指定的顺序访问,基本绝大多数存储设备都属于此。
(弹幕中一个很有意思的看法,分类应该是有区分作用,这种可以同时属于两个的应该是属性)
--------------------------------------------------------------------------
字符设备开发:
为了完成开发,需要开发驱动 和 一个简单的应用。这样才能测试。
单片机中,应用驱动都杂糅在一起。但是linux中是完全分开的。
-----------
在虚拟的内存中,用户空间是0-3G,内核空间是3G-4G。
应用程序想访问内核资源,只有三种方法,系统调用,异常和陷入。后面两个有时也叫硬件中断和软件中断。其中主要就是用系统调用。
而系统调用,也不是直接通过调用,而是通过语言自带的API函数来进行系统调用。比如POSIX,API和C的库函数等。
比如UNIX类操作系统,最长用的一个编程接口就是POSIX。
比如,程序使用open函数,打开一个设备文件,就是通过C库调用。
------------------
应用里调用C库中的open函数,这个open函数又调用系统中的一个可以实现文件打开的函数。这样在系统和编程接口中间,加了一层C库封装,可以实现一致的编程体验。
----------------------------------
比如:

__NR_这些就是一些系统调用函数,那些数字就是系统调用号。
实际的调用方式是“陷入”,也就是软中断,进入内核,然后使用系统调用号来调用对应的功能。
----------------------------------------------
一切皆文件。应用程序调用open函数打开一个设备。比如LED。
对这个文件,有read和write操作。
用write 函数向/dev/led写数据。比如写1表示打开,写0表示关闭。
关闭设备,则是使用close函数。
--------------------------------------------------
编写驱动的时候,需要编写驱动对应的open,close,write,read函数。
有一个文件file_operations结构体描述了对于字符设备的所有操作集合,不过未必需要全部实现,常用的就是上面几个。
驱动最终是被应用调用。
------------------------------------------------------------
字符设备驱动框架:
file_operations结构体 在 /include/linux/fs.h中定义。

可以看到llseek,read,write等指针。