IIC驱动
Linux之IIC驱动
一、IIC接口下的24C02 驱动分析
1、I2C通信介绍
它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据,是一个多主机的半双工通信方式
每个挂接在总线上的器件都有个唯一的地址
位速在标准模式下可达 100kbit/s,在快速模式下可达400kbit/s,在高速模式下可待3.4Mbit/s。
2、I2C总线系统结构,如下所示
其中SCL时钟线的频率由主机提供,且从机不能主动来引起数据传输,必须等待主机先发信号才行
两个或多个主机同时发起数据传输时,可以通过冲突检测和仲裁来防止数据被破坏。
3、I2C时序介绍
1)空闲状态
当总线上的SDA和SCL两条信号线同时处于高电平,便是空闲状态,如上面的硬件图所示,当我们不传输数据时, SDA和SCL被上拉电阻拉高,即进入空闲状态
2)起始信号
当SCL为高期间,SDA由高到低的跳变;便是总线的启动信号,只能由主机发起,且在空闲状态下才能启动该信号,如下图所示:
3)停止信号
当SCL为高期间,SDA由低到高的跳变;便是总线的停止信号,表示数据已传输完成,如下图所示:
4)传输数据格式
当发了起始信号 ...
DM9000C网卡移植
DM9000C网卡移植
一、DM9000C原理图
如下图所示:
#:表示低电平有效
SD0~15: 16位数据线,有CMD引脚决定访问类型
CMD: 命令线,当CMD为高,表示SD 传输的是数据,CMD为低表示传输的是地址
INT: 中断引脚,接在2440的GPF7脚上
IOR#: 读引脚,接在2440的nOE脚上
IOW#: 写引脚,接在2440的nWE脚上
CS#: 片选,放在2440的bank4的片选上面
1、2440的bank4地址区间
bank4的区间位于: 0X20000000~0X28000000,当我们访问这个区间的地址,内存控制器便会使能网卡DM9000C的使能脚,所以我们的DM9000C的io基地址=0X20000000
其中DM9000C的CMD引脚接在bank4的LADDR2上面,所以会有以下情况出现:
当在地址0X2000 0000上读写数据时,表示读写的数据是DM9000C的地址
访问的地址0X2000 0004上读写数据时,表示读写的数据是DM9000C的数据
2、DM9000C收 ...
网卡驱动程序
网卡驱动程序
一、网卡驱动程序框架
相关驱动特点
字符设备驱动
设置主设备号
填充file_operations结构体
用register_chrdev(主设备号,name,file_operations结构体)注册驱动
入口函数
出口函数
块符设备驱动
分配geadisk结构体(利用alloc_disk函数)
设置
构造队列queue=blk_init_queue(处理队列的函数)
其他属性(主设备号、容量)
注册geadisk结构体(利用add_disk函数)
上述字符设备驱动和块符设备驱动的共同特点:
都有设备节点
字符设备需要先open、块设备需要先格式化然后挂接(mount)
网卡驱动
不需要打开某设备,直接使用socket即可编程
网卡的驱动与硬件相关,主要是负责收发网络的数据包,它将上层协议传递下来的数据包以特定的媒介访问控制方式进行发送, 并将接收到的数据包传递给上层协议。
网卡设备与字符设备和块设备不同, 网络设备并不对应于**/dev目录下的文件,不过会存放在/sys/class/net**目录下
Linux网络设备驱动的4层模 ...
快速排序
描述:
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序 的平均时间复杂度为O(NlogN),是冒泡排序的一种改进版。
方法:快速排序主要采用“二分”的思想,步骤如下:
设置两个变量i、j,排序开始的时候:i=0,j=n-1;
2)待排序数组的第一个数组值s[0]作为比较值,首先保存到temp中,即temp=s[0];
3)然后j-- ,向前搜索,找到小于temp后,因为s[i]的值保存在temp中,所以直接赋值,s[i]=s[j]
4)然后i++,向后搜索,找到大于temp后,因为s[j]的值保存在第2步的s[i]中,所以直接赋值,s[j]=s[i],然后j–,避免死循环
5)重复第3、4步,直到i=j,最后将temp值返回s[i]中
然后采用“二分”的思想,以i为分界线,拆分成两个数组 s[0,i-1]、s[i+1,n-1]又开始排序
如下图,以数组 6 4 7 1 2为例:
代码如下:
123456789101 ...
输入子系统
输入子系统
一、系统分析
1.输入子系统简介
同样的输入子系统也需要输入驱动的框架,好来辨认应用程序要打开的是哪个输入驱动
比如: 鼠标、键盘、游戏手柄等等这些都属于输入设备;这些输入设备的驱动都是通过输入子系统来实现的(当然,这些设备也依赖于usb子系统)
这些输入设备都各有不同,那么输入子系统也就只能实现他们的共性,差异性则由设备驱动来实现。差异性又体现在哪里?
最直观的就表现在这些设备功能上的不同了。对于我们写驱动的人来说在设备驱动中就只要使用输入子系统提供的工具(也就是函数)来完成这些“差异”就行了,其他的则是输入子系统的工作。这个思想不仅存在于输入子系统,其他子系统也是一样(比如:usb子系统、video子系统等)
所以我们先来分析下输入子系统input.c的代码,然后怎么来使用输入子系统(在内核中以input来形容输入子系统)
2.输入子系统初始化分析
打开input.c,位于内核deivers/input,有以下这么两段:
12subsys_initcall(input_init); //修饰入口函数module_exit(input_exit); //修饰出 ...
按键驱动:异步通知机制
按键驱动:异步通知机制
一、相关函数说明
signal函数
signum是传递给它的唯一参数。执行了signal()调用后,进程只要接收到类型为signum的信号,不管其正在执行程序的哪一部分,就立即执行handler()函数。当handler()函数执行结束后,控制权返回进程被中断的那一点继续执行。
函数原型:
1234void (*signal(int signum,void(* handler)(int)))(int);//或者:typedef void (*sig_t)( int );sig_t signal(int signum,sig_t handler);
参数说明:
signum:所要处理的信号类型,它可以取除了SIGKILL和SIGSTOP外的任何一种信号。
handler:与信号关联的动作,它可以取以下三种值:
一个无返回值的函数地址
此函数必须在signal()被调用前申明,handler中为这个函数的名字。当接收到一个类型为signum的信号时,就执行handler 所指定的函数。这个函数应有如下形式的定义:
1void func(int sig ...
按键驱动——poll机制
按键驱动——poll机制
一、机制分析(主要分析sys_poll)
对于应用程序调用poll或select,它们调用的内核函数都是sys_poll。
sys_poll函数位于fs/select.c文件中,代码如下:
1234567891011121314151617181920asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, long timeout_msecs){ s64 timeout_jiffies; if (timeout_msecs > 0) {#if HZ > 1000 /* We can only overflow if HZ > 1000 */ if (timeout_msecs / 1000 > (s64)0x7fffffffffffffffULL / (s64)HZ) timeout_jiffies = -1; else#en ...
linux等待队列wait_queue_head_t和wait_queue_t
linux等待队列wait_queue_head_t和wait_queue_t
等待队列在linux内核中有着举足轻重的作用,很多linux驱动都或多或少涉及到了等待队列。因此,对于linux内核及驱动开发者来说,掌握等待队列是必须课之一。 Linux内核的等待队列是以双循环链表为基础数据结构,与进程调度机制紧密结合,能够用于实现核心的异步事件通知机制。它有两种数据结构:等待队列头(wait_queue_head_t)和等待队列项(wait_queue_t)。等待队列头和等待队列项中都包含一个list_head类型的域作为”连接件”。它通过一个双链表和把等待task的头,和等待的进程列表链接起来。下面具体介绍。
一、定义:
头文件:/include/linux/wait.h
12345struct __wait_queue_head { spinlock_t lock; struct list_head task_list;};typedef struct __wait_queue_head wait_queue_head_t;
二、作用:
在内核里面,等待队列是有 ...
Linux编程--文件描述符fd
Linux编程–文件描述符fd
linux中, 每一个进程在内核中,都对应有一个“打开文件”数组,存放指向文件对象的指针,而 fd 是这个数组的下标。
我们对文件进行操作时,系统调用,将fd传入内核,内核通过fd找到文件,对文件进行操作。
既然是数组下标,fd的类型为int, < 0 为非法值, >=0 为合法值。在linux中,一个进程默认可以打开的文件数为1024个,fd的范围为0~1023。可以通过设置,改变最大值。
在linux中,值为0、1、2的fd,分别代表标准输入、标准输出、标准错误输出。在上一篇文章中,使用重定向 2>/dev/null 就是把标准错误输出重定向到位桶中去,不显示出来。因为 0 1 2已经被linux使用了,通常在程序中打开的fd,是从3开始的。但我们在判断一个fd是否合法时,依然要使用>=0的判断标准。
fd的分配原则,是从小到大,找到第一个不用的进行分配。
除了open之外, socket编程的socket()/accept()等函数,也会返回一个fd值。
1)Linux系统下,所有进 ...
Markdown 语法整理
Markdown 语法整理
简明教程:https://ouweiya.gitbooks.io/markdown/
[TOC]
1.标题
代码
注:# 后面保持空格
12345678910# h1## h2### h3#### h4##### h5###### h6####### h7 // 错误代码######## h8 // 错误代码######### h9 // 错误代码########## h10 // 错误代码
演示
![1562910228586](Markdown 语法整理/1562910228586.png)
2.分级标题
代码
注:= - 最少可以只写一个,兼容性一般
1234一级标题======================二级标题---------------------
演示
![img](Markdown 语法整理/6912209-c969047ea76e86b3.webp)
3.TOC
输入[toc]然后回车,即可创建一个“目录”。TOC从文档中提取所有标题,其内容将自动更新。
注:根据标题生成目录,兼容性一般
代码
1[TO ...