嵌入式驱动编写-按键驱动程序

2019-07-13 05:20发布


今天,写出开发板上的最简单的按键驱动程序,首先需要阅读开发板的原理图和芯片手册. GPG3  GPG11  GPF0  GPF2四个引脚控制按键.










由原理图可知,需要将GPG3  GPG11  GPF0  GPF2设为输入引脚.
1 编写驱动程序 #include #include #include #include #include #include #include #include #include #include //定义两个类,自动创建设备节点 static struct class *seconddrv_class; static struct class_device *seconddrv_class_dev; volatile unsigned long *gpfcon;//gpf寄存器 volatile unsigned long *gpfdat; volatile unsigned long *gpgcon;//gpg寄存器 volatile unsigned long *gpgdat; static int second_drv_open(struct inode *inode, struct file *file) { /* 配置GPF0,2为输入引脚 */ *gpfcon &= ~((0x3<<(0*2)) | (0x3<<(2*2))); /* 配置GPG3,11为输入引脚 */ *gpgcon &= ~((0x3<<(3*2)) | (0x3<<(11*2))); return 0; } ssize_t second_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) { /* 返回4个引脚的电平 */ unsigned char key_vals[4]; int regval; if (size != sizeof(key_vals)) return -EINVAL; /* 读GPF0,2 */ regval = *gpfdat; key_vals[0] = (regval & (1<<0)) ? 1 : 0; key_vals[1] = (regval & (1<<2)) ? 1 : 0; /* 读GPG3,11 */ regval = *gpgdat; key_vals[2] = (regval & (1<<3)) ? 1 : 0; key_vals[3] = (regval & (1<<11)) ? 1 : 0; copy_to_user(buf, key_vals, sizeof(key_vals)); return sizeof(key_vals); } static struct file_operations sencod_drv_fops = { .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */ .open = second_drv_open, .read = second_drv_read, }; int major; //驱动入口 static int second_drv_init(void) { major = register_chrdev(0, "second_drv", &sencod_drv_fops); seconddrv_class = class_create(THIS_MODULE, "second_drv"); seconddrv_class_dev = class_device_create(seconddrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */ gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16); gpfdat = gpfcon + 1; gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16); gpgdat = gpgcon + 1; return 0; } //出口函数 static void second_drv_exit(void) { unregister_chrdev(major, "second_drv"); class_device_unregister(seconddrv_class_dev); class_destroy(seconddrv_class); iounmap(gpfcon); iounmap(gpgcon); return 0; } module_init(second_drv_init); module_exit(second_drv_exit); MODULE_LICENSE("GPL"); 2 编写makefile文佳 KERN_DIR = /work/system/linux-2.6.22.6 all: make -C $(KERN_DIR) M=`pwd` modules clean: make -C $(KERN_DIR) M=`pwd` modules clean rm -rf modules.order obj-m += second_drv.o
将代码上传导服务器,编译,放到网络文件系统上,启动开发板,挂接驱动程序 # insmod second_drv.ko # cat /proc/devices Character devices: 1 mem 2 pty 3 ttyp 4 /dev/vc/0 4 tty 4 ttyS 5 /dev/tty 5 /dev/console 5 /dev/ptmx 6 lp 7 vcs 10 misc 13 input 14 sound 29 fb 90 mtd 99 ppdev 116 alsa 128 ptm 136 pts 180 usb 189 usb_device 204 s3c2410_serial 252 second_drv 253 usb_endpoint 254 rtc Block devices: 1 ramdisk 7 loop 8 sd 31 mtdblock 65 sd 66 sd 67 sd 68 sd 69 sd 70 sd 71 sd 128 sd 129 sd 130 sd 131 sd 132 sd 133 sd 134 sd 135 sd 179 mmc看到设备号为252,查看设备目录 # ls -l /dev/buttons crw-r--r-- 1 0 0 252, 0 Jan 1 00:01 /dev/buttons
如果没有创建成功,手动创建 # mknod /dev/buttons c 252 03 编写测试程序 #include #include #include #include /* seconddrvtest */ int main(int argc, char **argv) { int fd; unsigned char key_vals[4]; int cnt = 0; fd = open("/dev/buttons", O_RDWR); if (fd < 0) { printf("can't open! "); } while (1) { read(fd, key_vals, sizeof(key_vals)); if (!key_vals[0] || !key_vals[1] || !key_vals[2] || !key_vals[3]) { printf("%04d key pressed: %d %d %d %d ", cnt++, key_vals[0], key_vals[1], key_vals[2], key_vals[3]); } } return 0; }
上传导服务器,编译 放到网络文件系统上,在开发板上运行 # ./seconddrvtest 0000 key pressed: 1 1 0 1 0001 key pressed: 1 1 0 1 0002 key pressed: 1 1 0 1 0003 key pressed: 1 1 0 1 0004 key pressed: 1 1 0 1 0005 key pressed: 1 1 0 1 0006 key pressed: 1 1 0 1 0007 key pressed: 1 1 0 1 0008 key pressed: 1 1 0 1 0009 key pressed: 1 1 0 1 0010 key pressed: 1 1 0 1 0011 key pressed: 1 1 0 1 0012 key pressed: 1 1 0 1 0013 key pressed: 1 1 0 1 0014 key pressed: 1 1 0 1 0015 key pressed: 1 1 0 1 0016 key pressed: 1 1 0 1 0017 key pressed: 1 1 0 1 0018 key pressed: 1 1 0 1 0019 key pressed: 1 1 0 1 0020 key pressed: 1 1 0 1 0021 key pressed: 1 1 0 1 0022 key pressed: 1 1 0 1 0023 key pressed: 1 1 0 1 0024 key pressed: 1 1 0 1 0025 key pressed: 1 1 0 1 0026 key pressed: 1 1 0 1 0027 key pressed: 1 1 0 1 0028 key pressed: 1 1 0 1 0029 key pressed: 1 1 0 1 0030 key pressed: 1 1 0 1 0031 key pressed: 1 1 0 1 0032 key pressed: 1 1 0 1 0033 key pressed: 1 1 0 1 0034 key pressed: 1 1 0 1 0035 key pressed: 1 1 0 1 0036 key pressed: 1 1 0 1 0037 key pressed: 1 1 0 1 0038 key pressed: 1 1 0 1 0039 key pressed: 1 1 0 1 0040 key pressed: 1 1 0 1 0041 key pressed: 1 1 0 1 0042 key pressed: 1 1 0 1 0043 key pressed: 1 1 0 1 0044 key pressed: 1 1 0 1 0045 key pressed: 1 1 0 1 0046 key pressed: 1 1 0 1 0047 key pressed: 1 1 0 1 0048 key pressed: 1 1 0 1 0049 key pressed: 1 1 0 1 0050 key pressed: 1 1 0 1 0051 key pressed: 1 1 0 1 0052 key pressed: 1 1 0 1 0053 key pressed: 1 1 0 1 0054 key pressed: 1 1 0 1 0055 key pressed: 1 1 0 1 0056 key pressed: 1 1 0 1 0057 key pressed: 1 1 0 1 0058 key pressed: 1 1 0 1 0059 key pressed: 1 1 0 1 0060 key pressed: 1 1 0 1 0061 key pressed: 1 1 0 1 0062 key pressed: 1 1 0 1 0063 key pressed: 1 1 0 1 0064 key pressed: 1 1 0 1 0065 key pressed: 1 1 0 1 0066 key pressed: 1 1 0 1 0067 key pressed: 1 1 0 1 0068 key pressed: 1 1 0 1 0069 key pressed: 1 1 0 1 0070 key pressed: 1 1 0 1 0071 key pressed: 1 1 0 1 0072 key pressed: 1 1 0 1 0073 key pressed: 1 1 0 1 0074 key pressed: 1 1 0 1 0075 key pressed: 1 1 0 1 0076 key pressed: 1 1 0 1 0077 key pressed: 1 1 0 1 0078 key pressed: 1 1 0 1 0079 key pressed: 1 1 0 1 0080 key pressed: 1 1 0 1 0081 key pressed: 1 1 0 1 0082 key pressed: 1 1 0 1 0083 key pressed: 1 1 0 1 0084 key pressed: 1 1 0 1 0085 key pressed: 1 1 0 1 0086 key pressed: 1 1 0 1 0087 key pressed: 1 1 0 1 0088 key pressed: 1 1 0 1 0089 key pressed: 1 1 0 1 0090 key pressed: 1 1 0 1 0091 key pressed: 1 1 0 1 0092 key pressed: 1 1 0 1 0093 key pressed: 1 1 0 1 0094 key pressed: 1 1 0 1 0095 key pressed: 1 1 0 1 0096 key pressed: 1 1 0 1 0097 key pressed: 1 1 0 1 0098 key pressed: 1 1 0 1 0099 key pressed: 1 1 0 1 0100 key pressed: 1 1 0 1 0101 key pressed: 1 1 0 1 0102 key pressed: 1 1 0 1 0103 key pressed: 1 1 0 1 0104 key pressed: 1 1 0 1 0105 key pressed: 1 1 0 1 0106 key pressed: 1 1 0 1 0107 key pressed: 1 1 0 1 0108 key pressed: 1 1 0 1 0109 key pressed: 1 1 0 1 0110 key pressed: 1 1 0 1 0111 key pressed: 1 1 0 1 0112 key pressed: 1 1 0 1 0113 key pressed: 1 1 0 1 0114 key pressed: 1 1 0 1 0115 key pressed: 1 1 0 1 0116 key pressed: 1 1 0 1 0117 key pressed: 1 1 0 1 0118 key pressed: 1 1 0 1 0119 key pressed: 1 1 0 1 0120 key pressed: 1 1 0 1 0121 key pressed: 1 1 0 1 0122 key pressed: 1 1 0 1 0123 key pressed: 1 1 0 1 0124 key pressed: 1 1 0 1 0125 key pressed: 1 1 0 1 0126 key pressed: 1 1 0 1 0127 key pressed: 1 1 0 1 0128 key pressed: 1 1 0 1 0129 key pressed: 1 1 0 1 0130 key pressed: 1 1 0 1 0131 key pressed: 1 1 0 1 0132 key pressed: 1 1 0 1 0133 key pressed: 1 1 0 1 0134 key pressed: 1 1 0 1 0135 key pressed: 1 1 0 1 0136 key pressed: 1 1 0 1 0137 key pressed: 1 1 0 1 0138 key pressed: 1 1 0 1 0139 key pressed: 1 1 0 1 0140 key pressed: 1 1 0 1 0141 key pressed: 1 1 0 1 0142 key pressed: 1 1 0 1 0143 key pressed: 1 1 0 1 0144 key pressed: 1 1 0 1 0145 key pressed: 1 1 0 1 0146 key pressed: 1 1 0 1 0147 key pressed: 1 1 0 1 0148 key pressed: 1 1 0 1 0149 key pressed: 1 1 0 1 0150 key pressed: 1 1 0 1 0151 key pressed: 1 1 0 1 0152 key pressed: 1 1 0 1 0153 key pressed: 1 1 0 1 0154 key pressed: 1 1 0 1 0155 key pressed: 1 0 1 1 0156 key pressed: 1 0 1 1 0157 key pressed: 1 0 1 1 0158 key pressed: 1 0 1 1 0159 key pressed: 1 0 1 1 0160 key pressed: 1 0 1 1 0161 key pressed: 1 0 1 1 0162 key pressed: 1 0 1 1 0163 key pressed: 1 0 1 1 0164 key pressed: 1 0 1 1 0165 key pressed: 1 0 1 1 0166 key pressed: 1 0 1 1 0167 key pressed: 1 0 1 1 0168 key pressed: 1 0 1 1 0169 key pressed: 1 0 1 1 0170 key pressed: 1 0 1 1 0171 key pressed: 1 0 1 1 0172 key pressed: 1 0 1 1 0173 key pressed: 1 0 1 1 0174 key pressed: 1 0 1 1 0175 key pressed: 1 0 1 1 0176 key pressed: 1 0 1 1 0177 key pressed: 1 0 1 1 0178 key pressed: 1 0 1 1 0179 key pressed: 1 0 1 1 0180 key pressed: 1 0 1 1 0181 key pressed: 1 0 1 1 0182 key pressed: 1 0 1 1 0183 key pressed: 1 0 1 1 0184 key pressed: 1 0 1 1 0185 key pressed: 1 0 1 1 0186 key pressed: 1 0 1 1 0187 key pressed: 1 0 1 1 0188 key pressed: 1 0 1 1 0189 key pressed: 1 0 1 1 0190 key pressed: 1 0 1 1 0191 key pressed: 1 0 1 1 0192 key pressed: 1 0 1 1 0193 key pressed: 1 0 1 1 0194 key pressed: 1 0 1 1 0195 key pressed: 1 0 1 1 0196 key pressed: 1 0 1 1 0197 key pressed: 1 0 1 1 0198 key pressed: 1 0 1 1 0199 key pressed: 1 0 1 1 0200 key pressed: 1 0 1 1 0201 key pressed: 1 0 1 1 0202 key pressed: 1 0 1 1 0203 key pressed: 1 0 1 1 0204 key pressed: 1 0 1 1 0205 key pressed: 1 0 1 1 0206 key pressed: 1 0 1 1 0207 key pressed: 1 0 1 1 0208 key pressed: 1 0 1 1 0209 key pressed: 1 0 1 1 0210 key pressed: 1 0 1 1 0211 key pressed: 1 0 1 1 0212 key pressed: 1 0 1 1 0213 key pressed: 1 0 1 1 0214 key pressed: 1 0 1 1 0215 key pressed: 1 0 1 1 0216 key pressed: 1 0 1 1 0217 key pressed: 1 0 1 1 0218 key pressed: 1 0 1 1 0219 key pressed: 1 0 1 1 0220 key pressed: 1 0 1 1 0221 key pressed: 1 0 1 1 0222 key pressed: 1 0 1 1 0223 key pressed: 1 0 1 1 0224 key pressed: 1 0 1 1 0225 key pressed: 1 0 1 1 0226 key pressed: 1 0 1 1 0227 key pressed: 1 0 1 1 0228 key pressed: 1 0 1 1 0229 key pressed: 1 0 1 1 0230 key pressed: 1 0 1 1 0231 key pressed: 1 0 1 1 0232 key pressed: 1 0 1 1 0233 key pressed: 1 0 1 1 0234 key pressed: 1 0 1 1 0235 key pressed: 1 0 1 1 0236 key pressed: 1 0 1 1 0237 key pressed: 1 0 1 1 0238 key pressed: 1 0 1 1 0239 key pressed: 1 0 1 1 0240 key pressed: 1 0 1 1 0241 key pressed: 1 0 1 1 0242 key pressed: 1 0 1 1 0243 key pressed: 1 0 1 1 0244 key pressed: 1 0 1 1 0245 key pressed: 1 0 1 1 0246 key pressed: 1 0 1 1 0247 key pressed: 1 0 1 1 0248 key pressed: 1 0 1 1 0249 key pressed: 1 0 1 1 0250 key pressed: 1 0 1 1 0251 key pressed: 1 0 1 1 0252 key pressed: 1 0 1 1 0253 key pressed: 1 0 1 1 0254 key pressed: 1 0 1 1 0255 key pressed: 1 0 1 1 0256 key pressed: 1 0 1 1 0257 key pressed: 1 0 1 1 0258 key pressed: 1 0 1 1 0259 key pressed: 1 0 1 1 0260 key pressed: 1 0 1 1 0261 key pressed: 1 0 1 1 0262 key pressed: 1 0 1 1 0263 key pressed: 1 0 1 1 0264 key pressed: 1 0 1 1 0265 key pressed: 1 0 1 1 0266 key pressed: 1 0 1 1 0267 key pressed: 1 0 1 1 0268 key pressed: 1 0 1 1 0269 key pressed: 1 0 1 1 0270 key pressed: 1 0 1 1 0271 key pressed: 1 0 1 1 0272 key pressed: 1 0 1 1 0273 key pressed: 1 0 1 1 0274 key pressed: 1 0 1 1 0275 key pressed: 1 0 1 1 0276 key pressed: 1 0 1 1 0277 key pressed: 1 0 1 1 0278 key pressed: 1 0 1 1 0279 key pressed: 1 0 1 1 0280 key pressed: 1 0 1 1 0281 key pressed: 1 0 1 1 0282 key pressed: 1 0 1 1 0283 key pressed: 1 0 1 1 0284 key pressed: 1 0 1 1 0285 key pressed: 1 0 1 1 0286 key pressed: 1 0 1 1 0287 key pressed: 1 0 1 1 0288 key pressed: 1 0 1 1 0289 key pressed: 1 0 1 1 0290 key pressed: 1 0 1 1 0291 key pressed: 1 0 1 1 0292 key pressed: 1 0 1 1 0293 key pressed: 1 0 1 1 0294 key pressed: 1 0 1 1 0295 key pressed: 1 0 1 1 0296 key pressed: 1 0 1 1 0297 key pressed: 1 0 1 1 0298 key pressed: 1 0 1 1 0299 key pressed: 1 0 1 1 0300 key pressed: 1 0 1 1 0301 key pressed: 1 0 1 1 0302 key pressed: 1 0 1 1 0303 key pressed: 1 0 1 1 0304 key pressed: 1 0 1 1 0305 key pressed: 1 0 1 1 0306 key pressed: 1 0 1 1 0307 key pressed: 1 0 1 1 0308 key pressed: 1 0 1 1 0309 key pressed: 1 0 1 1 0310 key pressed: 0 1 1 1 0311 key pressed: 0 1 1 1 0312 key pressed: 0 1 1 1 0313 key pressed: 0 1 1 1 0314 key pressed: 0 1 1 1 0315 key pressed: 0 1 1 1 0316 key pressed: 0 1 1 1 0317 key pressed: 0 1 1 1 0318 key pressed: 0 1 1 1 0319 key pressed: 0 1 1 1 0320 key pressed: 0 1 1 1 0321 key pressed: 0 1 1 1 0322 key pressed: 0 1 1 1 0323 key pressed: 0 1 1 1 0324 key pressed: 0 1 1 1 0325 key pressed: 0 1 1 1 0326 key pressed: 0 1 1 1 0327 key pressed: 0 1 1 1 0328 key pressed: 0 1 1 1 0329 key pressed: 0 1 1 1 0330 key pressed: 0 1 1 1 0331 key pressed: 0 1 1 1 0332 key pressed: 0 1 1 1 0333 key pressed: 0 1 1 1 0334 key pressed: 0 1 1 1 0335 key pressed: 0 1 1 1 0336 key pressed: 0 1 1 1 0337 key pressed: 0 1 1 1 0338 key pressed: 0 1 1 1 0339 key pressed: 0 1 1 1 0340 key pressed: 0 1 1 1 0341 key pressed: 0 1 1 1 0342 key pressed: 0 1 1 1 0343 key pressed: 0 1 1 1 0344 key pressed: 0 1 1 1 0345 key pressed: 0 1 1 1 0346 key pressed: 0 1 1 1 0347 key pressed: 0 1 1 1 0348 key pressed: 0 1 1 1 0349 key pressed: 0 1 1 1 0350 key pressed: 0 1 1 1 0351 key pressed: 0 1 1 1 0352 key pressed: 0 1 1 1 0353 key pressed: 0 1 1 1 0354 key pressed: 0 1 1 1 0355 key pressed: 0 1 1 1 0356 key pressed: 0 1 1 1 0357 key pressed: 0 1 1 1 0358 key pressed: 0 1 1 1 0359 key pressed: 0 1 1 1 0360 key pressed: 0 1 1 1 0361 key pressed: 0 1 1 1 0362 key pressed: 0 1 1 1 0363 key pressed: 0 1 1 1 0364 key pressed: 0 1 1 1 0365 key pressed: 0 1 1 1 0366 key pressed: 0 1 1 1 0367 key pressed: 0 1 1 1 0368 key pressed: 0 1 1 1 0369 key pressed: 0 1 1 1 0370 key pressed: 0 1 1 1 0371 key pressed: 0 1 1 1 0372 key pressed: 0 1 1 1 0373 key pressed: 0 1 1 1 0374 key pressed: 0 1 1 1 0375 key pressed: 0 1 1 1 0376 key pressed: 0 1 1 1 0377 key pressed: 0 1 1 1 0378 key pressed: 0 1 1 1 0379 key pressed: 0 1 1 1 0380 key pressed: 0 1 1 1 0381 key pressed: 0 1 1 1 0382 key pressed: 0 1 1 1 0383 key pressed: 0 1 1 1 0384 key pressed: 0 1 1 1 0385 key pressed: 0 1 1 1 0386 key pressed: 0 1 1 1 0387 key pressed: 0 1 1 1 0388 key pressed: 0 1 1 1 0389 key pressed: 0 1 1 1 0390 key pressed: 0 1 1 1 0391 key pressed: 0 1 1 1 0392 key pressed: 0 1 1 1 0393 key pressed: 0 1 1 1 0394 key pressed: 0 1 1 1 0395 key pressed: 0 1 1 1 0396 key pressed: 0 1 1 1 0397 key pressed: 0 1 1 1 0398 key pressed: 0 1 1 1 0399 key pressed: 0 1 1 1 0400 key pressed: 0 1 1 1 0401 key pressed: 0 1 1 1 0402 key pressed: 0 1 1 1 0403 key pressed: 0 1 1 1 0404 key pressed: 0 1 1 1 0405 key pressed: 0 1 1 1 0406 key pressed: 0 1 1 1 0407 key pressed: 0 1 1 1 0408 key pressed: 0 1 1 1 0409 key pressed: 0 1 1 1 0410 key pressed: 0 1 1 1 0411 key pressed: 0 1 1 1 0412 key pressed: 0 1 1 1 0413 key pressed: 0 1 1 1 0414 key pressed: 0 1 1 1 0415 key pressed: 0 1 1 1 0416 key pressed: 0 1 1 1 0417 key pressed: 0 1 1 1 0418 key pressed: 0 1 1 1 0419 key pressed: 0 1 1 1 0420 key pressed: 0 1 1 1 0421 key pressed: 0 1 1 1 0422 key pressed: 0 1 1 1 0423 key pressed: 0 1 1 1 0424 key pressed: 0 1 1 1 0425 key pressed: 0 1 1 1 0426 key pressed: 0 1 1 1 0427 key pressed: 0 1 1 1 0428 key pressed: 0 1 1 1 0429 key pressed: 0 1 1 1 0430 key pressed: 0 1 1 1 0431 key pressed: 0 1 1 1 0432 key pressed: 0 1 1 1 0433 key pressed: 0 1 1 1 0434 key pressed: 0 1 1 1 0435 key pressed: 0 1 1 1 0436 key pressed: 0 1 1 1 0437 key pressed: 0 1 1 1 0438 key pressed: 0 1 1 1 0439 key pressed: 0 1 1 1 0440 key pressed: 0 1 1 1 0441 key pressed: 0 1 1 1 0442 key pressed: 0 1 1 1 0443 key pressed: 0 1 1 1 0444 key pressed: 0 1 1 1 0445 key pressed: 0 1 1 1 0446 key pressed: 0 1 1 1 0447 key pressed: 0 1 1 1 0448 key pressed: 0 1 1 1 0449 key pressed: 0 1 1 1 0450 key pressed: 0 1 1 1 0451 key pressed: 0 1 1 1 0452 key pressed: 0 1 1 1 0453 key pressed: 0 1 1 1 0454 key pressed: 0 1 1 1 0455 key pressed: 0 1 1 1 0456 key pressed: 0 1 1 1 0457 key pressed: 0 1 1 1 0458 key pressed: 0 1 1 1 0459 key pressed: 0 1 1 1 0460 key pressed: 0 1 1 1 0461 key pressed: 0 1 1 1 0462 key pressed: 0 1 1 1 0463 key pressed: 0 1 1 1 0464 key pressed: 0 1 1 1
这种死循环查询的方式非常耗费CPU资源,如何优化? 通过中断的方式,在按下的时候触发中断 #include #include #include #include #include #include #include #include #include #include #include static struct class *thirddrv_class; static struct class_device *thirddrv_class_dev; volatile unsigned long *gpfcon; volatile unsigned long *gpfdat; volatile unsigned long *gpgcon; volatile unsigned long *gpgdat; static DECLARE_WAIT_QUEUE_HEAD(button_waitq); /* 中断事件标志, 中断服务程序将它置1,third_drv_read将它清0 */ static volatile int ev_press = 0; struct pin_desc{ unsigned int pin; unsigned int key_val; }; /* 键值: 按下时, 0x01, 0x02, 0x03, 0x04 */ /* 键值: 松开时, 0x81, 0x82, 0x83, 0x84 */ static unsigned char key_val; struct pin_desc pins_desc[4] = { {S3C2410_GPF0, 0x01}, {S3C2410_GPF2, 0x02}, {S3C2410_GPG3, 0x03}, {S3C2410_GPG11, 0x04}, }; /* * 确定按键值 */ static irqreturn_t buttons_irq(int irq, void *dev_id) { struct pin_desc * pindesc = (struct pin_desc *)dev_id; unsigned int pinval; pinval = s3c2410_gpio_getpin(pindesc->pin); if (pinval) { /* 松开 */ key_val = 0x80 | pindesc->key_val; } else { /* 按下 */ key_val = pindesc->key_val; } ev_press = 1; /* 表示中断发生了 */ wake_up_interruptible(&button_waitq); /* 唤醒休眠的进程 */ return IRQ_RETVAL(IRQ_HANDLED); } static int third_drv_open(struct inode *inode, struct file *file) { /* 配置GPF0,2为输入引脚 */ /* 配置GPG3,11为输入引脚 */ request_irq(IRQ_EINT0, buttons_irq, IRQT_BOTHEDGE, "S2", &pins_desc[0]); request_irq(IRQ_EINT2, buttons_irq, IRQT_BOTHEDGE, "S3", &pins_desc[1]); request_irq(IRQ_EINT11, buttons_irq, IRQT_BOTHEDGE, "S4", &pins_desc[2]); request_irq(IRQ_EINT19, buttons_irq, IRQT_BOTHEDGE, "S5", &pins_desc[3]); return 0; } ssize_t third_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) { if (size != 1) return -EINVAL; /* 如果没有按键动作, 休眠 */ wait_event_interruptible(button_waitq, ev_press); /* 如果有按键动作, 返回键值 */ copy_to_user(buf, &key_val, 1); ev_press = 0; return 1; } int third_drv_close(struct inode *inode, struct file *file) { free_irq(IRQ_EINT0, &pins_desc[0]); free_irq(IRQ_EINT2, &pins_desc[1]); free_irq(IRQ_EINT11, &pins_desc[2]); free_irq(IRQ_EINT19, &pins_desc[3]); return 0; } static struct file_operations sencod_drv_fops = { .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */ .open = third_drv_open, .read = third_drv_read, .release = third_drv_close, }; int major; static int third_drv_init(void) { major = register_chrdev(0, "third_drv", &sencod_drv_fops); thirddrv_class = class_create(THIS_MODULE, "third_drv"); thirddrv_class_dev = class_device_create(thirddrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */ gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16); gpfdat = gpfcon + 1; gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16); gpgdat = gpgcon + 1; return 0; } static void third_drv_exit(void) { unregister_chrdev(major, "third_drv"); class_device_unregister(thirddrv_class_dev); class_destroy(thirddrv_class); iounmap(gpfcon); iounmap(gpgcon); return 0; } module_init(third_drv_init); module_exit(third_drv_exit); MODULE_LICENSE("GPL");
编写测试程序 #include #include #include #include #include /* thirddrvtest */ int main(int argc, char **argv) { int fd; unsigned char key_val; fd = open("/dev/buttons", O_RDWR); if (fd < 0) { printf("can't open! "); } while (1) { read(fd, &key_val, 1); printf("key_val = 0x%x ", key_val); sleep(5); } return 0; }
在开发板上运行 # insmod third_drv.ko # ./thirddrvtest # rm -r /dev/buttons # ./thirddrvtest can't open! mkn ^H^H^H # mknod /dev/buttons c 252 0 # ./thirddrvtest # cat /proc/devices Character devices: 1 mem 2 pty 3 ttyp 4 /dev/vc/0 4 tty 4 ttyS 5 /dev/tty 5 /dev/console 5 /dev/ptmx 6 lp 7 vcs 10 misc 13 input 14 sound 29 fb 90 mtd 99 ppdev 116 alsa 128 ptm 136 pts 180 usb 189 usb_device 204 s3c2410_serial 251 third_drv 252 second_drv 253 usb_endpoint 254 rtc Block devices: 1 ramdisk 7 loop 8 sd 31 mtdblock 65 sd 66 sd 67 sd 68 sd 69 sd 70 sd 71 sd 128 sd 129 sd 130 sd 131 sd 132 sd 133 sd 134 sd 135 sd 179 mmc # mknod /dev/buttons c 251 0 mknod: /dev/buttons: File exists # rm -r /dev/buttons # mknod /dev/buttons c 251 0 # ./thirddrvtest # ./thirddrvtest key_val = 0x81 key_val = 0x81 key_val = 0x83 key_val = 0x82 key_val = 0x81 key_val = 0x2 key_val = 0x82 key_val = 0x83 key_val = 0x81