




下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、PAGE PAGE 244第章嵌入式Linux设备驱动编程 $ ls l /devcrw-rw 1 root uucp 4, 64 08-30 22:58 ttyS0 /*串口设备, c表示字符设备*/brw-r 1 root floppy 2, 0 08-30 22:58 fd0/*软盘设备,b表示块设备*/ $ lsmod ModuleSizeUsed by Autofs120680 (autoclean) (unused)eepro100181281 iptable_nat192520 (autoclean) (unused)ip_conntrack185401 (autoclean)
2、iptable_natiptable_mangle22720 (autoclean) (unused)iptable_filter22720 (autoclean) (unused)ip_tables119365 iptable_nat iptable_mangle iptable_filterusb-ohci193280 (unused)usbcore545281 usb-ohciext3677282 jbd444802 ext3aic7xxx1147043 sd_mod115843 scsi_mod985122 aic7xxx sd_mod static int _init initial
3、ization_function(void)/* 初始化代码 */module_init(initialization_function); request_module(module_name); request_module(char-major-%d-%d, MAJOR(dev), MINOR(dev); static void _exit cleanup_function(void)/* 释放代码 */module_exit(cleanup_function); #define _init_attribute_ (_section_ (.init.text) #ifdef MODULE
4、#define _exit_attribute_ (_section_(.exit.text)#else#define _exit#endif #define _initdata _attribute_ (_section_ (.init.data) #define _exitdata _attribute_ (_ _section_(.exit.data) static char *str_param = Linux Module Program;static int num_param = 4000;module_param(num_param, int, S_IRUGO);module_
5、param(str_param, charp, S_IRUGO); EXPORT_SYMBOL(符号名);EXPORT_SYMBOL_GPL(符号名); MODULE_AUTHOR(author);MODULE_DESCRIPTION(description);MODULE_VERSION(version_string);MODULE_DEVICE_TABLE(table_info);MODULE_ALIAS(alternate_name); int try_module_get(struct module *module); void module_put(struct module *mo
6、dule); obj-m := hello.o $ make -C /usr/src/linux-/ M=/driver_study/ modules $ make C /usr/src/linux-2.6.15 $ make -C /usr/src/linux-/ M=/driver_study/ modulesmake: Entering directory /usr/src/linux- CC M /driver_study/hello.o/driver_study/hello.c:18:35: warning: no newline at end of file Building mo
7、dules, stage 2. MODPOST CC /driver_study/hello.mod.o LD M /driver_study/hello.komake: Leaving directory /usr/src/linux- 1 #include 2 #include 3 #include 4 5 MODULE_INFO(vermagic, VERMAGIC_STRING);6 7 struct module _this_module8 _attribute_(section(.gnu.linkonce.this_module) = 9 .name = KBUILD_MODNAM
8、E,10 .init = init_module,11#ifdef CONFIG_MODULE_UNLOAD12 .exit = cleanup_module,13#endif14;1516static const char _module_depends17_attribute_used_18_attribute_(section(.modinfo) =19depends=; obj-m := modulename.omodule-objs := file1.o file2.o mount /procmount /varmount /dev/ptsmkdir /var/logmkdir /v
9、ar/runmkdir /var/ftpmkdir -p /var/spool/cronmkdir /var/config.insmod /usr/lib/company_driver.ko 2 /dev/null/usr/bin/userprocess/var/config/rc $ insmod module_test.ko symbol_type=1 string=a1b+c=d4e56g7h,8i9k/l.$ dmesg|tail n 10 Total symbols module init /* 在模块加载时打印*/ Digits: 7 /* 字符串中有7个数字*/ #include
10、 #include #include #define TOTAL_LETTERS0#define TOTAL_DIGITS1#define TOTAL_SYMBOLS2#define TOTAL_ALLTOTAL_LETTERS | TOTAL_DIGITS | TOTAL_SYMBOLS#define STR_MAX_LEN256static int symbol_type = TOTAL_ALL;static char *string = NULL; unsigned int total_symbols(char* string, unsigned int total_type)/* 该函
11、数根据统计类型(total_type)计算相应字符的个数而返回它*/* 这部分代码也可以从网上下载 */EXPORT_SYMBOL(total_symbols); /* 导出的符号用cat /proc/kallsyms |grep total_symbols命令检查*/static int total_symbols_init(void) char type_strSTR_MAX_LEN;unsigned int number_of_symbols = 0;switch(symbol_type)case TOTAL_LETTERS: /* “字母”统计 */strcpy(type_str, L
12、etters);break;case TOTAL_DIGITS: /* “数字”统计 */strcpy(type_str, Digits);break;case TOTAL_SYMBOLS: /* 其他符号”统计 */strcpy(type_str, Symbols);break;default: /* 默认为总体统计 */case TOTAL_ALL:strcpy(type_str, Characters);number_of_symbols = total_symbols(string, symbol_type);printk(Total symbols module initn);pri
13、ntk(%s: %dn, type_str, number_of_symbols);return 0; static void total_symbols_exit(void) printk(Total symbols module exitn); module_init(total_symbols_init); /* 初始化设备驱动程序的入口 */ module_exit(total_symbols_exit); /* 卸载设备驱动程序的入口 */ module_param(symbol_type, uint, S_IRUGO); module_param(string, charp, S_
14、IRUGO);MODULE_AUTHOR(David);MODULE_DESCRIPTION(A simple module program);MODULE_VERSION(V1.0); struct file_operationsloff_t (*llseek) (struct file *, loff_t, int);ssize_t (*read) (struct file *filp, char *buff, size_t count, loff_t *offp);int (*readdir) (struct file *, void *, filldir_t);unsigned int
15、 (*poll) (struct file *, struct poll_table_struct *);int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);int (*mmap) (struct file *, struct vm_area_struct *);int (*open) (struct inode *, struct file *);int (*flush) (struct file *);int (*release) (struct inode *, struct file *);
16、int (*fsync) (struct file *, struct dentry *);int (*fasync) (int, struct file *, int);int (*check_media_change) (kdev_t dev);int (*revalidate) (kdev_t dev);int (*lock) (struct file *, int, struct file_lock *); struct file mode_t f_mode;/*标识文件是否可读或可写,FMODE_READ或FMODE_WRITE*/dev_t f_rdev; /* 用于/dev/tt
17、y */off_t f_pos; /* 当前文件位移 */unsigned short f_flags; /* 文件标志,如O_RDONLY、O_NONBLOCK和O_SYNC */unsigned short f_count; /* 打开的文件数目 */unsigned short f_reada;struct inode *f_inode; /*指向inode的结构指针 */struct file_operations *f_op;/* 文件索引指针 */; #include MAJOR(dev_t dev); /*获得主设备号*/MINOR(dev_t dev); /*获得次设备号*/M
18、KDEV(int major, int minor); int (*open) (struct inode *, struct file *);/* gpio_drv.h */#ifndef FS2410_GPIO_SET_H#define FS2410_GPIO_SET_H#include #defineGPIO_DEVICE_NAMEgpio#defineGPIO_DEVICE_FILENAME/dev/gpio#defineLED_NUM4#define GPIO_IOCTL_MAGICG#define LED_D09_SWT_IOW(GPIO_IOCTL_MAGIC, 0, unsig
19、ned int)#define LED_D10_SWT_IOW(GPIO_IOCTL_MAGIC, 1, unsigned int)#define LED_D11_SWT_IOW(GPIO_IOCTL_MAGIC, 2, unsigned int)#define LED_D12_SWT_IOW(GPIO_IOCTL_MAGIC, 3, unsigned int)#define BEEP_SWT_IOW(GPIO_IOCTL_MAGIC, 4, unsigned int)#defineLED_SWT_ON0#defineLED_SWT_OFF1#defineBEEP_SWT_ON1#define
20、BEEP_SWT_OFF0#endif /* FS2410_GPIO_SET_H */ static struct file_operations gpio_fops = /* gpio设备的file_operations结构定义 */.owner = THIS_MODULE,.open = gpio_open, /* 进行初始化配置*/.release = gpio_release,/* 关闭设备*/.read = gpio_read,.write = gpio_write,.ioctl = gpio_ioctl,/* 实现主要控制功能*/;static struct cdev gpio_d
21、evs;static int gpio_init(void)int result;dev_t dev = MKDEV(major, 0);if (major) /* 设备号的动态分配 */result = register_chrdev_region(dev, 1, GPIO_DEVICE_NAME);else /* 设备号的动态分配 */result = alloc_chrdev_region(&dev, 0, 1, GPIO_DEVICE_NAME);major = MAJOR(dev);if (result owner = THIS_MODULE;dev-ops = fops;err =
22、 cdev_add (dev, devno, 1);if (err)printk (KERN_NOTICE Error %d adding gpio %d, err, minor); int gpio_open (struct inode *inode, struct file *filp) /* open操作函数:进行寄存器配置*/s3c2410_gpio_pullup(S3C2410_GPB0, 1); /* BEEP*/s3c2410_gpio_pullup(S3C2410_GPF4, 1); /* LED D12 */s3c2410_gpio_pullup(S3C2410_GPF5,
23、1); /* LED D11 */s3c2410_gpio_pullup(S3C2410_GPF6, 1); /* LED D10 */s3c2410_gpio_pullup(S3C2410_GPF7, 1); /* LED D9 */s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP);s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF5_OUTP);s3c2410_gpio_cfgpin(S3C
24、2410_GPF4, S3C2410_GPF6_OUTP);s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF7_OUTP);return 0; int switch_gpio(unsigned int pin, unsigned int swt) /* 向5个端口中的一个输出ON/OFF值 */if (!(pin = S3C2410_GPF4) & (pin != S3C2410_GPB0)printk(Unsupported pin);return 1; s3c2410_gpio_setpin(pin, swt);return 0;static in
25、t gpio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) /* ioctl函数接口:主要接口的实现。对5个GPIO设备进行控制(发亮或发声) */unsigned int swt = (unsigned int)arg;switch (cmd) case LED_D09_SWT:switch_gpio(S3C2410_GPF7, swt); /* LED D9控制 */break;case LED_D10_SWT:switch_gpio(S3C2410_GPF6, swt)
26、; /* LED D10控制 */break;case LED_D11_SWT:switch_gpio(S3C2410_GPF5, swt); /* LED D11控制 */break;case LED_D12_SWT:switch_gpio(S3C2410_GPF4, swt); /* LED D12控制 */break;case BEEP_SWT:switch_gpio(S3C2410_GPB0, swt); /* BEEP控制 */break;default:printk(Unsupported commandn);break;return 0; static int gpio_rele
27、ase(struct inode *node, struct file *file) /* release操作函数,熄灭所有灯和关闭蜂鸣器 */switch_gpio(S3C2410_GPB0, BEEP_SWT_OFF);switch_gpio(S3C2410_GPF4, LED_SWT_OFF);switch_gpio(S3C2410_GPF5, LED_SWT_OFF);switch_gpio(S3C2410_GPF6, LED_SWT_OFF);switch_gpio(S3C2410_GPF7, LED_SWT_OFF);return 0; void s3c2410_gpio_cfgp
28、in(unsigned int pin, unsigned int function) /* 对某个管脚进行配置(输入/输出/其他功能)*/unsigned long base = S3C2410_GPIO_BASE(pin); /* 获得端口的组基地址*/unsigned long shift = 1;unsigned long mask = 0 x03; /* 通常用配置寄存器的两位表示一个端口*/unsigned long con;unsigned long flags;if (pin S3C2410_GPIO_BANKB) shift = 0;mask = 0 x01; /* 在GPA
29、端口中用配置寄存器的一位表示一个端口*/ mask = (S3C2410_GPIO_OFFSET(pin) shift);local_irq_save(flags); /* 保存现场,保证下面一段是原子操作 */con = _raw_readl(base + 0 x00);con &= mask;con |= function;_raw_writel(con, base + 0 x00); /* 向配置寄存器写入新配置数据 */local_irq_restore(flags); /* 恢复现场 */void s3c2410_gpio_pullup(unsigned int pin, unsig
30、ned int to) /* 配置上拉功能 */unsigned long base = S3C2410_GPIO_BASE(pin); /* 获得端口的组基地址*/unsigned long offs = S3C2410_GPIO_OFFSET(pin);/* 获得端口的组内偏移地址 */unsigned long flags;unsigned long up; if (pin S3C2410_GPIO_BANKB)return;local_irq_save(flags);up = _raw_readl(base + 0 x08);up &= (1 offs);up |= to offs;_
31、raw_writel(up, base + 0 x08); /* 向上拉功能寄存器写入新配置数据*/local_irq_restore(flags); void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) /* 向某个管脚进行输出 */unsigned long base = S3C2410_GPIO_BASE(pin);unsigned long offs = S3C2410_GPIO_OFFSET(pin);unsigned long flags;unsigned long dat;local_irq_save(flags)
32、;dat = _raw_readl(base + 0 x04);dat &= (1 offs);dat |= to offs;_raw_writel(dat, base + 0 x04); /* 向数据寄存器写入新数据*/local_irq_restore(flags); /* gpio_test.c */#include #include #include #include #include #include #include #include gpio_drv.hint led_timer(int dev_fd, int led_no, unsigned int time) /* 发亮指定
33、LED一段时间之后熄灭它*/led_no %= 4;ioctl(dev_fd, LED_D09_SWT + led_no, LED_SWT_ON); /* 发亮*/sleep(time);ioctl(dev_fd, LED_D09_SWT + led_no, LED_SWT_OFF); /* 熄灭 */int beep_timer(int dev_fd, unsigned int time)/* 开蜂鸣器一段时间之后关闭*/ioctl(dev_fd, BEEP_SWT, BEEP_SWT_ON); /* 发声*/sleep(time);ioctl(dev_fd, BEEP_SWT, BEEP_
34、SWT_OFF);/* 关闭 */int main()int i = 0;int dev_fd;/* 打开gpio设备 */dev_fd = open(GPIO_DEVICE_FILENAME, O_RDWR | O_NONBLOCK);if ( dev_fd = -1 ) printf(Cannt open gpio device filen);exit(1);while(1)i = (i + 1) % 4;led_timer(dev_fd, i, 1); /* LED操作*/beep_timer(dev_fd, 1); /* BEEP操作 */close(dev_fd);return 0;
35、 $ make clean;make /* 驱动程序的编译*/$ insmod gpio_drv.ko /* 加载gpio驱动 */$ cat /proc/devices /* 通过这个命令可以查到gpio设备的主设备号 */$ mknod /dev/gpio c 252 0 /* 假设主设备号为252, 创建设备文件节点*/ $ arm-linux-gcc o gpio_test gpio_test.c$ ./gpio_test int request_irq(unsigned int irq,void (*handler)(int irq, void *dev_id, struct pt_
36、regs *regs),unsigned long irqflags, const char * devname, oid *dev_id); void free_irq(unsigned int irq, void *dev_id); /* butt_drv.h */typedef struct _st_key_info_matrix/* 按键数据结构 */unsigned charkey_id;/* 按键ID */unsigned intirq_no;/* 对应的中断号 */unsigned intirq_gpio_port;/* 对应的中断线的输入端口地址*/unsigned intks
37、can_gpio_port;/* 对应的KSCAN端口地址 */ st_key_info_matrix;typedef struct _st_key_buffer/* 按键缓冲数据结构 */unsigned long jiffyMAX_KEY_COUNT;/* 按键时间, 5秒钟以前的铵键作废*/unsigned char bufMAX_KEY_COUNT;/* 按键缓冲区 */unsigned int head,tail;/* 按键缓冲区头和尾 */ st_key_buffer; static st_key_info_matrix key_info_matrixMAX_COLUMNMAX_R
38、OW =10,IRQ_EINT0, S3C2410_GPF0, S3C2410_GPE11, /* 0行0列 */11, IRQ_EINT0, S3C2410_GPF0, S3C2410_GPG6,12, IRQ_EINT0, S3C2410_GPF0, S3C2410_GPE13,16,IRQ_EINT0, S3C2410_GPF0, S3C2410_GPG2,7, IRQ_EINT2, S3C2410_GPF2,S3C2410_GPE11,/* 1行0列 */8,IRQ_EINT2,S3C2410_GPF2,S3C2410_GPG6,9, IRQ_EINT2, S3C2410_GPF2,
39、S3C2410_GPE13,15,IRQ_EINT2, S3C2410_GPF2, S3C2410_GPG2,4, IRQ_EINT11,S3C2410_GPG3,S3C2410_GPE11,/* 2行0列 */5, IRQ_EINT11,S3C2410_GPG3,S3C2410_GPG6,6, IRQ_EINT11,S3C2410_GPG3,S3C2410_GPE13,14,IRQ_EINT11, S3C2410_GPG3, S3C2410_GPG2,1, IRQ_EINT19,S3C2410_GPG11,S3C2410_GPE11,/* 3行0列 */2, IRQ_EINT19,S3C24
40、10_GPG11,S3C2410_GPG6,3, IRQ_EINT19,S3C2410_GPG11,S3C2410_GPE13,13, IRQ_EINT19,S3C2410_GPG11,S3C2410_GPG2,; static void init_gpio(void)s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_OUTP); /* GPE11 */s3c2410_gpio_setpin(S3C2410_GPE11, 0);s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_OUTP); /* G
41、PE13 */s3c2410_gpio_setpin(S3C2410_GPE13, 0);s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_OUTP); /* GPG2 */s3c2410_gpio_setpin(S3C2410_GPG2, 0);s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2410_GPG6_OUTP); /* GPG6 */s3c2410_gpio_setpin(S3C2410_GPG6, 0);s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0)
42、; /* GPF0 */s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2); /* GPF2 */s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_EINT11); /* GPG3 */s3c2410_gpio_cfgpin(S3C2410_GPG11, S3C2410_GPG11_EINT19); /* GPG11 */set_irq_type(IRQ_EINT0, IRQT_FALLING); set_irq_type(IRQ_EINT2, IRQT_FALLING);set_irq_typ
43、e(IRQ_EINT11, IRQT_FALLING);set_irq_type(IRQ_EINT19, IRQT_FALLING); /* 初始化并添加struct cdev结构到系统之中 */static void button_setup_cdev(struct cdev *dev, int minor, struct file_operations *fops)int err;int devno = MKDEV(button_major,minor);cdev_init(dev, fops); /* 初始化结构体struct cdev */dev-owner = THIS_MODULE
44、;dev-ops = fops; /* 关联到设备的file_operations结构 */err = cdev_add(dev, devno, 1); /* 将struct cdev结构添加到系统之中 */if (err)printk(KERN_INFOError %d adding button %dn,err, minor);/* 驱动初始化 */static int button_init(void)int ret; /* 将主设备号和次设备号定义到一个dev_t数据类型的结构体之中 */dev_t dev = MKDEV(button_major, 0); if (button_ma
45、jor)/* 静态注册一个设备,设备号先前指定好,并设定设备名,用cat /proc/devices来查看 */ret = register_chrdev_region(dev, 1, BUTTONS_DEVICE_NAME);else /*由系统动态分配主设备号 */ret = alloc_chrdev_region(&dev, 0, 1, BUTTONS_DEVICE_NAME);button_major = MAJOR(dev); /* 获得主设备号 */if (ret 0)printk(KERN_WARNINGButton:unable to get major %dn,button_
46、major);return ret;/* 初始化和添加结构体struct cdev到系统之中 */button_setup_cdev(&button_dev, 0, &button_fops); printk(Button driver initialized.n);return 0;/* 驱动卸载 */static void _exit button_exit(void)cdev_del(&button_dev); /* 删除结构体struct cdev */* 卸载设备驱动所占有的资源 */unregister_chrdev_region(MKDEV(button_major, 0), 1
47、); printk(Button driver uninstalledn);module_init(button_init); /* 初始化设备驱动程序的入口 */module_exit(button_exit); /* 卸载设备驱动程序的入口 */MODULE_AUTHOR(David);MODULE_LICENSE(Dual BSD/GPL); static struct file_operations button_fops =.owner = THIS_MODULE,.ioctl = button_ioctl,.open = button_open,.read = button_rea
48、d,.release = button_release,; /* 打开文件, 申请中断 */static int button_open(struct inode *inode,struct file *filp) int ret = nonseekable_open(inode, filp);if (ret 0) return ret;init_gpio();/* 相关GPIO端口的初始化*/ret = request_irqs();/* 申请4个中断 */if (ret = 1) & (ucKey = 16)/* 如果缓冲区已满, 则不添加 */if (key_buffer.head +
49、1) & (MAX_KEY_COUNT - 1) != key_buffer.tail)spin_lock_irq(&buffer_lock);key_buffer.bufkey_buffer.tail = ucKey;key_buffer.jiffykey_buffer.tail = get_tick_count();key_buffer.tail +;key_buffer.tail &= (MAX_KEY_COUNT -1);spin_unlock_irq(&buffer_lock);init_gpio();/* 初始化GPIO端口,主要是为了恢复中断端口配置 */enable_irqs(
50、);/* 开启中断 */return IRQ_HANDLED;/* 2.6内核返回值一般是这个宏 */* 申请4个中断 */static int request_irqs(void)int ret, i, j;for (i = 0; i MAX_COLUMN; i+)ret = request_irq(key_info_matrixi0.irq_no, button_irq, SA_INTERRUPT, BUTTONS_DEVICE_NAME, NULL);if (ret 0)for (j = 0; j i; j+)free_irq(key_info_matrixj0.irq_no, NULL
51、);return -EFAULT;return 0;/* 释放中断 */static _inline void free_irqs(void)int i;for (i = 0; i MAX_COLUMN; i+)free_irq(key_info_matrixi0.irq_no, NULL); /* * 进入中断后, 扫描铵键码 * 返回: 按键码(1-16), 0 xff表示错误 */static _inline unsigned char button_scan(int irq)unsigned char key_id = 0 xff;unsigned char column = 0 xf
52、f, row = 0 xff;s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_INP); /* GPF0 */s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_INP); /* GPF2 */s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_INP); /* GPG3 */s3c2410_gpio_cfgpin(S3C2410_GPG11, S3C2410_GPG11_INP); /* GPG11 */switch (irq) /* 根据irq值确定操作按键所在
53、行的位置*/case IRQ_EINT0:column = 0;break;case IRQ_EINT2:column = 1;break;case IRQ_EINT11:column = 2;break;case IRQ_EINT19:column = 3;break;if (column != 0 xff) /* 开始逐列扫描, 扫描第0列 */s3c2410_gpio_setpin(S3C2410_GPE11, 0); /* 将KSCAN0置为低电平 */s3c2410_gpio_setpin(S3C2410_GPG6, 1);s3c2410_gpio_setpin(S3C2410_GP
54、E13, 1);s3c2410_gpio_setpin(S3C2410_GPG2, 1);if(!s3c2410_gpio_getpin(key_info_matrixcolumn0.irq_gpio_port) /* 观察对应的中断线的输入端口值 */key_id = key_info_matrixcolumn0.key_id;return key_id;/* 扫描第1列*/s3c2410_gpio_setpin(S3C2410_GPE11, 1);s3c2410_gpio_setpin(S3C2410_GPG6, 0); /* 将KSCAN1置为低电平 */s3c2410_gpio_set
55、pin(S3C2410_GPE13, 1);s3c2410_gpio_setpin(S3C2410_GPG2, 1);if(!s3c2410_gpio_getpin(key_info_matrixcolumn1.irq_gpio_port)key_id = key_info_matrixcolumn1.key_id;return key_id;/* 扫描第2列*/s3c2410_gpio_setpin(S3C2410_GPE11, 1);s3c2410_gpio_setpin(S3C2410_GPG6, 1);s3c2410_gpio_setpin(S3C2410_GPE13, 0); /*
56、将KSCAN2置为低电平 */s3c2410_gpio_setpin(S3C2410_GPG2, 1);if(!s3c2410_gpio_getpin(key_info_matrixcolumn2.irq_gpio_port)key_id = key_info_matrixcolumn2.key_id;return key_id;/* 扫描第3列*/s3c2410_gpio_setpin(S3C2410_GPE11, 1);s3c2410_gpio_setpin(S3C2410_GPG6, 1);s3c2410_gpio_setpin(S3C2410_GPE13, 1);s3c2410_gpi
57、o_setpin(S3C2410_GPG2, 0); /* 将KSCAN3置为低电平 */if(!s3c2410_gpio_getpin(key_info_matrixcolumn3.irq_gpio_port)key_id = key_info_matrixcolumn3.key_id;return key_id;return key_id; /* 从缓冲删除过时数据(5秒前的按键值) */static void remove_timeoutkey(void)unsigned long tick;spin_lock_irq(&buffer_lock); /* 获得一个自旋锁 */while(key_buffer.head != key_buffer.tail)tick = get_tick_count() - key_buffer.jiffykey_buffer.head;if (tick 5000)/* 5秒 */break;key_buffer.bufkey_buffer.head = 0;key_buffer.jiffykey_buffer.head
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025至2030中国玻纤涂塑窗纱行业市场现状分析及竞争格局与投资发展报告
- 三位数乘两位数过关测验习题带答案
- 心理咨询机构受检者隐私保护制度及措施
- 科密碎纸机行业深度研究分析报告(2024-2030版)
- 2025年聚苯乙烯(PS)风险评估与管理报告
- 羽绒座垫项目投资可行性研究分析报告(2024-2030版)
- 2025-2030年中国吸塑包装清洁球项目投资可行性研究分析报告
- 2025年合同管理自查报告(三)
- 2021-2026年中国桂鱼产品流通行业调查研究及投资战略规划研究报告
- 2025年中国电能计量电流互感器检测设备行业投资分析及发展战略咨询报告
- 2024年湖北省武汉市中考道德与法治·历史试题(含答案解析)
- 2024年天津市初中学业水平考试语文试卷及参考答案
- 山东省聊城市2023-2024学年高一下学期期末考试英语试题
- 公路水运工程施工企业主要负责人和安全生产管理人员考核大纲和模拟试题库1
- 预应力混凝土管桩(L21G404)
- 企业法务概论智慧树知到期末考试答案章节答案2024年温州大学
- 第1课 多姿与多彩(生活色彩)课件-2023-2024学年高中美术人教版(2019)选择性必修1《绘画》
- 海拔高度与气压、空气密度、重力加速度对照表
- 考评员职业道德课件
- 物控培训教程预防呆滞料与库存控制的实用方法
- 天气数据分析与气象预测
评论
0/150
提交评论