基于Linux的红外线感应驱动程序开发
基于Linux的嵌入式红外热成像系统设计

基于Linux的嵌入式红外热成像系统设计
系统结构设计本系统通过红外焦平面阵列探测器将红外图像送入红外图像采集模块并完成模数转化,转化后的数字信号送入图像校正模块进行非均匀校正、测温和滤波处理,校正后的图像数据再送入图像显示终端,图像显示终端将图像信息进行灰度拉伸、伪彩变换后在终端进行显示,并可完成图像分析、图像存储等多种功能。
本系统可应用于远程检测和移动监控等多个领域。
系统总体方案如图1 所示。
图1 红外热成像系统框图
系统硬件设计1 硬件结构本文设计的红外成像系统的结构可分为红外镜头、信号预处理、数字信号处理、控制显示四大部分,系统硬件结构如图2 所示。
红外焦平面阵列探测器完成光电转化功能,信号预处理电路包括视频信号分离电路和视频信号调整电路,预处理后的模拟信号经高速A/D 转化后由双口
RAM 送入DSP。
由于DSP 具有高速的处理能力,要求DSP 能有效地与低速外设连接,否则整个系统的数据处理能力就会受到影响,因此需要把图像数据进行
高速缓存。
双口RAM 具有两套独立的数据、地址和控制总线,因而可从两个
端口同时读写而互不干扰,并且具有随机存取的优点,读写具有很大的灵活性。
DSP 完成红外图像数据的非均匀校正、中值滤波等大运算量处理,减轻ARM 的运算负担,因此成像系统具有很强的可靠性和实时性。
ARM-Linux 完成灰度拉伸、伪彩变换、数据分析处理、红外图像显示及系统控制。
图2 红外热成像系统硬件框图
2 主要芯片介绍ARM 处理器体积小、内核耗电少、具有良好的图像处理能。
基于嵌入式ARM-Linux平台的红外智能控制系统

基于嵌入式ARM-Linux平台的红外智能控制系统
严军;邢晓溪
【期刊名称】《数据通信》
【年(卷),期】2013(000)004
【摘要】根据红外线传输原理,提出了一种基于Linux操作系统和ARM9的新型红外智能控制系统.该系统可以对不同设备的红外遥控器发送的红外数据进行采样,再通过无线网络,将数据保存至PC机或者无线手持设备,这样用户可以对想要控制的目标设备调用相应的红外命令,从而实现一个平台远程控制多个红外设备.
【总页数】3页(P10-12)
【作者】严军;邢晓溪
【作者单位】上海理工大学光电信息与计算机工程学院上海200093;上海理工大学光电信息与计算机工程学院上海200093
【正文语种】中文
【相关文献】
1.基于嵌入式平台的公交优先智能控制系统 [J], 李民生;南柄飞
2.基于RT5350嵌入式平台的无线智能小车控制系统设计 [J], 王浩
3.基于红外探测技术的嵌入式智能监测平台研究 [J], 关永;吴敏华;张杰;赵冬生;张聪霞
4.基于Arm-Linux的嵌入式智能家居控制系统的设计 [J], 谭涛;徐晓辉;黄晓亮;王盟;温阳
5.基于RT5350嵌入式平台的无线智能灯光控制系统设计 [J], 王浩
因版权原因,仅展示原文概要,查看原文内容请购买。
基于Linux内核的1-wair总线驱动(温度传感器驱动)

基于Linux内核的1-wair总线驱动(温度传感器驱动)*******************************************************************************驱动代码:ds18b20_drv******************************************************************************* #include#include#include#include#include#include#include#include#include#include#include#include#includeMODULE_LICENSE("GPL");#define DS18B20_RESET (0x10009)#define DS18B20_REL (0x10011)#define SKIP_ROM 0xcc#define COVERTT 0x44#define READ_MEM 0xbe#define WRITE_MEM 0x4e#define NINE_BIT 0x1f#define TEN_BIT 0x3f#define ELE_BIT 0x5f#define TWL_BIT 0x7f#define TH 100#define TL 0#define TEMP_H 10000#define TEMP_L -10000static unsigned long *gpio_con;static unsigned long *gpio_dat;static void gpio_cfg_out(unsigned char val) {*gpio_con &= ~0xf;*gpio_con |= 0x1;if (val == 0) {*gpio_dat &= ~0x1;} else {*gpio_dat |= 0x1;}}static unsigned char gpio_cfg_in(void){*gpio_con &= ~0xf;return *gpio_dat & 0x1;}static void ds18b20_write8(unsigned char data) {int i = 0;for (; i<8; i++) {if ((data & 0x1) == 1) {gpio_cfg_out(0);udelay(3);gpio_cfg_out(1);udelay(80);} else {gpio_cfg_out(0);udelay(80);gpio_cfg_out(1);udelay(3);}data >>= 1;}}static unsigned char ds18b20_read8(void) {int i = 0;unsigned char bit;unsigned char data = 0;for (; i<8; i++) {gpio_cfg_out(0);udelay(2);gpio_cfg_out(1);udelay(5);bit = gpio_cfg_in();data |= (bit << i);udelay(5);gpio_cfg_out(1);udelay(60);}return data;}static void ds18b20_reset(void){unsigned char ret = 0;gpio_cfg_out(0);udelay(500);gpio_cfg_out(1);udelay(30);ret = gpio_cfg_in();udelay(500);#if 0if (ret == 0) {printk("reset ok.\n");} else {printk("reset failed.\n");}#endif}static void ds18b20_config_rel(unsigned char rel){ds18b20_reset();ds18b20_write8(SKIP_ROM);ds18b20_write8(WRITE_MEM);ds18b20_write8(TH);ds18b20_write8(TL);switch (rel) {case 9:ds18b20_write8(NINE_BIT);break;case 10:ds18b20_write8(TEN_BIT);break;case 11:ds18b20_write8(ELE_BIT);break;case 12:ds18b20_write8(TWL_BIT);break;}}static int ds18b20_open(struct inode *inode, struct file *file) {return 0;}static int ds18b20_release(struct inode *inode, struct file *file) {return 0;}void bubbleSort(int arr[], int count){int i = count, j;int temp;while (i > 0) {for (j=0; iif (arr[j] > arr[j+1]) {temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}i--;}}static ssize_t ds18b20_read(struct file *file, char *buf, size_t count, loff_t *pos){unsigned char h8, l8;int i, temp = 0, tvalsum;int value[12];ds18b20_reset();ds18b20_write8(SKIP_ROM);ds18b20_write8(COVERTT);udelay(700);mdelay(750);for (i=0; i<12; ++i) {ds18b20_reset();ds18b20_write8(SKIP_ROM);ds18b20_write8(READ_MEM);l8 = ds18b20_read8();h8 = ds18b20_read8();temp = (h8 << 8) | l8;if (temp & 0x8000) {temp = ~temp + 1;}temp *= 50;temp >>= 3;if ((temp > TEMP_H) || (temp < TEMP_L)) {--i;temp = 0;continue;}value[i] = temp;}bubbleSort(value, 12);for (i=4, tvalsum=0; i<8; ++i) {tvalsum += value[i];}temp = (tvalsum) / 4;if(copy_to_user(buf, &temp, 4))return -EFAULT;return count;}static int ds18b20_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){unsigned char rel;if(copy_from_user(&rel, (unsigned char *)arg, 1))return -EFAULT;switch (cmd) {case DS18B20_RESET:ds18b20_reset();break;case DS18B20_REL:ds18b20_config_rel(rel);break;default:return -1;}return 0;}static struct file_operations ds18b20_fops = {.owner = THIS_MODULE,.open = ds18b20_open,.release = ds18b20_release,.read = ds18b20_read,.unlocked_ioctl = ds18b20_ioctl,};static struct miscdevice ds18b20_miscdev = {.minor = MISC_DYNAMIC_MINOR,.name = "ds18b20",.fops = &ds18b20_fops,};static int ds18b20_init(void){misc_register(&ds18b20_miscdev);gpio_con = ioremap(0xe0200c20, 8);gpio_dat = gpio_con + 1;return 0;}static void ds18b20_exit(void){iounmap(gpio_con);misc_deregister(&ds18b20_miscdev);}module_init(ds18b20_init);module_exit(ds18b20_exit);******************************************************************************* Makefile文件*******************************************************************************ifeq ($(KERNELRELEASE),)KERNELDIR ?= /home/linux/linux-3.0.8/PWD := $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_installtest:test.cclean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* module* test.PHONY: modules modules_install cleanelseobj-m := ds18b20_drv.oendif*******************************************************************************测试代码:test******************************************************************************* #include#include#include#include#include#include#include#define DS18B20_RESET 0x10001#define DS18B20_REL 0x10002int main(int argc, char *argv[]){int fd;int data;unsigned char relbit;fd = open("/dev/ds18b20", O_RDWR);if (fd < 0){printf("open ds18b20 failed.\n");exit(-1);}if (argc < 2){printf("usage:\n %s <9|10|11|12>\n", argv[0]); exit(-1);}relbit = strtoul(argv[1], NULL, 10);while (1) {ioctl(fd, DS18B20_REL, &relbit);read(fd, &data, sizeof(data));usleep(200000);printf("%f\n", (float)data / 100);}close(fd);return 0;}。
基于Linux的红外网络通信的实现

基于L i n u x的红外网络通信的实现周亦敏佟国香(上海理工大学计算机工程学院200093)摘要分析了红外网络通信标准I r D A的层次结构,介绍了L i n u x网络设备驱动程序在内核中的工作机理,并以在高端嵌入式处理器P X A255上实现的红外网络通信为实例,给出了L i n u x网络设备驱动程序的一种开发模式和实现要点,为复杂网络驱动程序的设计和各类嵌入式设备开发中红外网络通信的应用提供了一种实用的方法。
关键词I r D A L i n u x网络设备驱动P X A255T h e I m p l e m e n t a t i o no f L i n u x-b a s e dI n f r a r e dWi r e l e s s C o m m u n i c a t i o n sZ h o uY i m i n T o n gG u o x i a n g(C o l l e g e o fC o m p u t e r E n g i n e e r i n g,U n i v e r s i t yo fS h a n g h a i f o r S c i e n c e a n dT e c h n o l o g y,S h a n g h a i2o o o p q,C h i n a)r b s t r a c t I s i t a n a u v w x yz o r s h x a r{h i s x{s u r x o z I r D A|t s a n y a r y}r o s o{o u o z i n z r a r x y~i r x u x t t{o m m u n i{a s i o n t a n y i n s r o y u{x yz o rs h x~o r k i n gm x{h a n i t m o zn x s~o r k y x v i{xy r i v x r~i s h i n k x r n x u o zL i n u x}u a s z o r m.W i s h s h x i n t s a n{x o z i n z r a r x y n x s~o r k{o m m u n i{a s i o n t i m}u x m x n s x y o n P X A255|s h x h i g h|x m b x y y x y}r o{x t t o r,a y x v x u o}m x n s m o y xa n yx t t x n s i a u i m}u x m x n s x y}o i n s to z L i n u xn x s~o r k y x v i{xy r i v x r a r x}r x t x n s x ys o}r o v i y xa z x a t i b u x m x s h o yz o r y x t i g no z{o m}u x xn x s~o r k y x v i{x y r i v x r a n ya}}u i{a s i o no z i n z r a r x y~i r x u x t t{o m m u n i{a s i o n t i ny i z z x r x n s x m b x y y x y|y x v i{x.K e y w o r d s I r D A L i n u x N x s~o r k y x v i{x y r i v x r P X A2551引言随着I n s x r n x s的飞速发展,从W A N到M A N,再到L A N,P A N,这些技术已逐渐成熟。
Linux内核红外遥控子系统-LIRC

Linux Infrared RemoteControl System修订历史版本日期作者描述0.1 2011-10-12 杜昌彬初稿1.红外遥控基础知识1.1红外遥控简介红外遥控协议有有很多,比如RC-5,RC-6,NEC,SIRC等,不过协议都比较简单,基本上都是以脉冲宽度或脉冲间隔来编码。
当遥控器上按下按键时,遥控器逻辑单元会产生一个完整的逻辑脉冲波形,这个波形上包含了遥控命令的信息,他是红外传输的基带信号。
这个波形被送到遥控器的调制单元,经调制单元调制成高频的红外电磁波信号,并由发光二极管发射出去。
如下图的左边模块。
红外遥控的信号的产生和接收红外电磁波信号现在一般使用一体化接收头接收,接收头同时完成了信号的解调和放大,其输出信号就是红外的基带脉冲信号。
解调后的信号可直接送入信号处理器中由处理器对脉冲波形进行解码,也就是将经编码的脉冲信号翻译成逻辑数字。
根据不同的控制协议,解码方式不同。
红外接收头,一跟线用于输出脉冲信号,其他两根是电源线和地线1.2红外遥控协议下面已sony的SIRC协议为列说明。
编码SIRC协议使用脉冲宽度对每一比特位进行编码,编码规则如下:SIRC协议编码首先,每一个脉冲后跟一个固定宽为600微秒的间隔,而每一个脉冲便是一个逻辑数字,并由脉冲的宽度决定是0还是1:脉冲宽度1200微秒表示逻辑1,宽度600微秒表示逻辑0.幀格式当按下遥控器上的按键时,遥控器会发送一个命令信号,这个信号就是一个幀,它包含了命令字段和地址(设备)字段,以及扩展字段。
当按住按键不放时,遥控器会不断的发送这一命令信号,直到松开。
SIRC协议的幀格式有12位、15位、20位三种,如下所示:一个幀以一个起始标志(图中的红色)开始,它是一个2400微秒的脉冲并跟一个间隔。
之后是7字节的命令字段(图中的橙色),这个字段用于识别按下了遥控器上的哪个按键;然后是地址字段(图中的蓝色),用于识别控制的是什么类型的设备;对于20位宽格式,还有一个扩展字段,用于传输其他信息。
基于嵌入式ARM-Linux的红外通信及解码驱动设计

基于嵌入式ARM-Linux的红外通信及解码驱动设计何剑锋;方方;丁仿;栗楠;周凯【期刊名称】《光通信技术》【年(卷),期】2011(035)004【摘要】提出了以嵌入式微处理器S3C2440为核心,在嵌入式ARM-Linux2.6.12操作系统上实现红外通信与解码驱动的设计方案.介绍了红外遥控系统结构和红外遥控系统中专用发射芯片(TC9012)编码方式,在此基础上结合嵌入式Linux和驱动程序设计框架,详细阐述了嵌入式Linux2.6.12系统上红外遥控解码的驱动程序开发并讨论了驱动程序的编译加载方法.通过Linux图形用户界面下的应用程序测试其红外解码驱动,实践并验证了该设计在ARM平台上通信稳定,具备优良的正确性、准确性和实时性.%The design of infrared communication and decode driver in embedded ARM-Linux2.6.12 based on the S3C2440 microprocessor is proposed. It introduces system structure of infrared remote control and remote control ASIC (TC9012) coding methods. In addition combining with embedded Linux and framework of drivr programming, the developmentof device drivers for infrared remote control decoding and compiling method of drivers in embedded Linux2.6.12 operating system is detailed. Finally application testing under the Linux system GUI verifies that the driver program for communication is stability and reliably on ARM platform as well as excellent correctness, accuracy and real-time performance.【总页数】4页(P45-48)【作者】何剑锋;方方;丁仿;栗楠;周凯【作者单位】成都理工大学,核技术与自动化工程学院,成都,610059;东华理工大学,软件学院,南昌,330013;成都理工大学,核技术与自动化工程学院,成都,610059;东华理工大学,软件学院,南昌,330013;东华理工大学,软件学院,南昌,330013;东华理工大学,软件学院,南昌,330013【正文语种】中文【中图分类】TP915【相关文献】1.嵌入式Linux下红外遥控解码的驱动设计 [J], 张公礼;王东明2.基于CPLD的室内无线红外通信PPM编解码实现 [J], 董光辉;席志红;苏宝强3.基于DDK的TLV320AIC23型编解码器的驱动设计 [J], 范学锋;吴成柯4.基于嵌入式Linux的红外通信系统设计 [J], 陈祖爵;王继凤;王加民5.基于嵌入式控制器的红外通信系统设计 [J], 谢平;王得芳因版权原因,仅展示原文概要,查看原文内容请购买。
基于嵌入式Linux的红外通信系统设计

8162009,30(4)计算机工程与设计Computer Engineering and Design0引言红外通信成本低廉,跨平台适应性好,传输速率高,所以普遍用于低成本、跨平台、点对点高速数据连接是嵌入式系统通信中一种比较理想的方案选择[1]。
Linux 是目前最具活力的操作系统之一,其对各类计算机架构的兼容和支持,强健的网络功能,独特的自由软件的特征,近几年应用范围越来越大,基于Linux 的各种应用开发成为目前的主流技术之一。
因此在嵌入式Linux 系统基础上的红外通信系统的设计可以实现当下采用Linux 操作系统的嵌入式设备短距离通信的需求。
1系统总体方案基于Linux 的红外通信系统由软、硬件两部分组成,硬件部分主要包括:(1)硬件开发平台;主要包括微处理器S3C2410,FLASH ,SDRAM 等相关模块。
(2)红外通信模块;采用具有UART 接口的红外器件ZHX 1010及其外围器件。
软件部分主要包括:嵌入式Linux 操作系统、红外通信模块驱动程序和红外通信应用程序。
系统总体结构如图1所示。
2系统硬件组成2.1硬件开发平台嵌入式系统开发平台采用S3C2410处理器为控制器,结构框图如图2所示。
S3C2410是16/32-bit RISC 处理器,主频为203MHz ,是现在普遍采用的应用型处理器。
S3C2410处理器主要包括以下内容:(1)ARM 内核。
在内核中实现了ARM 指令集所定义的操收稿日期:2008-03-24E-mail :wjmltc@嵌入式系统陈祖爵,王继凤,王加民:基于嵌入式Linux 的红外通信系统设计2009,30(4)817作,JTAG 口调试功能,存储器管理单元(MMU ),Buffer ,Cache 等模块。
(2)外设控制模块(peripheral control module ,PCM )。
S3C2410外设控制器包括多种串行数据口控制器,USB 客户端控制器,SD 卡控制器等。
基于Linux的温度传感器DS18B20驱动程序设计

基于Linux的温度传感器DS18B20驱动程序设计引言传统的模拟温度测量抗干扰能力差,放大电路零点漂移大,导致测量值误差大,难以达到所需精度。
在实际应用中,采用抗干扰能力强的数字温度传感器是解决上述问题的有效办法。
DS18B20 是Dallas 公司生产的数字温度传感器,具有体积小、适用电压宽、经济灵活的特点。
它内部使用了onboard 专利技术,全部传感元件及转换电路集成在一个形如三极管的集成电路内。
DS18B20 有电源线、地线及数据线3 根引脚线,工作电压范围为3~5.5 V,支持单总线接口。
准确的温度测量是很多嵌入式系统中重要的一点。
在Linux 操作系统下使用数字温度传感器DS18B20,不仅可以得到高精度的温度测量值,而且硬件简单可靠。
1Linux 的设备驱动程序在Linux 中,驱动程序是内核的一部分,它屏蔽了硬件细节,是整个操作系统的基础。
驱动程序与Linux 内核结合有两种方式:在编译内核时,静态地链接进内核;在系统运行时,以模块加载的方式加载进内核。
驱动的对象是存储器和外设。
Linux 将存储器和外设分为3 个基础类:字符设备、块设备、网络设备。
字符设备是指必须以串行顺序依次进行访问的设备,不需要经过系统的快速缓冲;而块设备要经过系统的快速缓冲,可以任意顺序进行访问,以块为单位进行操作。
字符设备和块设备并没有严格的界限,有些设备(如Flash)既可看作字符设备,也可作为块设备来访问。
网络设备面向数据包的接收和发送而设计,并不对应于文件系统节点。
内核与网络设备的通信方式完全不同于内核与字符设备、块设备的通信方式。
DS18B20 是单总线温度传感器,主机只能以“位”为单位对其进行访问。
因此,在Linux 系统中,将DS18B20 作为一种典型的字符设备来访问。
2 DS18B20 的结构和工作原理2.1DS18B20 的内外结构DS18B20 的外部结构如图1 所示。
其中,VDD 为电源输入端,DQ 为数字信号输入/输出端,GND 为电源地。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
如图所示为cdev结构体、file-operations和用户空间调用 驱动的关系:
中断机制
▪ 中断流程图
CPU在处理某一事件A时,发生了另一事件B请求CPU 迅速去处理(中断发生);
CPU暂时中断当前的工作,转去处理事件B(中断响 应和中断服务);
待CPU将事件B处理完毕后,再回到原来事件A被中断 的地方继续处理事件A(中断返回),这一过程称为中断。
2.设备操作的实现:(file_operations函数集的实现)
如: unsigned long copy_to_user(void __user *to, const void *from, unsigned long n); unsigned long copy_from_user(void *to, const void __user *from, unsigned long n); put_user(local,user); get_user(local,user);
3.int open(struct inode *inode, struct file *):该函数用 来打开一个设备文件.
4.int release(struct inode *inode, struct file *):该函数 用来关闭一个设备文件. 该结构体的初始化形式如下例: struct file_operations scull_fops = { .owner =THIS_MODULE, .read = read, .write = write, .open = open, .release = release, }
3.设备注销:void cdev_del(struct cdev *p);
字符设备驱动小结: 字符设备驱动程序中完成的主要工作是初始化、添加
和删除cdev结构体,申请和释放设备号,以及填充 file_operation结构体中操作函数,并实现file_operations 结构体中的read()、write()、ioctl()等重要函数。如图所示 为cdev结构体、file_operations和用户空间调用驱动的关 系。
其中: filp为文件属性结构体指针.
buf为用户态函数使用的字符内存缓冲.
count为要读取的数据数.
f_ops为文件指针的偏移量.
ssize_t write(struct file *filp, const char __user *buf, size_t count, loff_t *f_ops):用来向设备输入数据. 各函数的含义与上个函数相同.
1.int register_chrdev_region(dev_t first, unsigned int count, char *name); 其中, first为要分配的设备编号范围的起始值,经常被置零.count 则是所请求的连续设备编号的个数,这意味着只能申请连续的设 备编号.
2.int alloc_chrdev_region(dev_t *dev, unsigned firstminor, int count, char *name); 其中dev用于保存申请成功后动态分配的第一个设备号, firstminor则是请求使用的第一个次设备号.其余与上个函数相 同.
和中断分两大类:外部中断和内部中断
1.外部中断寄存器
24个外部中断占用GPF0-GPF7(EINT0-EINT7),GPG0-GPG15 (EINT8-EINT23)。用这些脚做中断输入,则必须配置引脚为中断,并且 不要上拉。
寄存器:
EXTINT0-EXTINT2:分别设置EINT0—EINT7、EINT8—EINT15、 EINT16—EINT23的触发方式(高电平触发、低电平触发、下降沿触发、上 升沿触发)。 EINTFLT0-EINTFLT3:控制滤波时钟和滤波宽度。 EINTPEND:这个是中断挂起寄存器,清除时要写1,后面还有几个是写1 清除。当一个外部中断(EINT4-EINT23)发生后,那么相应的位会被置1。 为什么没有EINT0-EINT3,因为它们分别由SRCPND寄存器的后4位控制。 EINTMASK:这个简单,是屏蔽中断用的,也就是说位为1时,此次中断无 效。
my_cdev.owner = THIS_MODULE; 最后即可以向模块添加该结构体:
int cdev_add(struct cdev *dev, dev_t dev_num, usigned int count).其中dev是cdev结构体,dev_num是该设备对应的第一个 设备编号, count则是与该设备关联的设备编号数量.
I/O接口寄存器(通过GPF控制外部中断(EINT0-EINT7) )
2. 内部中断寄存器(8个)
SUBSRCPND:当一个中断发生后,那么相应的位会被置1,表 示一个中断发生了。
INTSUBMSK:与上一个是一样的,中断屏蔽寄存器。 SRCPND:当一个中断发生后,那么相应的位会被置1,表示一 个或一类中断发生了。 INTMSK:用来屏蔽SRCPND寄存器所标识的中断。但只能屏蔽 IRQ中断,不能屏蔽FIQ中断。 INTMOD:当INTMOD中某位被设置为1时,它对应的中断被设 为FIQ,CPU将进入快速中断模式。 PRIORITY:用于设置IRQ中断的优先级。具体使用方法可参考 芯片手册。 INTPND:中断优先级仲裁器选出优先级最高中断后,这个中断 在INTPND寄存器中的相应位被置1,随后,CPU进入中断模式处理 它。同一时间内,此寄存器只有一位被置1。 INTOFFSET:用来表示INTPND寄存器中哪位被置1了,即记录 INTPND中位[x]为1的位x的值。清除INTPND、SRCPND时自动清除。
四.字符设备的注册.
内核内部使用struct cdev结构来表示字符设备.在内核调用设备 的操作之前,必须分配或注册一个或者多个该结构体.该结构体 包含在头文件中.一般的步骤如下: 首先定义该结构体:
struct cdev my_cdev; 然后即可以初始化该结构,使用如下的函数初始化:
int cdev_init(struct cdev *dev, struct file_operations *fops). 然后定义该结构体中的一个所有者字段:
三种中断都等待进一步处理了。接下来从SRCPND往下看,看 INTMSK。如果中断被屏蔽了,就不用说了(注意:快中断也能被 屏蔽)。如果没有被屏蔽,那么会进一步到INTMOD。如果是快中 断,那么直接出来,进入FIQ(即CPU进入快中断模式处理)。如 果是普通中断,那么SRCPND可以有多为置1(FIQ只能有一个), 这时就会经过PRIORITY选出一个优先级高的,然后把根据选出的中 断把INTPND相应位置1(注意:只能选出一个),进入IRQ,让 CPU处理。
基于Linux的红外线感应驱动 程序开发
红外感应模块
简介
▪红外线感应器是根据红外线反射的原理研制的,属于一种 智能节水、节能设备。包括感应水龙头、自动干手器、医用 洗手器、自动给皂器、感应小便斗冲水器、感应便器。
▪这是标准的称呼,也有称为热红外人体感应器。
原理
这种是通过红外线反射原理,当人体的手或身体的某一部 分在红外线区域内,红外线发射管发出的红外线由于人体 手或身体摭挡反射到红外线接收管,通过集成线路内的微 电脑处理后的信号发送给脉冲电磁阀,电磁阀接受信号后 按指定的指令打开阀芯来控制头出水;当人体的手或身体 离开红外线感应范围,电磁阀没有接受信号,电磁阀阀芯 则通过内部的弹簧进行复位来控制的关水。
MAJOR(dev_t dev_id);
MINOR(dev_t dev_id); 将主设备号和次设备号转换为dev_t类型,则可以使用下面的宏:
MKDEV(int major, int minor); 其中,major为主设备号,minor为次设备号.
二.分配设备号
在建立一个字符设备之前.首先要申请设备号,完成该功能的函 数有两个,都包含在头文件中.下面分别来看这两个文件:
c .如果是外部中断,对于EINT8-23需要清除EINTPEND和 SRCPND(同样注意顺序)。对于EINT0-EINT3只需清除 SRCPND。
字符设备的驱动流程
字符设备驱动模型
字符设备驱动程序的基本步骤
一.设备号 对字符设备的访问是通过文件系统内的设备名称来访问的,设备 名称位于目录/dev下.为了便于系统管理,设置了和设备名称一一 对应的设备号,它分为主设备号和次设备号.通常来说,主设备号标 示了设备对应的驱动程序,次设备号则用来分辨拥有同一个主设 备号的的各个不同设备. 在内核中,设备号使用类型dev_t来保存,它包括了主设备号和次 设备号.dev_t是一个32位的整数,其中的12位用来标示主设备号, 其余的20位用来标示次设备号.我们可以使用两个宏来获得设备 的主设备号及次设备号:
4. 中断的清除
a.如果是不带子中断的内部中断,只需清除SRCPND,注意 清除需位置1。
b. 如果是带子中断的内部中断,需清除SRCPND和 SUBSRCPND,注意先清除SUBSRCPND,再清除SRCPND。 因为,如果你先清除SRCPND的话,然后在清除SUBSRCPND的 过程中,SRCPND会以为又有中断发生,又会置1。也就是说一 次中断会响应两次。所以必须先掐断源头。
2. 外部中断过程
如果是外部中断:EINT0-EINT3发生后SRCPND相应位置1,如 果没有被INTMSK屏蔽,那么等待进一步处理。EINT4-EINT23发生 后EINTPEND相应位置1,如果没有被EINTMASK屏蔽,那么 SRCPND相应位EINT4-7 或EINT8-23置1,如果没有被INTMSK屏 蔽,等待进一步处理。
五.移除字符设备
void cdev_del(struct cdev *dev);
六.注销设备号.
unregister_chrdev_region(dev_t first, unsigned int count); 以上两个函数一般用于模块出口函数中.